From f920008cad63d263d263b326a561833d0d6daa29 Mon Sep 17 00:00:00 2001 From: Lars Date: Thu, 4 Jul 2024 23:17:56 +0200 Subject: [PATCH] Release 0.0.1 --- .gitignore | 124 + icon.png | Bin 0 -> 104738 bytes lib/Flox_lib-0.19.6.dist-info/INSTALLER | 1 + lib/Flox_lib-0.19.6.dist-info/LICENSE.txt | 21 + lib/Flox_lib-0.19.6.dist-info/METADATA | 65 + lib/Flox_lib-0.19.6.dist-info/RECORD | 23 + lib/Flox_lib-0.19.6.dist-info/REQUESTED | 0 lib/Flox_lib-0.19.6.dist-info/WHEEL | 5 + lib/Flox_lib-0.19.6.dist-info/top_level.txt | 1 + lib/Flox_lib-0.19.6.dist-info/zip-safe | 1 + lib/bin/chardetect.exe | Bin 0 -> 108470 bytes lib/certifi-2024.7.4.dist-info/INSTALLER | 1 + lib/certifi-2024.7.4.dist-info/LICENSE | 20 + lib/certifi-2024.7.4.dist-info/METADATA | 67 + lib/certifi-2024.7.4.dist-info/RECORD | 14 + lib/certifi-2024.7.4.dist-info/WHEEL | 5 + lib/certifi-2024.7.4.dist-info/top_level.txt | 1 + lib/certifi/__init__.py | 4 + lib/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 307 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 622 bytes lib/certifi/__pycache__/core.cpython-312.pyc | Bin 0 -> 3192 bytes lib/certifi/cacert.pem | 4798 ++++++++++ lib/certifi/core.py | 114 + lib/certifi/py.typed | 0 lib/chardet-4.0.0.dist-info/INSTALLER | 1 + lib/chardet-4.0.0.dist-info/LICENSE | 504 + lib/chardet-4.0.0.dist-info/METADATA | 101 + lib/chardet-4.0.0.dist-info/RECORD | 94 + lib/chardet-4.0.0.dist-info/WHEEL | 6 + lib/chardet-4.0.0.dist-info/entry_points.txt | 3 + lib/chardet-4.0.0.dist-info/top_level.txt | 1 + lib/chardet/__init__.py | 83 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2992 bytes .../__pycache__/big5freq.cpython-312.pyc | Bin 0 -> 27188 bytes .../__pycache__/big5prober.cpython-312.pyc | Bin 0 -> 1342 bytes .../chardistribution.cpython-312.pyc | Bin 0 -> 8258 bytes .../charsetgroupprober.cpython-312.pyc | Bin 0 -> 3830 bytes .../__pycache__/charsetprober.cpython-312.pyc | Bin 0 -> 4360 bytes .../codingstatemachine.cpython-312.pyc | Bin 0 -> 3607 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 508 bytes .../__pycache__/cp949prober.cpython-312.pyc | Bin 0 -> 1351 bytes lib/chardet/__pycache__/enums.cpython-312.pyc | Bin 0 -> 2907 bytes .../__pycache__/escprober.cpython-312.pyc | Bin 0 -> 4244 bytes lib/chardet/__pycache__/escsm.cpython-312.pyc | Bin 0 -> 15014 bytes .../__pycache__/eucjpprober.cpython-312.pyc | Bin 0 -> 4103 bytes .../__pycache__/euckrfreq.cpython-312.pyc | Bin 0 -> 12071 bytes .../__pycache__/euckrprober.cpython-312.pyc | Bin 0 -> 1345 bytes .../__pycache__/euctwfreq.cpython-312.pyc | Bin 0 -> 27193 bytes .../__pycache__/euctwprober.cpython-312.pyc | Bin 0 -> 1345 bytes .../__pycache__/gb2312freq.cpython-312.pyc | Bin 0 -> 19115 bytes .../__pycache__/gb2312prober.cpython-312.pyc | Bin 0 -> 1358 bytes .../__pycache__/hebrewprober.cpython-312.pyc | Bin 0 -> 5023 bytes .../__pycache__/jisfreq.cpython-312.pyc | Bin 0 -> 22144 bytes .../__pycache__/jpcntx.cpython-312.pyc | Bin 0 -> 39035 bytes .../langbulgarianmodel.cpython-312.pyc | Bin 0 -> 83102 bytes .../langgreekmodel.cpython-312.pyc | Bin 0 -> 76967 bytes .../langhebrewmodel.cpython-312.pyc | Bin 0 -> 77478 bytes .../langhungarianmodel.cpython-312.pyc | Bin 0 -> 83062 bytes .../langrussianmodel.cpython-312.pyc | Bin 0 -> 105230 bytes .../__pycache__/langthaimodel.cpython-312.pyc | Bin 0 -> 77656 bytes .../langturkishmodel.cpython-312.pyc | Bin 0 -> 77498 bytes .../__pycache__/latin1prober.cpython-312.pyc | Bin 0 -> 6805 bytes .../mbcharsetprober.cpython-312.pyc | Bin 0 -> 3727 bytes .../mbcsgroupprober.cpython-312.pyc | Bin 0 -> 1394 bytes .../__pycache__/mbcssm.cpython-312.pyc | Bin 0 -> 34682 bytes .../sbcharsetprober.cpython-312.pyc | Bin 0 -> 5391 bytes .../sbcsgroupprober.cpython-312.pyc | Bin 0 -> 2322 bytes .../__pycache__/sjisprober.cpython-312.pyc | Bin 0 -> 4217 bytes .../universaldetector.cpython-312.pyc | Bin 0 -> 9997 bytes .../__pycache__/utf8prober.cpython-312.pyc | Bin 0 -> 3004 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 475 bytes lib/chardet/big5freq.py | 386 + lib/chardet/big5prober.py | 47 + lib/chardet/chardistribution.py | 233 + lib/chardet/charsetgroupprober.py | 107 + lib/chardet/charsetprober.py | 145 + lib/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 184 bytes .../__pycache__/chardetect.cpython-312.pyc | Bin 0 -> 3619 bytes lib/chardet/cli/chardetect.py | 84 + lib/chardet/codingstatemachine.py | 88 + lib/chardet/compat.py | 36 + lib/chardet/cp949prober.py | 49 + lib/chardet/enums.py | 76 + lib/chardet/escprober.py | 101 + lib/chardet/escsm.py | 246 + lib/chardet/eucjpprober.py | 92 + lib/chardet/euckrfreq.py | 195 + lib/chardet/euckrprober.py | 47 + lib/chardet/euctwfreq.py | 387 + lib/chardet/euctwprober.py | 46 + lib/chardet/gb2312freq.py | 283 + lib/chardet/gb2312prober.py | 46 + lib/chardet/hebrewprober.py | 292 + lib/chardet/jisfreq.py | 325 + lib/chardet/jpcntx.py | 233 + lib/chardet/langbulgarianmodel.py | 4650 +++++++++ lib/chardet/langgreekmodel.py | 4398 +++++++++ lib/chardet/langhebrewmodel.py | 4383 +++++++++ lib/chardet/langhungarianmodel.py | 4650 +++++++++ lib/chardet/langrussianmodel.py | 5718 +++++++++++ lib/chardet/langthaimodel.py | 4383 +++++++++ lib/chardet/langturkishmodel.py | 4383 +++++++++ lib/chardet/latin1prober.py | 145 + lib/chardet/mbcharsetprober.py | 91 + lib/chardet/mbcsgroupprober.py | 54 + lib/chardet/mbcssm.py | 572 ++ lib/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 189 bytes .../__pycache__/languages.cpython-312.pyc | Bin 0 -> 9639 bytes lib/chardet/metadata/languages.py | 310 + lib/chardet/sbcharsetprober.py | 145 + lib/chardet/sbcsgroupprober.py | 83 + lib/chardet/sjisprober.py | 92 + lib/chardet/universaldetector.py | 286 + lib/chardet/utf8prober.py | 82 + lib/chardet/version.py | 9 + lib/flox/__init__.py | 337 + lib/flox/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 20175 bytes lib/flox/__pycache__/browser.cpython-312.pyc | Bin 0 -> 4291 bytes .../__pycache__/clipboard.cpython-312.pyc | Bin 0 -> 3941 bytes lib/flox/__pycache__/launcher.cpython-312.pyc | Bin 0 -> 7551 bytes lib/flox/__pycache__/settings.cpython-312.pyc | Bin 0 -> 3146 bytes .../string_matcher.cpython-312.pyc | Bin 0 -> 7470 bytes lib/flox/__pycache__/utils.cpython-312.pyc | Bin 0 -> 6937 bytes lib/flox/browser.py | 75 + lib/flox/clipboard.py | 82 + lib/flox/launcher.py | 142 + lib/flox/settings.py | 53 + lib/flox/string_matcher.py | 219 + lib/flox/utils.py | 137 + lib/flox/version | 1 + lib/idna-2.10.dist-info/INSTALLER | 1 + lib/idna-2.10.dist-info/LICENSE.rst | 34 + lib/idna-2.10.dist-info/METADATA | 243 + lib/idna-2.10.dist-info/RECORD | 22 + lib/idna-2.10.dist-info/WHEEL | 6 + lib/idna-2.10.dist-info/top_level.txt | 1 + lib/idna/__init__.py | 2 + lib/idna/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 252 bytes lib/idna/__pycache__/codec.cpython-312.pyc | Bin 0 -> 4355 bytes lib/idna/__pycache__/compat.cpython-312.pyc | Bin 0 -> 685 bytes lib/idna/__pycache__/core.cpython-312.pyc | Bin 0 -> 15047 bytes lib/idna/__pycache__/idnadata.cpython-312.pyc | Bin 0 -> 36325 bytes .../__pycache__/intranges.cpython-312.pyc | Bin 0 -> 2343 bytes .../__pycache__/package_data.cpython-312.pyc | Bin 0 -> 206 bytes .../__pycache__/uts46data.cpython-312.pyc | Bin 0 -> 147648 bytes lib/idna/codec.py | 118 + lib/idna/compat.py | 12 + lib/idna/core.py | 400 + lib/idna/idnadata.py | 2050 ++++ lib/idna/intranges.py | 53 + lib/idna/package_data.py | 2 + lib/idna/uts46data.py | 8357 +++++++++++++++++ lib/requests-2.25.1.dist-info/INSTALLER | 1 + lib/requests-2.25.1.dist-info/LICENSE | 175 + lib/requests-2.25.1.dist-info/METADATA | 103 + lib/requests-2.25.1.dist-info/RECORD | 43 + lib/requests-2.25.1.dist-info/REQUESTED | 0 lib/requests-2.25.1.dist-info/WHEEL | 6 + lib/requests-2.25.1.dist-info/top_level.txt | 1 + lib/requests/__init__.py | 137 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4726 bytes .../__pycache__/__version__.cpython-312.pyc | Bin 0 -> 579 bytes .../_internal_utils.cpython-312.pyc | Bin 0 -> 1547 bytes .../__pycache__/adapters.cpython-312.pyc | Bin 0 -> 22847 bytes lib/requests/__pycache__/api.cpython-312.pyc | Bin 0 -> 7240 bytes lib/requests/__pycache__/auth.cpython-312.pyc | Bin 0 -> 13826 bytes .../__pycache__/certs.cpython-312.pyc | Bin 0 -> 656 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 1876 bytes .../__pycache__/cookies.cpython-312.pyc | Bin 0 -> 25276 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 5981 bytes lib/requests/__pycache__/help.cpython-312.pyc | Bin 0 -> 3949 bytes .../__pycache__/hooks.cpython-312.pyc | Bin 0 -> 1042 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 35026 bytes .../__pycache__/packages.cpython-312.pyc | Bin 0 -> 630 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 28192 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 5945 bytes .../__pycache__/structures.cpython-312.pyc | Bin 0 -> 5631 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 33628 bytes lib/requests/__version__.py | 14 + lib/requests/_internal_utils.py | 42 + lib/requests/adapters.py | 533 ++ lib/requests/api.py | 161 + lib/requests/auth.py | 305 + lib/requests/certs.py | 18 + lib/requests/compat.py | 72 + lib/requests/cookies.py | 549 ++ lib/requests/exceptions.py | 123 + lib/requests/help.py | 119 + lib/requests/hooks.py | 34 + lib/requests/models.py | 956 ++ lib/requests/packages.py | 14 + lib/requests/sessions.py | 781 ++ lib/requests/status_codes.py | 123 + lib/requests/structures.py | 105 + lib/requests/utils.py | 992 ++ lib/urllib3-1.26.19.dist-info/INSTALLER | 1 + lib/urllib3-1.26.19.dist-info/LICENSE.txt | 21 + lib/urllib3-1.26.19.dist-info/METADATA | 1499 +++ lib/urllib3-1.26.19.dist-info/RECORD | 84 + lib/urllib3-1.26.19.dist-info/WHEEL | 6 + lib/urllib3-1.26.19.dist-info/top_level.txt | 1 + lib/urllib3/__init__.py | 102 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3395 bytes .../__pycache__/_collections.cpython-312.pyc | Bin 0 -> 16478 bytes .../__pycache__/_version.cpython-312.pyc | Bin 0 -> 208 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 20397 bytes .../connectionpool.cpython-312.pyc | Bin 0 -> 36481 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 13483 bytes .../__pycache__/fields.cpython-312.pyc | Bin 0 -> 10399 bytes .../__pycache__/filepost.cpython-312.pyc | Bin 0 -> 4008 bytes .../__pycache__/poolmanager.cpython-312.pyc | Bin 0 -> 20462 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 7284 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 34138 bytes lib/urllib3/_collections.py | 355 + lib/urllib3/_version.py | 2 + lib/urllib3/connection.py | 572 ++ lib/urllib3/connectionpool.py | 1139 +++ lib/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 188 bytes .../_appengine_environ.cpython-312.pyc | Bin 0 -> 1838 bytes .../__pycache__/appengine.cpython-312.pyc | Bin 0 -> 11530 bytes .../__pycache__/ntlmpool.cpython-312.pyc | Bin 0 -> 5709 bytes .../__pycache__/pyopenssl.cpython-312.pyc | Bin 0 -> 24407 bytes .../securetransport.cpython-312.pyc | Bin 0 -> 35528 bytes .../contrib/__pycache__/socks.cpython-312.pyc | Bin 0 -> 7501 bytes lib/urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 205 bytes .../__pycache__/bindings.cpython-312.pyc | Bin 0 -> 17417 bytes .../__pycache__/low_level.cpython-312.pyc | Bin 0 -> 14791 bytes .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 397 + lib/urllib3/contrib/appengine.py | 314 + lib/urllib3/contrib/ntlmpool.py | 130 + lib/urllib3/contrib/pyopenssl.py | 518 + lib/urllib3/contrib/securetransport.py | 920 ++ lib/urllib3/contrib/socks.py | 216 + lib/urllib3/exceptions.py | 323 + lib/urllib3/fields.py | 274 + lib/urllib3/filepost.py | 98 + lib/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 189 bytes .../packages/__pycache__/six.cpython-312.pyc | Bin 0 -> 41309 bytes lib/urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 199 bytes .../__pycache__/makefile.cpython-312.pyc | Bin 0 -> 1815 bytes .../weakref_finalize.cpython-312.pyc | Bin 0 -> 7321 bytes lib/urllib3/packages/backports/makefile.py | 51 + .../packages/backports/weakref_finalize.py | 155 + lib/urllib3/packages/six.py | 1076 +++ lib/urllib3/poolmanager.py | 540 ++ lib/urllib3/request.py | 191 + lib/urllib3/response.py | 885 ++ lib/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1136 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 4746 bytes .../util/__pycache__/proxy.cpython-312.pyc | Bin 0 -> 1542 bytes .../util/__pycache__/queue.cpython-312.pyc | Bin 0 -> 1342 bytes .../util/__pycache__/request.cpython-312.pyc | Bin 0 -> 4412 bytes .../util/__pycache__/response.cpython-312.pyc | Bin 0 -> 2979 bytes .../util/__pycache__/retry.cpython-312.pyc | Bin 0 -> 21708 bytes .../util/__pycache__/ssl_.cpython-312.pyc | Bin 0 -> 15081 bytes .../ssl_match_hostname.cpython-312.pyc | Bin 0 -> 5061 bytes .../__pycache__/ssltransport.cpython-312.pyc | Bin 0 -> 10762 bytes .../util/__pycache__/timeout.cpython-312.pyc | Bin 0 -> 11129 bytes .../util/__pycache__/url.cpython-312.pyc | Bin 0 -> 15761 bytes .../util/__pycache__/wait.cpython-312.pyc | Bin 0 -> 4393 bytes lib/urllib3/util/connection.py | 149 + lib/urllib3/util/proxy.py | 57 + lib/urllib3/util/queue.py | 22 + lib/urllib3/util/request.py | 146 + lib/urllib3/util/response.py | 107 + lib/urllib3/util/retry.py | 622 ++ lib/urllib3/util/ssl_.py | 495 + lib/urllib3/util/ssl_match_hostname.py | 159 + lib/urllib3/util/ssltransport.py | 221 + lib/urllib3/util/timeout.py | 271 + lib/urllib3/util/url.py | 435 + lib/urllib3/util/wait.py | 152 + plugin.json | 12 + plugin.log | 595 ++ plugin/osrswiki.py | 23 + plugin/searchwiki.py | 34 + requirements.txt | 2 + run.py | 12 + 288 files changed, 75791 insertions(+) create mode 100644 .gitignore create mode 100644 icon.png create mode 100644 lib/Flox_lib-0.19.6.dist-info/INSTALLER create mode 100644 lib/Flox_lib-0.19.6.dist-info/LICENSE.txt create mode 100644 lib/Flox_lib-0.19.6.dist-info/METADATA create mode 100644 lib/Flox_lib-0.19.6.dist-info/RECORD create mode 100644 lib/Flox_lib-0.19.6.dist-info/REQUESTED create mode 100644 lib/Flox_lib-0.19.6.dist-info/WHEEL create mode 100644 lib/Flox_lib-0.19.6.dist-info/top_level.txt create mode 100644 lib/Flox_lib-0.19.6.dist-info/zip-safe create mode 100644 lib/bin/chardetect.exe create mode 100644 lib/certifi-2024.7.4.dist-info/INSTALLER create mode 100644 lib/certifi-2024.7.4.dist-info/LICENSE create mode 100644 lib/certifi-2024.7.4.dist-info/METADATA create mode 100644 lib/certifi-2024.7.4.dist-info/RECORD create mode 100644 lib/certifi-2024.7.4.dist-info/WHEEL create mode 100644 lib/certifi-2024.7.4.dist-info/top_level.txt create mode 100644 lib/certifi/__init__.py create mode 100644 lib/certifi/__main__.py create mode 100644 lib/certifi/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/certifi/__pycache__/__main__.cpython-312.pyc create mode 100644 lib/certifi/__pycache__/core.cpython-312.pyc create mode 100644 lib/certifi/cacert.pem create mode 100644 lib/certifi/core.py create mode 100644 lib/certifi/py.typed create mode 100644 lib/chardet-4.0.0.dist-info/INSTALLER create mode 100644 lib/chardet-4.0.0.dist-info/LICENSE create mode 100644 lib/chardet-4.0.0.dist-info/METADATA create mode 100644 lib/chardet-4.0.0.dist-info/RECORD create mode 100644 lib/chardet-4.0.0.dist-info/WHEEL create mode 100644 lib/chardet-4.0.0.dist-info/entry_points.txt create mode 100644 lib/chardet-4.0.0.dist-info/top_level.txt create mode 100644 lib/chardet/__init__.py create mode 100644 lib/chardet/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/big5freq.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/big5prober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/chardistribution.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/charsetgroupprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/charsetprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/codingstatemachine.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/compat.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/cp949prober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/enums.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/escprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/escsm.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/eucjpprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/euckrfreq.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/euckrprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/euctwfreq.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/euctwprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/gb2312freq.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/gb2312prober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/hebrewprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/jisfreq.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/jpcntx.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langgreekmodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langhebrewmodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langhungarianmodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langrussianmodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langthaimodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/langturkishmodel.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/latin1prober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/mbcharsetprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/mbcssm.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/sbcharsetprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/sjisprober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/universaldetector.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/utf8prober.cpython-312.pyc create mode 100644 lib/chardet/__pycache__/version.cpython-312.pyc create mode 100644 lib/chardet/big5freq.py create mode 100644 lib/chardet/big5prober.py create mode 100644 lib/chardet/chardistribution.py create mode 100644 lib/chardet/charsetgroupprober.py create mode 100644 lib/chardet/charsetprober.py create mode 100644 lib/chardet/cli/__init__.py create mode 100644 lib/chardet/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/chardet/cli/__pycache__/chardetect.cpython-312.pyc create mode 100644 lib/chardet/cli/chardetect.py create mode 100644 lib/chardet/codingstatemachine.py create mode 100644 lib/chardet/compat.py create mode 100644 lib/chardet/cp949prober.py create mode 100644 lib/chardet/enums.py create mode 100644 lib/chardet/escprober.py create mode 100644 lib/chardet/escsm.py create mode 100644 lib/chardet/eucjpprober.py create mode 100644 lib/chardet/euckrfreq.py create mode 100644 lib/chardet/euckrprober.py create mode 100644 lib/chardet/euctwfreq.py create mode 100644 lib/chardet/euctwprober.py create mode 100644 lib/chardet/gb2312freq.py create mode 100644 lib/chardet/gb2312prober.py create mode 100644 lib/chardet/hebrewprober.py create mode 100644 lib/chardet/jisfreq.py create mode 100644 lib/chardet/jpcntx.py create mode 100644 lib/chardet/langbulgarianmodel.py create mode 100644 lib/chardet/langgreekmodel.py create mode 100644 lib/chardet/langhebrewmodel.py create mode 100644 lib/chardet/langhungarianmodel.py create mode 100644 lib/chardet/langrussianmodel.py create mode 100644 lib/chardet/langthaimodel.py create mode 100644 lib/chardet/langturkishmodel.py create mode 100644 lib/chardet/latin1prober.py create mode 100644 lib/chardet/mbcharsetprober.py create mode 100644 lib/chardet/mbcsgroupprober.py create mode 100644 lib/chardet/mbcssm.py create mode 100644 lib/chardet/metadata/__init__.py create mode 100644 lib/chardet/metadata/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/chardet/metadata/__pycache__/languages.cpython-312.pyc create mode 100644 lib/chardet/metadata/languages.py create mode 100644 lib/chardet/sbcharsetprober.py create mode 100644 lib/chardet/sbcsgroupprober.py create mode 100644 lib/chardet/sjisprober.py create mode 100644 lib/chardet/universaldetector.py create mode 100644 lib/chardet/utf8prober.py create mode 100644 lib/chardet/version.py create mode 100644 lib/flox/__init__.py create mode 100644 lib/flox/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/flox/__pycache__/browser.cpython-312.pyc create mode 100644 lib/flox/__pycache__/clipboard.cpython-312.pyc create mode 100644 lib/flox/__pycache__/launcher.cpython-312.pyc create mode 100644 lib/flox/__pycache__/settings.cpython-312.pyc create mode 100644 lib/flox/__pycache__/string_matcher.cpython-312.pyc create mode 100644 lib/flox/__pycache__/utils.cpython-312.pyc create mode 100644 lib/flox/browser.py create mode 100644 lib/flox/clipboard.py create mode 100644 lib/flox/launcher.py create mode 100644 lib/flox/settings.py create mode 100644 lib/flox/string_matcher.py create mode 100644 lib/flox/utils.py create mode 100644 lib/flox/version create mode 100644 lib/idna-2.10.dist-info/INSTALLER create mode 100644 lib/idna-2.10.dist-info/LICENSE.rst create mode 100644 lib/idna-2.10.dist-info/METADATA create mode 100644 lib/idna-2.10.dist-info/RECORD create mode 100644 lib/idna-2.10.dist-info/WHEEL create mode 100644 lib/idna-2.10.dist-info/top_level.txt create mode 100644 lib/idna/__init__.py create mode 100644 lib/idna/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/idna/__pycache__/codec.cpython-312.pyc create mode 100644 lib/idna/__pycache__/compat.cpython-312.pyc create mode 100644 lib/idna/__pycache__/core.cpython-312.pyc create mode 100644 lib/idna/__pycache__/idnadata.cpython-312.pyc create mode 100644 lib/idna/__pycache__/intranges.cpython-312.pyc create mode 100644 lib/idna/__pycache__/package_data.cpython-312.pyc create mode 100644 lib/idna/__pycache__/uts46data.cpython-312.pyc create mode 100644 lib/idna/codec.py create mode 100644 lib/idna/compat.py create mode 100644 lib/idna/core.py create mode 100644 lib/idna/idnadata.py create mode 100644 lib/idna/intranges.py create mode 100644 lib/idna/package_data.py create mode 100644 lib/idna/uts46data.py create mode 100644 lib/requests-2.25.1.dist-info/INSTALLER create mode 100644 lib/requests-2.25.1.dist-info/LICENSE create mode 100644 lib/requests-2.25.1.dist-info/METADATA create mode 100644 lib/requests-2.25.1.dist-info/RECORD create mode 100644 lib/requests-2.25.1.dist-info/REQUESTED create mode 100644 lib/requests-2.25.1.dist-info/WHEEL create mode 100644 lib/requests-2.25.1.dist-info/top_level.txt create mode 100644 lib/requests/__init__.py create mode 100644 lib/requests/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/requests/__pycache__/__version__.cpython-312.pyc create mode 100644 lib/requests/__pycache__/_internal_utils.cpython-312.pyc create mode 100644 lib/requests/__pycache__/adapters.cpython-312.pyc create mode 100644 lib/requests/__pycache__/api.cpython-312.pyc create mode 100644 lib/requests/__pycache__/auth.cpython-312.pyc create mode 100644 lib/requests/__pycache__/certs.cpython-312.pyc create mode 100644 lib/requests/__pycache__/compat.cpython-312.pyc create mode 100644 lib/requests/__pycache__/cookies.cpython-312.pyc create mode 100644 lib/requests/__pycache__/exceptions.cpython-312.pyc create mode 100644 lib/requests/__pycache__/help.cpython-312.pyc create mode 100644 lib/requests/__pycache__/hooks.cpython-312.pyc create mode 100644 lib/requests/__pycache__/models.cpython-312.pyc create mode 100644 lib/requests/__pycache__/packages.cpython-312.pyc create mode 100644 lib/requests/__pycache__/sessions.cpython-312.pyc create mode 100644 lib/requests/__pycache__/status_codes.cpython-312.pyc create mode 100644 lib/requests/__pycache__/structures.cpython-312.pyc create mode 100644 lib/requests/__pycache__/utils.cpython-312.pyc create mode 100644 lib/requests/__version__.py create mode 100644 lib/requests/_internal_utils.py create mode 100644 lib/requests/adapters.py create mode 100644 lib/requests/api.py create mode 100644 lib/requests/auth.py create mode 100644 lib/requests/certs.py create mode 100644 lib/requests/compat.py create mode 100644 lib/requests/cookies.py create mode 100644 lib/requests/exceptions.py create mode 100644 lib/requests/help.py create mode 100644 lib/requests/hooks.py create mode 100644 lib/requests/models.py create mode 100644 lib/requests/packages.py create mode 100644 lib/requests/sessions.py create mode 100644 lib/requests/status_codes.py create mode 100644 lib/requests/structures.py create mode 100644 lib/requests/utils.py create mode 100644 lib/urllib3-1.26.19.dist-info/INSTALLER create mode 100644 lib/urllib3-1.26.19.dist-info/LICENSE.txt create mode 100644 lib/urllib3-1.26.19.dist-info/METADATA create mode 100644 lib/urllib3-1.26.19.dist-info/RECORD create mode 100644 lib/urllib3-1.26.19.dist-info/WHEEL create mode 100644 lib/urllib3-1.26.19.dist-info/top_level.txt create mode 100644 lib/urllib3/__init__.py create mode 100644 lib/urllib3/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/_collections.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/_version.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/connection.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/connectionpool.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/exceptions.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/fields.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/filepost.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/poolmanager.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/request.cpython-312.pyc create mode 100644 lib/urllib3/__pycache__/response.cpython-312.pyc create mode 100644 lib/urllib3/_collections.py create mode 100644 lib/urllib3/_version.py create mode 100644 lib/urllib3/connection.py create mode 100644 lib/urllib3/connectionpool.py create mode 100644 lib/urllib3/contrib/__init__.py create mode 100644 lib/urllib3/contrib/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc create mode 100644 lib/urllib3/contrib/__pycache__/appengine.cpython-312.pyc create mode 100644 lib/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc create mode 100644 lib/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc create mode 100644 lib/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc create mode 100644 lib/urllib3/contrib/__pycache__/socks.cpython-312.pyc create mode 100644 lib/urllib3/contrib/_appengine_environ.py create mode 100644 lib/urllib3/contrib/_securetransport/__init__.py create mode 100644 lib/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc create mode 100644 lib/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc create mode 100644 lib/urllib3/contrib/_securetransport/bindings.py create mode 100644 lib/urllib3/contrib/_securetransport/low_level.py create mode 100644 lib/urllib3/contrib/appengine.py create mode 100644 lib/urllib3/contrib/ntlmpool.py create mode 100644 lib/urllib3/contrib/pyopenssl.py create mode 100644 lib/urllib3/contrib/securetransport.py create mode 100644 lib/urllib3/contrib/socks.py create mode 100644 lib/urllib3/exceptions.py create mode 100644 lib/urllib3/fields.py create mode 100644 lib/urllib3/filepost.py create mode 100644 lib/urllib3/packages/__init__.py create mode 100644 lib/urllib3/packages/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/urllib3/packages/__pycache__/six.cpython-312.pyc create mode 100644 lib/urllib3/packages/backports/__init__.py create mode 100644 lib/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc create mode 100644 lib/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc create mode 100644 lib/urllib3/packages/backports/makefile.py create mode 100644 lib/urllib3/packages/backports/weakref_finalize.py create mode 100644 lib/urllib3/packages/six.py create mode 100644 lib/urllib3/poolmanager.py create mode 100644 lib/urllib3/request.py create mode 100644 lib/urllib3/response.py create mode 100644 lib/urllib3/util/__init__.py create mode 100644 lib/urllib3/util/__pycache__/__init__.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/connection.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/proxy.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/queue.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/request.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/response.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/retry.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/ssl_.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/ssltransport.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/timeout.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/url.cpython-312.pyc create mode 100644 lib/urllib3/util/__pycache__/wait.cpython-312.pyc create mode 100644 lib/urllib3/util/connection.py create mode 100644 lib/urllib3/util/proxy.py create mode 100644 lib/urllib3/util/queue.py create mode 100644 lib/urllib3/util/request.py create mode 100644 lib/urllib3/util/response.py create mode 100644 lib/urllib3/util/retry.py create mode 100644 lib/urllib3/util/ssl_.py create mode 100644 lib/urllib3/util/ssl_match_hostname.py create mode 100644 lib/urllib3/util/ssltransport.py create mode 100644 lib/urllib3/util/timeout.py create mode 100644 lib/urllib3/util/url.py create mode 100644 lib/urllib3/util/wait.py create mode 100644 plugin.json create mode 100644 plugin.log create mode 100644 plugin/osrswiki.py create mode 100644 plugin/searchwiki.py create mode 100644 requirements.txt create mode 100644 run.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6fcf2e2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,124 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# Flox library folder +flox + +# VScode + +.vscode/ +bin/ + +scripts/test.json \ No newline at end of file diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6b028b359efdf0d1932d280b5a165ecf731d4bd3 GIT binary patch literal 104738 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

-C0wPAkmit#uw3{yAx)JcAK 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 literal 0 HcmV?d00001 diff --git a/lib/Flox_lib-0.19.6.dist-info/INSTALLER b/lib/Flox_lib-0.19.6.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/Flox_lib-0.19.6.dist-info/LICENSE.txt b/lib/Flox_lib-0.19.6.dist-info/LICENSE.txt new file mode 100644 index 0000000..8aa2645 --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/Flox_lib-0.19.6.dist-info/METADATA b/lib/Flox_lib-0.19.6.dist-info/METADATA new file mode 100644 index 0000000..55bfc52 --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/METADATA @@ -0,0 +1,65 @@ +Metadata-Version: 2.1 +Name: Flox-lib +Version: 0.19.6 +Summary: Python library to help build Flow Launcher and Wox plugins. +Home-page: https://github.com/Garulf/Flox +Author: William McAllister +Author-email: dev.garulf@gmail.com +License: MIT +Project-URL: Bug Tracker, https://github.com/Garulf/Flox/issues +Classifier: Programming Language :: Python :: 3 +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: Microsoft :: Windows +Description-Content-Type: text/markdown +License-File: LICENSE.txt + +[![Release](https://github.com/Garulf/Flox/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/Garulf/Flox/actions/workflows/release.yml) +# FLOX + +Flox is a Python library to help build Flow Launcher and Wox plugins + +Flox adds many useful methods to speed up plugin development + +Heavily inspired from the great work done by deanishe at: [deanishe/alfred-workflow](https://github.com/deanishe/alfred-workflow) + +## Installation + + +### PIP install from pypi + +``` +pip install flox-lib +``` + +### PIP install from github + +``` +pip install git+https://github.com/garulf/flox.git +``` + +## Basic Usage + +``` +from flox import Flox + +import requests + +# have your class inherit from Flox +class YourClass(Flox): + + def query(self, query): + for _ in range(250): + self.add_item( + title=self.args, + subtitle=str(_) + ) + + def context_menu(self, data): + self.add_item( + title=data, + subtitle=data + ) + +if __name__ == "__main__": + YourClass() +``` diff --git a/lib/Flox_lib-0.19.6.dist-info/RECORD b/lib/Flox_lib-0.19.6.dist-info/RECORD new file mode 100644 index 0000000..1af5e77 --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/RECORD @@ -0,0 +1,23 @@ +Flox_lib-0.19.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Flox_lib-0.19.6.dist-info/LICENSE.txt,sha256=ACwmltkrXIz5VsEQcrqljq-fat6ZXAMepjXGoe40KtE,1069 +Flox_lib-0.19.6.dist-info/METADATA,sha256=oXruRxS9yGEo_xakDUi7KFpPd1F9vNFx0mqsnzSHiME,1565 +Flox_lib-0.19.6.dist-info/RECORD,, +Flox_lib-0.19.6.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Flox_lib-0.19.6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92 +Flox_lib-0.19.6.dist-info/top_level.txt,sha256=ToVvesHvA4pegruUxqdJ2gkmKACaQRSWPIKAoqyR9_0,5 +Flox_lib-0.19.6.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +flox/__init__.py,sha256=AbtSHfocNNCyrA1_2MHk3RTBi4J9QMCmgChSGyHfvXY,11379 +flox/__pycache__/__init__.cpython-312.pyc,, +flox/__pycache__/browser.cpython-312.pyc,, +flox/__pycache__/clipboard.cpython-312.pyc,, +flox/__pycache__/launcher.cpython-312.pyc,, +flox/__pycache__/settings.cpython-312.pyc,, +flox/__pycache__/string_matcher.cpython-312.pyc,, +flox/__pycache__/utils.cpython-312.pyc,, +flox/browser.py,sha256=olZ3cbG1bzXc97AK0M60CNE6JLMkJhnHdOWpnFrdk_s,2732 +flox/clipboard.py,sha256=OKkS8guLa6D1OjnQXdvh_U8cRTrGijWJBepb99mhHtk,2319 +flox/launcher.py,sha256=E9je22w2ntnCr45ARe7_5pfGhNCsA5Sx5WvyZeSV8UY,4457 +flox/settings.py,sha256=Vi67rPTrp-97vYkdCiVObiLc8m_Tg24i1emn2aahJSI,1351 +flox/string_matcher.py,sha256=2WQ3HBX4HMdPKnZr6eVNYML6kOlwjwHlhL59OkIywM4,7877 +flox/utils.py,sha256=X5-hQz80UXX94XxvshB7vVHSb4MAoZChoZ29vjgdFE0,3943 +flox/version,sha256=zoupBJrAgnX6zlL40wHdkDnSu9YNO9kG96PRVLFYOkE,7 diff --git a/lib/Flox_lib-0.19.6.dist-info/REQUESTED b/lib/Flox_lib-0.19.6.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/lib/Flox_lib-0.19.6.dist-info/WHEEL b/lib/Flox_lib-0.19.6.dist-info/WHEEL new file mode 100644 index 0000000..1f37c02 --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/lib/Flox_lib-0.19.6.dist-info/top_level.txt b/lib/Flox_lib-0.19.6.dist-info/top_level.txt new file mode 100644 index 0000000..e8a6ce2 --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/top_level.txt @@ -0,0 +1 @@ +flox diff --git a/lib/Flox_lib-0.19.6.dist-info/zip-safe b/lib/Flox_lib-0.19.6.dist-info/zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/Flox_lib-0.19.6.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/lib/bin/chardetect.exe b/lib/bin/chardetect.exe new file mode 100644 index 0000000000000000000000000000000000000000..fed0fac8a0744bc4a8ee230b09d580777df9117b GIT binary patch literal 108470 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.6 +License-File: LICENSE + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> import certifi + + >>> certifi.where() + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' + +Or from the command line:: + + $ python -m certifi + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem + +Enjoy! + +.. _`Requests`: https://requests.readthedocs.io/en/master/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. diff --git a/lib/certifi-2024.7.4.dist-info/RECORD b/lib/certifi-2024.7.4.dist-info/RECORD new file mode 100644 index 0000000..d30500b --- /dev/null +++ b/lib/certifi-2024.7.4.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2024.7.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2024.7.4.dist-info/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989 +certifi-2024.7.4.dist-info/METADATA,sha256=L9_EuPoQQvHFzxu03_ctaEZxhEty7inz569jGWjlLGo,2221 +certifi-2024.7.4.dist-info/RECORD,, +certifi-2024.7.4.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91 +certifi-2024.7.4.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=LHXz7E80YJYBzCBv6ZyidQ5-ciYSkSebpY2E5OM0l7o,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-312.pyc,, +certifi/__pycache__/__main__.cpython-312.pyc,, +certifi/__pycache__/core.cpython-312.pyc,, +certifi/cacert.pem,sha256=SIupYGAr8HzGP073rsEIaS_sQYIPwzKKjj894DgUmu4,291528 +certifi/core.py,sha256=qRDDFyXVJwTB_EmoGppaXU_R9qCZvhl-EzxPMuV3nTA,4426 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/lib/certifi-2024.7.4.dist-info/WHEEL b/lib/certifi-2024.7.4.dist-info/WHEEL new file mode 100644 index 0000000..564c672 --- /dev/null +++ b/lib/certifi-2024.7.4.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (70.2.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/lib/certifi-2024.7.4.dist-info/top_level.txt b/lib/certifi-2024.7.4.dist-info/top_level.txt new file mode 100644 index 0000000..963eac5 --- /dev/null +++ b/lib/certifi-2024.7.4.dist-info/top_level.txt @@ -0,0 +1 @@ +certifi diff --git a/lib/certifi/__init__.py b/lib/certifi/__init__.py new file mode 100644 index 0000000..d321f1b --- /dev/null +++ b/lib/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2024.07.04" diff --git a/lib/certifi/__main__.py b/lib/certifi/__main__.py new file mode 100644 index 0000000..8945b5d --- /dev/null +++ b/lib/certifi/__main__.py @@ -0,0 +1,12 @@ +import argparse + +from certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/lib/certifi/__pycache__/__init__.cpython-312.pyc b/lib/certifi/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0541492c7b7033c0bfb32509e9e67dfe88ef95c0 GIT binary patch literal 307 zcmX@j%ge<81Z*trX>maMF^B^LOi;#W1t4QOLkdF*V-7;Lkd$0b2?KL za|%loOC_r&+e=2EGEJsi9Lf24C8>EO#kW|?Gg6CEi%= zlFYPB{rLFIyv&mLc)fzkUmP~M`6;D2sdh!&Ks!JlC>942AD9^#8SgVFKHwIeP=0|+ QzJdJ)pHw4v5hqX%0J=$24gdfE literal 0 HcmV?d00001 diff --git a/lib/certifi/__pycache__/__main__.cpython-312.pyc b/lib/certifi/__pycache__/__main__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ffbe67f837ce962bd8e9bd26a2f47828fd89741 GIT binary patch literal 622 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 BcNhQw literal 0 HcmV?d00001 diff --git a/lib/certifi/cacert.pem b/lib/certifi/cacert.pem new file mode 100644 index 0000000..a658158 --- /dev/null +++ b/lib/certifi/cacert.pem @@ -0,0 +1,4798 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +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 +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global Certification Authority" +# Serial: 1846098327275375458322922162 +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P256 Certification Authority" +# Serial: 4151900041497450638097112925 +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P384 Certification Authority" +# Serial: 2704997926503831671788816187 +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz +# Label: "ANF Secure Server Root CA" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 159662449406622349769042896298 +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication RootCA3" +# Serial: 16247922307909811815 +# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26 +# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a +# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94 +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 +MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg +Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r +CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA +lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG +TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 +9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 +8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 +g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we +GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst ++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M +0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ +T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw +HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA +FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd +9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI +UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ +OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke +gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf +iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV +nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD +2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// +1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad +TdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G3 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G3" +# Serial: 576386314500428537169965010905813481816650257167 +# MD5 Fingerprint: 30:42:1b:b7:bb:81:75:35:e4:16:4f:53:d2:94:de:04 +# SHA1 Fingerprint: 63:cf:b6:c1:27:2b:56:e4:88:8e:1c:23:9a:b6:2e:81:47:24:c3:c7 +# SHA256 Fingerprint: e0:d3:22:6a:eb:11:63:c2:e4:8f:f9:be:3b:50:b4:c6:43:1b:e7:bb:1e:ac:c5:c3:6b:5d:5e:c5:09:03:9a:08 +-----BEGIN CERTIFICATE----- +MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEM +BQAwWjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dp +ZXMsIEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAe +Fw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEwMTlaMFoxCzAJBgNVBAYTAkNOMSUw +IwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtU +cnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUAA4IC +DwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNS +T1QY4SxzlZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqK +AtCWHwDNBSHvBm3dIZwZQ0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1 +nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/VP68czH5GX6zfZBCK70bwkPAPLfSIC7Ep +qq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1AgdB4SQXMeJNnKziyhWTXA +yB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm9WAPzJMs +hH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gX +zhqcD0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAv +kV34PmVACxmZySYgWmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msT +f9FkPz2ccEblooV7WIQn3MSAPmeamseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jA +uPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCFTIcQcf+eQxuulXUtgQIDAQAB +o2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj7zjKsK5Xf/Ih +MBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E +BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4 +wM8zAQLpw6o1D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2 +XFNFV1pF1AWZLy4jVe5jaN/TG3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1 +JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNjduMNhXJEIlU/HHzp/LgV6FL6qj6j +ITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstlcHboCoWASzY9M/eV +VHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys+TIx +xHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1on +AX1daBli2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d +7XB4tmBZrOFdRWOPyN9yaFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2Ntjj +gKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsASZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV ++Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFRJQJ6+N1rZdVtTTDIZbpo +FGWsJwt0ivKH +-----END CERTIFICATE----- + +# Issuer: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Subject: CN=TrustAsia Global Root CA G4 O=TrustAsia Technologies, Inc. +# Label: "TrustAsia Global Root CA G4" +# Serial: 451799571007117016466790293371524403291602933463 +# MD5 Fingerprint: 54:dd:b2:d7:5f:d8:3e:ed:7c:e0:0b:2e:cc:ed:eb:eb +# SHA1 Fingerprint: 57:73:a5:61:5d:80:b2:e6:ac:38:82:fc:68:07:31:ac:9f:b5:92:5a +# SHA256 Fingerprint: be:4b:56:cb:50:56:c0:13:6a:52:6d:f4:44:50:8d:aa:36:a0:b5:4f:42:e4:ac:38:f7:2a:f4:70:e4:79:65:4c +-----BEGIN CERTIFICATE----- +MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMw +WjELMAkGA1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMs +IEluYy4xJDAiBgNVBAMMG1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0y +MTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJaMFoxCzAJBgNVBAYTAkNOMSUwIwYD +VQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQwIgYDVQQDDBtUcnVz +dEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATx +s8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbw +LxYI+hW8m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJij +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mD +pm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/pDHel4NZg6ZvccveMA4GA1UdDwEB/wQE +AwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AAbbd+NvBNEU/zy4k6LHiR +UKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xkdUfFVZDj +/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust ECC Root-01 O=CommScope +# Subject: CN=CommScope Public Trust ECC Root-01 O=CommScope +# Label: "CommScope Public Trust ECC Root-01" +# Serial: 385011430473757362783587124273108818652468453534 +# MD5 Fingerprint: 3a:40:a7:fc:03:8c:9c:38:79:2f:3a:a2:6c:b6:0a:16 +# SHA1 Fingerprint: 07:86:c0:d8:dd:8e:c0:80:98:06:98:d0:58:7a:ef:de:a6:cc:a2:5d +# SHA256 Fingerprint: 11:43:7c:da:7b:b4:5e:41:36:5f:45:b3:9a:38:98:6b:0d:e0:0d:ef:34:8e:0c:7b:b0:87:36:33:80:0b:c3:8b +-----BEGIN CERTIFICATE----- +MIICHTCCAaOgAwIBAgIUQ3CCd89NXTTxyq4yLzf39H91oJ4wCgYIKoZIzj0EAwMw +TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t +bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMTAeFw0yMTA0MjgxNzM1NDNa +Fw00NjA0MjgxNzM1NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv +cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDEw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAARLNumuV16ocNfQj3Rid8NeeqrltqLxeP0C +flfdkXmcbLlSiFS8LwS+uM32ENEp7LXQoMPwiXAZu1FlxUOcw5tjnSCDPgYLpkJE +hRGnSjot6dZoL0hOUysHP029uax3OVejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSOB2LAUN3GGQYARnQE9/OufXVNMDAKBggq +hkjOPQQDAwNoADBlAjEAnDPfQeMjqEI2Jpc1XHvr20v4qotzVRVcrHgpD7oh2MSg +2NED3W3ROT3Ek2DS43KyAjB8xX6I01D1HiXo+k515liWpDVfG2XqYZpwI7UNo5uS +Um9poIyNStDuiw7LR47QjRE= +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust ECC Root-02 O=CommScope +# Subject: CN=CommScope Public Trust ECC Root-02 O=CommScope +# Label: "CommScope Public Trust ECC Root-02" +# Serial: 234015080301808452132356021271193974922492992893 +# MD5 Fingerprint: 59:b0:44:d5:65:4d:b8:5c:55:19:92:02:b6:d1:94:b2 +# SHA1 Fingerprint: 3c:3f:ef:57:0f:fe:65:93:86:9e:a0:fe:b0:f6:ed:8e:d1:13:c7:e5 +# SHA256 Fingerprint: 2f:fb:7f:81:3b:bb:b3:c8:9a:b4:e8:16:2d:0f:16:d7:15:09:a8:30:cc:9d:73:c2:62:e5:14:08:75:d1:ad:4a +-----BEGIN CERTIFICATE----- +MIICHDCCAaOgAwIBAgIUKP2ZYEFHpgE6yhR7H+/5aAiDXX0wCgYIKoZIzj0EAwMw +TjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwiQ29t +bVNjb3BlIFB1YmxpYyBUcnVzdCBFQ0MgUm9vdC0wMjAeFw0yMTA0MjgxNzQ0NTRa +Fw00NjA0MjgxNzQ0NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21tU2Nv +cGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgRUNDIFJvb3QtMDIw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAR4MIHoYx7l63FRD/cHB8o5mXxO1Q/MMDAL +j2aTPs+9xYa9+bG3tD60B8jzljHz7aRP+KNOjSkVWLjVb3/ubCK1sK9IRQq9qEmU +v4RDsNuESgMjGWdqb8FuvAY5N9GIIvejQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTmGHX/72DehKT1RsfeSlXjMjZ59TAKBggq +hkjOPQQDAwNnADBkAjAmc0l6tqvmSfR9Uj/UQQSugEODZXW5hYA4O9Zv5JOGq4/n +ich/m35rChJVYaoR4HkCMHfoMXGsPHED1oQmHhS48zs73u1Z/GtMMH9ZzkXpc2AV +mkzw5l4lIhVtwodZ0LKOag== +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust RSA Root-01 O=CommScope +# Subject: CN=CommScope Public Trust RSA Root-01 O=CommScope +# Label: "CommScope Public Trust RSA Root-01" +# Serial: 354030733275608256394402989253558293562031411421 +# MD5 Fingerprint: 0e:b4:15:bc:87:63:5d:5d:02:73:d4:26:38:68:73:d8 +# SHA1 Fingerprint: 6d:0a:5f:f7:b4:23:06:b4:85:b3:b7:97:64:fc:ac:75:f5:33:f2:93 +# SHA256 Fingerprint: 02:bd:f9:6e:2a:45:dd:9b:f1:8f:c7:e1:db:df:21:a0:37:9b:a3:c9:c2:61:03:44:cf:d8:d6:06:fe:c1:ed:81 +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUPgNJgXUWdDGOTKvVxZAplsU5EN0wDQYJKoZIhvcNAQEL +BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi +Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMTAeFw0yMTA0MjgxNjQ1 +NTRaFw00NjA0MjgxNjQ1NTNaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t +U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt +MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwSGWjDR1C45FtnYSk +YZYSwu3D2iM0GXb26v1VWvZVAVMP8syMl0+5UMuzAURWlv2bKOx7dAvnQmtVzslh +suitQDy6uUEKBU8bJoWPQ7VAtYXR1HHcg0Hz9kXHgKKEUJdGzqAMxGBWBB0HW0al +DrJLpA6lfO741GIDuZNqihS4cPgugkY4Iw50x2tBt9Apo52AsH53k2NC+zSDO3Oj +WiE260f6GBfZumbCk6SP/F2krfxQapWsvCQz0b2If4b19bJzKo98rwjyGpg/qYFl +P8GMicWWMJoKz/TUyDTtnS+8jTiGU+6Xn6myY5QXjQ/cZip8UlF1y5mO6D1cv547 +KI2DAg+pn3LiLCuz3GaXAEDQpFSOm117RTYm1nJD68/A6g3czhLmfTifBSeolz7p +UcZsBSjBAg/pGG3svZwG1KdJ9FQFa2ww8esD1eo9anbCyxooSU1/ZOD6K9pzg4H/ +kQO9lLvkuI6cMmPNn7togbGEW682v3fuHX/3SZtS7NJ3Wn2RnU3COS3kuoL4b/JO +Hg9O5j9ZpSPcPYeoKFgo0fEbNttPxP/hjFtyjMcmAyejOQoBqsCyMWCDIqFPEgkB +Ea801M/XrmLTBQe0MXXgDW1XT2mH+VepuhX2yFJtocucH+X8eKg1mp9BFM6ltM6U +CBwJrVbl2rZJmkrqYxhTnCwuwwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUN12mmnQywsL5x6YVEFm45P3luG0wDQYJ +KoZIhvcNAQELBQADggIBAK+nz97/4L1CjU3lIpbfaOp9TSp90K09FlxD533Ahuh6 +NWPxzIHIxgvoLlI1pKZJkGNRrDSsBTtXAOnTYtPZKdVUvhwQkZyybf5Z/Xn36lbQ +nmhUQo8mUuJM3y+Xpi/SB5io82BdS5pYV4jvguX6r2yBS5KPQJqTRlnLX3gWsWc+ +QgvfKNmwrZggvkN80V4aCRckjXtdlemrwWCrWxhkgPut4AZ9HcpZuPN4KWfGVh2v +trV0KnahP/t1MJ+UXjulYPPLXAziDslg+MkfFoom3ecnf+slpoq9uC02EJqxWE2a +aE9gVOX2RhOOiKy8IUISrcZKiX2bwdgt6ZYD9KJ0DLwAHb/WNyVntHKLr4W96ioD +j8z7PEQkguIBpQtZtjSNMgsSDesnwv1B10A8ckYpwIzqug/xBpMu95yo9GA+o/E4 +Xo4TwbM6l4c/ksp4qRyv0LAbJh6+cOx69TOY6lz/KwsETkPdY34Op054A5U+1C0w +lREQKC6/oAI+/15Z0wUOlV9TRe9rh9VIzRamloPh37MG88EU26fsHItdkJANclHn +YfkUyq+Dj7+vsQpZXdxc1+SWrVtgHdqul7I52Qb1dgAT+GhMIbA1xNxVssnBQVoc +icCMb3SgazNNtQEo/a2tiRc7ppqEvOuM6sRxJKi6KfkIsidWNTJf6jn7MZrVGczw +-----END CERTIFICATE----- + +# Issuer: CN=CommScope Public Trust RSA Root-02 O=CommScope +# Subject: CN=CommScope Public Trust RSA Root-02 O=CommScope +# Label: "CommScope Public Trust RSA Root-02" +# Serial: 480062499834624527752716769107743131258796508494 +# MD5 Fingerprint: e1:29:f9:62:7b:76:e2:96:6d:f3:d4:d7:0f:ae:1f:aa +# SHA1 Fingerprint: ea:b0:e2:52:1b:89:93:4c:11:68:f2:d8:9a:ac:22:4c:a3:8a:57:ae +# SHA256 Fingerprint: ff:e9:43:d7:93:42:4b:4f:7c:44:0c:1c:3d:64:8d:53:63:f3:4b:82:dc:87:aa:7a:9f:11:8f:c5:de:e1:01:f1 +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIUVBa/O345lXGN0aoApYYNK496BU4wDQYJKoZIhvcNAQEL +BQAwTjELMAkGA1UEBhMCVVMxEjAQBgNVBAoMCUNvbW1TY29wZTErMCkGA1UEAwwi +Q29tbVNjb3BlIFB1YmxpYyBUcnVzdCBSU0EgUm9vdC0wMjAeFw0yMTA0MjgxNzE2 +NDNaFw00NjA0MjgxNzE2NDJaME4xCzAJBgNVBAYTAlVTMRIwEAYDVQQKDAlDb21t +U2NvcGUxKzApBgNVBAMMIkNvbW1TY29wZSBQdWJsaWMgVHJ1c3QgUlNBIFJvb3Qt +MDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh+g77aAASyE3VrCLE +NQE7xVTlWXZjpX/rwcRqmL0yjReA61260WI9JSMZNRTpf4mnG2I81lDnNJUDMrG0 +kyI9p+Kx7eZ7Ti6Hmw0zdQreqjXnfuU2mKKuJZ6VszKWpCtYHu8//mI0SFHRtI1C +rWDaSWqVcN3SAOLMV2MCe5bdSZdbkk6V0/nLKR8YSvgBKtJjCW4k6YnS5cciTNxz +hkcAqg2Ijq6FfUrpuzNPDlJwnZXjfG2WWy09X6GDRl224yW4fKcZgBzqZUPckXk2 +LHR88mcGyYnJ27/aaL8j7dxrrSiDeS/sOKUNNwFnJ5rpM9kzXzehxfCrPfp4sOcs +n/Y+n2Dg70jpkEUeBVF4GiwSLFworA2iI540jwXmojPOEXcT1A6kHkIfhs1w/tku +FT0du7jyU1fbzMZ0KZwYszZ1OC4PVKH4kh+Jlk+71O6d6Ts2QrUKOyrUZHk2EOH5 +kQMreyBUzQ0ZGshBMjTRsJnhkB4BQDa1t/qp5Xd1pCKBXbCL5CcSD1SIxtuFdOa3 +wNemKfrb3vOTlycEVS8KbzfFPROvCgCpLIscgSjX74Yxqa7ybrjKaixUR9gqiC6v +wQcQeKwRoi9C8DfF8rhW3Q5iLc4tVn5V8qdE9isy9COoR+jUKgF4z2rDN6ieZdIs +5fq6M8EGRPbmz6UNp2YINIos8wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUR9DnsSL/nSz12Vdgs7GxcJXvYXowDQYJ +KoZIhvcNAQELBQADggIBAIZpsU0v6Z9PIpNojuQhmaPORVMbc0RTAIFhzTHjCLqB +KCh6krm2qMhDnscTJk3C2OVVnJJdUNjCK9v+5qiXz1I6JMNlZFxHMaNlNRPDk7n3 ++VGXu6TwYofF1gbTl4MgqX67tiHCpQ2EAOHyJxCDut0DgdXdaMNmEMjRdrSzbyme +APnCKfWxkxlSaRosTKCL4BWaMS/TiJVZbuXEs1DIFAhKm4sTg7GkcrI7djNB3Nyq +pgdvHSQSn8h2vS/ZjvQs7rfSOBAkNlEv41xdgSGn2rtO/+YHqP65DSdsu3BaVXoT +6fEqSWnHX4dXTEN5bTpl6TBcQe7rd6VzEojov32u5cSoHw2OHG1QAk8mGEPej1WF +sQs3BWDJVTkSBKEqz3EWnzZRSb9wO55nnPt7eck5HHisd5FUmrh1CoFSl+NmYWvt +PjgelmFV4ZFUjO2MJB+ByRCac5krFk5yAD9UG/iNuovnFNa2RU9g7Jauwy8CTl2d +lklyALKrdVwPaFsdZcJfMw8eD/A7hvWwTruc9+olBdytoptLFwG+Qt81IR2tq670 +v64fG9PiO/yzcnMcmyiQiRM9HcEARwmWmjgb3bHPDcK0RPOWlc4yOo80nOAXx17O +rg3bhzjlP1v9mxnhMUF6cKojawHhRUzNlM47ni3niAIi9G7oyOzWPPO5std3eqx7 +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS ECC Root 2020 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS ECC Root 2020" +# Serial: 72082518505882327255703894282316633856 +# MD5 Fingerprint: c1:ab:fe:6a:10:2c:03:8d:bc:1c:22:32:c0:85:a7:fd +# SHA1 Fingerprint: c0:f8:96:c5:a9:3b:01:06:21:07:da:18:42:48:bc:e9:9d:88:d5:ec +# SHA256 Fingerprint: 57:8a:f4:de:d0:85:3f:4e:59:98:db:4a:ea:f9:cb:ea:8d:94:5f:60:b6:20:a3:8d:1a:3c:13:b2:bc:7b:a8:e1 +-----BEGIN CERTIFICATE----- +MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQsw +CQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBH +bWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIw +MB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIzNTk1OVowYzELMAkGA1UEBhMCREUx +JzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkGA1UE +AwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/O +tdKPD/M12kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDP +f8iAC8GXs7s1J8nCG6NCMEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6f +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2cA +MGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZMo7k+5Dck2TOrbRBR2Di +z6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdUga/sf+Rn +27iQ7t0l +-----END CERTIFICATE----- + +# Issuer: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Subject: CN=Telekom Security TLS RSA Root 2023 O=Deutsche Telekom Security GmbH +# Label: "Telekom Security TLS RSA Root 2023" +# Serial: 44676229530606711399881795178081572759 +# MD5 Fingerprint: bf:5b:eb:54:40:cd:48:71:c4:20:8d:7d:de:0a:42:f2 +# SHA1 Fingerprint: 54:d3:ac:b3:bd:57:56:f6:85:9d:ce:e5:c3:21:e2:d4:ad:83:d0:93 +# SHA256 Fingerprint: ef:c6:5c:ad:bb:59:ad:b6:ef:e8:4d:a2:23:11:b3:56:24:b7:1b:3b:1e:a0:da:8b:66:55:17:4e:c8:97:86:46 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIQIZxULej27HF3+k7ow3BXlzANBgkqhkiG9w0BAQwFADBj +MQswCQYDVQQGEwJERTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0 +eSBHbWJIMSswKQYDVQQDDCJUZWxla29tIFNlY3VyaXR5IFRMUyBSU0EgUm9vdCAy +MDIzMB4XDTIzMDMyODEyMTY0NVoXDTQ4MDMyNzIzNTk1OVowYzELMAkGA1UEBhMC +REUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkgR21iSDErMCkG +A1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgUlNBIFJvb3QgMjAyMzCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAO01oYGA88tKaVvC+1GDrib94W7zgRJ9 +cUD/h3VCKSHtgVIs3xLBGYSJwb3FKNXVS2xE1kzbB5ZKVXrKNoIENqil/Cf2SfHV +cp6R+SPWcHu79ZvB7JPPGeplfohwoHP89v+1VmLhc2o0mD6CuKyVU/QBoCcHcqMA +U6DksquDOFczJZSfvkgdmOGjup5czQRxUX11eKvzWarE4GC+j4NSuHUaQTXtvPM6 +Y+mpFEXX5lLRbtLevOP1Czvm4MS9Q2QTps70mDdsipWol8hHD/BeEIvnHRz+sTug +BTNoBUGCwQMrAcjnj02r6LX2zWtEtefdi+zqJbQAIldNsLGyMcEWzv/9FIS3R/qy +8XDe24tsNlikfLMR0cN3f1+2JeANxdKz+bi4d9s3cXFH42AYTyS2dTd4uaNir73J +co4vzLuu2+QVUhkHM/tqty1LkCiCc/4YizWN26cEar7qwU02OxY2kTLvtkCJkUPg +8qKrBC7m8kwOFjQgrIfBLX7JZkcXFBGk8/ehJImr2BrIoVyxo/eMbcgByU/J7MT8 +rFEz0ciD0cmfHdRHNCk+y7AO+oMLKFjlKdw/fKifybYKu6boRhYPluV75Gp6SG12 +mAWl3G0eQh5C2hrgUve1g8Aae3g1LDj1H/1Joy7SWWO/gLCMk3PLNaaZlSJhZQNg ++y+TS/qanIA7AgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtqeX +gj10hZv3PJ+TmpV5dVKMbUcwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS2 +p5eCPXSFm/c8n5OalXl1UoxtRzANBgkqhkiG9w0BAQwFAAOCAgEAqMxhpr51nhVQ +pGv7qHBFfLp+sVr8WyP6Cnf4mHGCDG3gXkaqk/QeoMPhk9tLrbKmXauw1GLLXrtm +9S3ul0A8Yute1hTWjOKWi0FpkzXmuZlrYrShF2Y0pmtjxrlO8iLpWA1WQdH6DErw +M807u20hOq6OcrXDSvvpfeWxm4bu4uB9tPcy/SKE8YXJN3nptT+/XOR0so8RYgDd +GGah2XsjX/GO1WfoVNpbOms2b/mBsTNHM3dA+VKq3dSDz4V4mZqTuXNnQkYRIer+ +CqkbGmVps4+uFrb2S1ayLfmlyOw7YqPta9BO1UAJpB+Y1zqlklkg5LB9zVtzaL1t +xKITDmcZuI1CfmwMmm6gJC3VRRvcxAIU/oVbZZfKTpBQCHpCNfnqwmbU+AGuHrS+ +w6jv/naaoqYfRvaE7fzbzsQCzndILIyy7MMAo+wsVRjBfhnu4S/yrYObnqsZ38aK +L4x35bcF7DvB7L6Gs4a8wPfc5+pbrrLMtTWGS9DiP7bY+A4A7l3j941Y/8+LN+lj +X273CXE2whJdV/LItM3z7gLfEdxquVeEHVlNjM7IDiPCtyaaEBRx/pOyiriA8A4Q +ntOoUAw3gi/q4Iqd4Sw5/7W0cwDk90imc6y/st53BIe0o82bNSQ3+pCTE4FCxpgm +dTdmQRCsu/WU48IxK63nI1bMNSWSs1A= +-----END CERTIFICATE----- + +# Issuer: CN=FIRMAPROFESIONAL CA ROOT-A WEB O=Firmaprofesional SA +# Subject: CN=FIRMAPROFESIONAL CA ROOT-A WEB O=Firmaprofesional SA +# Label: "FIRMAPROFESIONAL CA ROOT-A WEB" +# Serial: 65916896770016886708751106294915943533 +# MD5 Fingerprint: 82:b2:ad:45:00:82:b0:66:63:f8:5f:c3:67:4e:ce:a3 +# SHA1 Fingerprint: a8:31:11:74:a6:14:15:0d:ca:77:dd:0e:e4:0c:5d:58:fc:a0:72:a5 +# SHA256 Fingerprint: be:f2:56:da:f2:6e:9c:69:bd:ec:16:02:35:97:98:f3:ca:f7:18:21:a0:3e:01:82:57:c5:3c:65:61:7f:3d:4a +-----BEGIN CERTIFICATE----- +MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQsw +CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE +YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB +IFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2WhcNNDcwMzMxMDkwMTM2WjBuMQsw +CQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UE +YQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENB +IFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zf +e9MEkVz6iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6C +cyvHZpsKjECcfIr28jlgst7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FDY1w8ndYn81LsF7Kpryz3dvgwHQYDVR0O +BBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO +PQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFw +hVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dG +XSaQpYXFuXqUPoeovQA= +-----END CERTIFICATE----- diff --git a/lib/certifi/core.py b/lib/certifi/core.py new file mode 100644 index 0000000..91f538b --- /dev/null +++ b/lib/certifi/core.py @@ -0,0 +1,114 @@ +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import sys +import atexit + +def exit_cacert_ctx() -> None: + _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr] + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: + return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") + +elif sys.version_info >= (3, 7): + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the + # file in cases where we're inside of a zipimport situation until + # someone actually calls where(), but we don't want to re-extract + # the file on every call of where(), so we'll do it once then store + # it in a global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you + # to manage the cleanup of this file, so it doesn't actually + # return a path, it returns a context manager that will give + # you the path when you enter it and will do any cleanup when + # you leave it. In the common case of not needing a temporary + # file, it will just return the file system location and the + # __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + atexit.register(exit_cacert_ctx) + + return _CACERT_PATH + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") + +else: + import os + import types + from typing import Union + + Package = Union[types.ModuleType, str] + Resource = Union[str, "os.PathLike"] + + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict' + ) -> str: + with open(where(), encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where() -> str: + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/lib/certifi/py.typed b/lib/certifi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/lib/chardet-4.0.0.dist-info/INSTALLER b/lib/chardet-4.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/chardet-4.0.0.dist-info/LICENSE b/lib/chardet-4.0.0.dist-info/LICENSE new file mode 100644 index 0000000..8add30a --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/lib/chardet-4.0.0.dist-info/METADATA b/lib/chardet-4.0.0.dist-info/METADATA new file mode 100644 index 0000000..590bcc3 --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/METADATA @@ -0,0 +1,101 @@ +Metadata-Version: 2.1 +Name: chardet +Version: 4.0.0 +Summary: Universal encoding detector for Python 2 and 3 +Home-page: https://github.com/chardet/chardet +Author: Mark Pilgrim +Author-email: mark@diveintomark.org +Maintainer: Daniel Blanchard +Maintainer-email: dan.blanchard@gmail.com +License: LGPL +Keywords: encoding,i18n,xml +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL) +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Linguistic +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* + +Chardet: The Universal Character Encoding Detector +-------------------------------------------------- + +.. image:: https://img.shields.io/travis/chardet/chardet/stable.svg + :alt: Build status + :target: https://travis-ci.org/chardet/chardet + +.. image:: https://img.shields.io/coveralls/chardet/chardet/stable.svg + :target: https://coveralls.io/r/chardet/chardet + +.. image:: https://img.shields.io/pypi/v/chardet.svg + :target: https://warehouse.python.org/project/chardet/ + :alt: Latest version on PyPI + +.. image:: https://img.shields.io/pypi/l/chardet.svg + :alt: License + + +Detects + - ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants) + - Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese) + - EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP (Japanese) + - EUC-KR, ISO-2022-KR (Korean) + - KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic) + - ISO-8859-5, windows-1251 (Bulgarian) + - ISO-8859-1, windows-1252 (Western European languages) + - ISO-8859-7, windows-1253 (Greek) + - ISO-8859-8, windows-1255 (Visual and Logical Hebrew) + - TIS-620 (Thai) + +.. note:: + Our ISO-8859-2 and windows-1250 (Hungarian) probers have been temporarily + disabled until we can retrain the models. + +Requires Python 2.7 or 3.5+. + +Installation +------------ + +Install from `PyPI `_:: + + pip install chardet + +Documentation +------------- + +For users, docs are now available at https://chardet.readthedocs.io/. + +Command-line Tool +----------------- + +chardet comes with a command-line script which reports on the encodings of one +or more files:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +About +----- + +This is a continuation of Mark Pilgrim's excellent chardet. Previously, two +versions needed to be maintained: one that supported python 2.x and one that +supported python 3.x. We've recently merged with `Ian Cordasco `_'s +`charade `_ fork, so now we have one +coherent version that works for Python 2.7+ and 3.4+. + +:maintainer: Dan Blanchard + + diff --git a/lib/chardet-4.0.0.dist-info/RECORD b/lib/chardet-4.0.0.dist-info/RECORD new file mode 100644 index 0000000..66d684f --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/RECORD @@ -0,0 +1,94 @@ +../../bin/chardetect.exe,sha256=HwPkUB74rQL7xgePWXnoEZHBPZSmFrwjVeH9XgUUkCs,108470 +chardet-4.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +chardet-4.0.0.dist-info/LICENSE,sha256=YJXp_6d33SKDn3gBqoRbMcntB_PWv4om3F0t7IzMDvM,26432 +chardet-4.0.0.dist-info/METADATA,sha256=ySYQAE7NPm3LwxgMqFi1zdLQ48mmwMbrJwqAWCtcbH8,3526 +chardet-4.0.0.dist-info/RECORD,, +chardet-4.0.0.dist-info/WHEEL,sha256=ADKeyaGyKF5DwBNE0sRE5pvW-bSkFMJfBuhzZ3rceP4,110 +chardet-4.0.0.dist-info/entry_points.txt,sha256=fAMmhu5eJ-zAJ-smfqQwRClQ3-nozOCmvJ6-E8lgGJo,60 +chardet-4.0.0.dist-info/top_level.txt,sha256=AowzBbZy4x8EirABDdJSLJZMkJ_53iIag8xfKR6D7kI,8 +chardet/__init__.py,sha256=mWZaWmvZkhwfBEAT9O1Y6nRTfKzhT7FHhQTTAujbqUA,3271 +chardet/__pycache__/__init__.cpython-312.pyc,, +chardet/__pycache__/big5freq.cpython-312.pyc,, +chardet/__pycache__/big5prober.cpython-312.pyc,, +chardet/__pycache__/chardistribution.cpython-312.pyc,, +chardet/__pycache__/charsetgroupprober.cpython-312.pyc,, +chardet/__pycache__/charsetprober.cpython-312.pyc,, +chardet/__pycache__/codingstatemachine.cpython-312.pyc,, +chardet/__pycache__/compat.cpython-312.pyc,, +chardet/__pycache__/cp949prober.cpython-312.pyc,, +chardet/__pycache__/enums.cpython-312.pyc,, +chardet/__pycache__/escprober.cpython-312.pyc,, +chardet/__pycache__/escsm.cpython-312.pyc,, +chardet/__pycache__/eucjpprober.cpython-312.pyc,, +chardet/__pycache__/euckrfreq.cpython-312.pyc,, +chardet/__pycache__/euckrprober.cpython-312.pyc,, +chardet/__pycache__/euctwfreq.cpython-312.pyc,, +chardet/__pycache__/euctwprober.cpython-312.pyc,, +chardet/__pycache__/gb2312freq.cpython-312.pyc,, +chardet/__pycache__/gb2312prober.cpython-312.pyc,, +chardet/__pycache__/hebrewprober.cpython-312.pyc,, +chardet/__pycache__/jisfreq.cpython-312.pyc,, +chardet/__pycache__/jpcntx.cpython-312.pyc,, +chardet/__pycache__/langbulgarianmodel.cpython-312.pyc,, +chardet/__pycache__/langgreekmodel.cpython-312.pyc,, +chardet/__pycache__/langhebrewmodel.cpython-312.pyc,, +chardet/__pycache__/langhungarianmodel.cpython-312.pyc,, +chardet/__pycache__/langrussianmodel.cpython-312.pyc,, +chardet/__pycache__/langthaimodel.cpython-312.pyc,, +chardet/__pycache__/langturkishmodel.cpython-312.pyc,, +chardet/__pycache__/latin1prober.cpython-312.pyc,, +chardet/__pycache__/mbcharsetprober.cpython-312.pyc,, +chardet/__pycache__/mbcsgroupprober.cpython-312.pyc,, +chardet/__pycache__/mbcssm.cpython-312.pyc,, +chardet/__pycache__/sbcharsetprober.cpython-312.pyc,, +chardet/__pycache__/sbcsgroupprober.cpython-312.pyc,, +chardet/__pycache__/sjisprober.cpython-312.pyc,, +chardet/__pycache__/universaldetector.cpython-312.pyc,, +chardet/__pycache__/utf8prober.cpython-312.pyc,, +chardet/__pycache__/version.cpython-312.pyc,, +chardet/big5freq.py,sha256=D_zK5GyzoVsRes0HkLJziltFQX0bKCLOrFe9_xDvO_8,31254 +chardet/big5prober.py,sha256=kBxHbdetBpPe7xrlb-e990iot64g_eGSLd32lB7_h3M,1757 +chardet/chardistribution.py,sha256=3woWS62KrGooKyqz4zQSnjFbJpa6V7g02daAibTwcl8,9411 +chardet/charsetgroupprober.py,sha256=GZLReHP6FRRn43hvSOoGCxYamErKzyp6RgOQxVeC3kg,3839 +chardet/charsetprober.py,sha256=KSmwJErjypyj0bRZmC5F5eM7c8YQgLYIjZXintZNstg,5110 +chardet/cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +chardet/cli/__pycache__/__init__.cpython-312.pyc,, +chardet/cli/__pycache__/chardetect.cpython-312.pyc,, +chardet/cli/chardetect.py,sha256=kUPeQCi-olObXpOq5MtlKuBn1EU19rkeenAMwxl7URY,2711 +chardet/codingstatemachine.py,sha256=VYp_6cyyki5sHgXDSZnXW4q1oelHc3cu9AyQTX7uug8,3590 +chardet/compat.py,sha256=40zr6wICZwknxyuLGGcIOPyve8DTebBCbbvttvnmp5Q,1200 +chardet/cp949prober.py,sha256=TZ434QX8zzBsnUvL_8wm4AQVTZ2ZkqEEQL_lNw9f9ow,1855 +chardet/enums.py,sha256=Aimwdb9as1dJKZaFNUH2OhWIVBVd6ZkJJ_WK5sNY8cU,1661 +chardet/escprober.py,sha256=kkyqVg1Yw3DIOAMJ2bdlyQgUFQhuHAW8dUGskToNWSc,3950 +chardet/escsm.py,sha256=RuXlgNvTIDarndvllNCk5WZBIpdCxQ0kcd9EAuxUh84,10510 +chardet/eucjpprober.py,sha256=iD8Jdp0ISRjgjiVN7f0e8xGeQJ5GM2oeZ1dA8nbSeUw,3749 +chardet/euckrfreq.py,sha256=-7GdmvgWez4-eO4SuXpa7tBiDi5vRXQ8WvdFAzVaSfo,13546 +chardet/euckrprober.py,sha256=MqFMTQXxW4HbzIpZ9lKDHB3GN8SP4yiHenTmf8g_PxY,1748 +chardet/euctwfreq.py,sha256=No1WyduFOgB5VITUA7PLyC5oJRNzRyMbBxaKI1l16MA,31621 +chardet/euctwprober.py,sha256=13p6EP4yRaxqnP4iHtxHOJ6R2zxHq1_m8hTRjzVZ95c,1747 +chardet/gb2312freq.py,sha256=JX8lsweKLmnCwmk8UHEQsLgkr_rP_kEbvivC4qPOrlc,20715 +chardet/gb2312prober.py,sha256=gGvIWi9WhDjE-xQXHvNIyrnLvEbMAYgyUSZ65HUfylw,1754 +chardet/hebrewprober.py,sha256=c3SZ-K7hvyzGY6JRAZxJgwJ_sUS9k0WYkvMY00YBYFo,13838 +chardet/jisfreq.py,sha256=vpmJv2Bu0J8gnMVRPHMFefTRvo_ha1mryLig8CBwgOg,25777 +chardet/jpcntx.py,sha256=PYlNqRUQT8LM3cT5FmHGP0iiscFlTWED92MALvBungo,19643 +chardet/langbulgarianmodel.py,sha256=r6tvOtO8FqhnbWBB5V4czcl1fWM4pB9lGiWQU-8gvsw,105685 +chardet/langgreekmodel.py,sha256=1cMu2wUgPB8bQ2RbVjR4LNwCCETgQ-Dwo0Eg2_uB11s,99559 +chardet/langhebrewmodel.py,sha256=urMmJHHIXtCwaWAqy1zEY_4SmwwNzt730bDOtjXzRjs,98764 +chardet/langhungarianmodel.py,sha256=ODAisvqCfes8B4FeyM_Pg9HY3ZDnEyaCiT4Bxyzoc6w,102486 +chardet/langrussianmodel.py,sha256=sPqkrBbX0QVwwy6oqRl-x7ERv2J4-zaMoCvLpkSsSJI,131168 +chardet/langthaimodel.py,sha256=ppoKOGL9OPdj9A4CUyG8R48zbnXt9MN1WXeCYepa6sc,103300 +chardet/langturkishmodel.py,sha256=H3ldicI_rhlv0r3VFpVWtUL6X30Wy596v7_YHz2sEdg,95934 +chardet/latin1prober.py,sha256=S2IoORhFk39FEFOlSFWtgVybRiP6h7BlLldHVclNkU8,5370 +chardet/mbcharsetprober.py,sha256=AR95eFH9vuqSfvLQZN-L5ijea25NOBCoXqw8s5O9xLQ,3413 +chardet/mbcsgroupprober.py,sha256=h6TRnnYq2OxG1WdD5JOyxcdVpn7dG0q-vB8nWr5mbh4,2012 +chardet/mbcssm.py,sha256=SY32wVIF3HzcjY3BaEspy9metbNSKxIIB0RKPn7tjpI,25481 +chardet/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +chardet/metadata/__pycache__/__init__.cpython-312.pyc,, +chardet/metadata/__pycache__/languages.cpython-312.pyc,, +chardet/metadata/languages.py,sha256=41tLq3eLSrBEbEVVQpVGFq9K7o1ln9b1HpY1l0hCUQo,19474 +chardet/sbcharsetprober.py,sha256=nmyMyuxzG87DN6K3Rk2MUzJLMLR69MrWpdnHzOwVUwQ,6136 +chardet/sbcsgroupprober.py,sha256=hqefQuXmiFyDBArOjujH6hd6WFXlOD1kWCsxDhjx5Vc,4309 +chardet/sjisprober.py,sha256=IIt-lZj0WJqK4rmUZzKZP4GJlE8KUEtFYVuY96ek5MQ,3774 +chardet/universaldetector.py,sha256=DpZTXCX0nUHXxkQ9sr4GZxGB_hveZ6hWt3uM94cgWKs,12503 +chardet/utf8prober.py,sha256=IdD8v3zWOsB8OLiyPi-y_fqwipRFxV9Nc1eKBLSuIEw,2766 +chardet/version.py,sha256=A4CILFAd8MRVG1HoXPp45iK9RLlWyV73a1EtwE8Tvn8,242 diff --git a/lib/chardet-4.0.0.dist-info/WHEEL b/lib/chardet-4.0.0.dist-info/WHEEL new file mode 100644 index 0000000..6d38aa0 --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.35.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/lib/chardet-4.0.0.dist-info/entry_points.txt b/lib/chardet-4.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..a884269 --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +chardetect = chardet.cli.chardetect:main + diff --git a/lib/chardet-4.0.0.dist-info/top_level.txt b/lib/chardet-4.0.0.dist-info/top_level.txt new file mode 100644 index 0000000..79236f2 --- /dev/null +++ b/lib/chardet-4.0.0.dist-info/top_level.txt @@ -0,0 +1 @@ +chardet diff --git a/lib/chardet/__init__.py b/lib/chardet/__init__.py new file mode 100644 index 0000000..80ad254 --- /dev/null +++ b/lib/chardet/__init__.py @@ -0,0 +1,83 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .universaldetector import UniversalDetector +from .enums import InputState +from .version import __version__, VERSION + + +__all__ = ['UniversalDetector', 'detect', 'detect_all', '__version__', 'VERSION'] + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() + + +def detect_all(byte_str): + """ + Detect all the possible encodings of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + + detector = UniversalDetector() + detector.feed(byte_str) + detector.close() + + if detector._input_state == InputState.HIGH_BYTE: + results = [] + for prober in detector._charset_probers: + if prober.get_confidence() > detector.MINIMUM_THRESHOLD: + charset_name = prober.charset_name + lower_charset_name = prober.charset_name.lower() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if detector._has_win_bytes: + charset_name = detector.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + results.append({ + 'encoding': charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language, + }) + if len(results) > 0: + return sorted(results, key=lambda result: -result['confidence']) + + return [detector.result] diff --git a/lib/chardet/__pycache__/__init__.cpython-312.pyc b/lib/chardet/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43b4b87534252d65175dbe5390c65deef3364110 GIT binary patch literal 2992 zcmd@WOHUg|c-CG&u#F9v00|~61TanlBxxERK~7Sjg@#89qz~k3S=hzctashnCB)Q7 zq^cC6MoM~uLk~?Gsi}yn^wxjSLoYZ+vb&;6r1p{<4dlY9->kj3329F~RO(3k%{Sj` zzMc6V^K)^r1HrJ+H)eivA@mzr7{ioDb}j<4ig?6RB8pKH6h&~8Xo{I9%sOrs>6m50 z60=TNDHKLL{WUdV<1L?|2|I5ESd_2@>`y5$6QH!xD^ldDfE7;c6;xqbl`#+<15$im z9aA|~2$(b{%Myu*EU~O+d#`VFY+z(KV8LdvpjmlcO>^XCmJ>y60S2}Lm?oPT!v+XZ z+1UlKiqw5x5~;?|q4hkb1Yh9OhLL^#F_qZU2Tw(d47@O_P6JP(_55Bh&!18%@kk#9 zsU@Tq8`SkYvP31RsK=ld=7JW5K%%t3F)+iz7z&sczi}`yawpBGvjQVX(=s2C!i+ql zufuQ|5;K)h1x8UZFj^hDN>`l2Tuf)Mz~~}om~k+W6BRz52TKB@%8YQ0i$x@%HK(Q~ z;yIau7Be|Xl$6OyM#lLChcTC!oYZypUhBIShe!~3MxKfSqWfmpQHT=J*Hun3VOi~B zK3NJBX^w~zkrb5!KeVEK3C*H!rWK8Yg+7dBtXXGd9OG1tCeG!eh@KGyUb9S#vO*%x zPIQRJnmrd*GFC`nFwEXqPgm%Q0^t}MjiKv9cbYfp>a5dyJ9smgc2;lD)jP1!-{i<1{O zP|J;Vw8Fp&^IS9B-Y;RaWP%K=D$otA7k%^qp(S(D93}Vr(lGK9bbT+eU^&+d0YTlW z1Kpzsxl8n`>Cw7_vc^73mZT+m>>!^vt>>#0ZU$c(4oYAj(3=j@qk)68q$NokwGzBE zMNhm!hIs!^Ct{ACJgCK+zcd@3Qs~zAG*a6PspS4Y@H9C&>{d?~c%%hAuo_;Ck$QQ? z;1=dE1(nja_=8@H@|6;rie4S#vZ6$$#6sDGYV@C}o0#!vh3i(g-n;$E5k;5&}re#H7<z3)Iac6 zKl{dq<9%8QOA4+csB9d|Q&6`xH&kZ!FXvG@G%!3cbY+Mg?;q_O>mM2H)m(;-#Ki>7 zBFYN_)*P?_R+WW_I;*+aSx#XWA`+YHF3y3m5%&FoVRq=!JDM3b(5zfME=W8+Li{m{ zf}~j$8ADUUB##4DOwJjTx}w?gr>R+UE@F~nTA9AyO}hMv&6BbDQa0Z`M}|3@V$MFYoz0e&uh_B`M>7>|sfxB| z$X(=Jc{A%dl<_pAJPm12)BUPUpeGgRNqc&-wT+qDGpX7$cU;-V6Pd=2RAWb`F_>x$ zrW-GAl+w)|o2hJlRN0#Kw`Kh2Q~vWA|AmzQ!p6nXYHdftSn d)4!sc$0+d3ikzd=vhA7GL-}?Zny4Dx#-A(Up&bAK literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/big5freq.cpython-312.pyc b/lib/chardet/__pycache__/big5freq.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b86562a28278f3ea42458ab44e48c262bf0b473 GIT binary patch literal 27188 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 C@vuPv literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/big5prober.cpython-312.pyc b/lib/chardet/__pycache__/big5prober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b71f78267f715026c37c4f448dacb511ae994764 GIT binary patch literal 1342 zcmah}&2Q936o2Ejcb#RIKu`kPQ_6>0w+clF5JG$=sZgsdMM}9?D~-JC*^Q~aYi4Ez zj&jH$5qgYn1jDALC3w-cN2oZ4!QMwTtQOPZ7y%d^}Cl$wjN6>OeI@276GMG;!TUhb2i}ce_8x-sgswkHzPMj*HL+loiK2T z53aEZUE-4s+buEEH#T59Kj>O$m&WY!COjf;Wf>eZt*RojLOZIDVyO<*H~JmLA7l$; z5dm3L0Bi8<5FF$oAS=ZoX&2gd{^}agVgexR2hm)?=)v7JxPP>Wf8L932qXyh9cLo7 z#4u)@t4yg)Y0wWOrQAf5ZpA@7Cq3R{a<2QE>?ZtS zw-pBMR-DL{LBG{OI`~Zf&_<|Z&55&d!Vx)GJ@y&?vqcN1Fd)vM_-`F{?E2IDf1ZA2 zfBVM%Zm046U(MHzE1Txi!#iiLy*_he(|lu}{Ku|6uRf_htBvpud@)7k&{I^XY(YXC z<4$U-oG;)7;gjeUYCf}EA)eM$r3eP?dl6ebK33a!z)`mpqU-SQs zLTyiJd*$5M(7t{2HFTZ&2}Rb)sGVb&F@USFq*ED1h59i>*^faJI6a~{Gsf49!ex9# zAfFY#vl2C&Y6QCMkM`9JiR=6{`V_)q7R6qP5c1(NkPEwTeitt7!q@xdI%&K-`ppNx HUDx^v8?ifm literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/chardistribution.cpython-312.pyc b/lib/chardet/__pycache__/chardistribution.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..245bf5b88b439c88cad96c86046cf254cc34abf6 GIT binary patch literal 8258 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/charsetgroupprober.cpython-312.pyc b/lib/chardet/__pycache__/charsetgroupprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4aa85208eccf14e0054b75a8e6396e588ebed6e0 GIT binary patch literal 3830 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 Hj?VuA>OnF= literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/codingstatemachine.cpython-312.pyc b/lib/chardet/__pycache__/codingstatemachine.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ad694577eb65004507deb855df4f5ae1bf3eecc GIT binary patch literal 3607 zcmb_f%Wo4$7@zek8`}`tfJt$|Q&S}vh!ONb1qeh5t<*wV5!!=syV~rIlMU-#GrJBr z1c?JugVYN3Qm9n5^wc6Ml|P~PURVlBwBmqN^}r31_QI*(H@j=+;q=szGX7@fd;I2m z&F1$F8`1z=Qq$26064RwhT#sEN zm4qILIf+IpDLn~ukDh{AX1#jPHF7r;ucTXYsn>t`gsmIagfJ7DRKH0OlBO_@QwPn{ zdVqzxHl1eNsI{m{$6IjVunSFQX^hrv4touiyN1>@RZd}7C@$0YY%Y{BP!dSFlZ@&N zuH}LhXBso6nX{J~F1=`&Cap21Q+HBzLvEWgunIOc7Z`=Em9W%l)iBj@lkKIp#R4gi zR;g>$S(%;%b1Mb3N!6NQ4p?-SsT)@vFl<}6O&gp|8+OwPB~=R{g}MP~gj#6ljH>YW zMn@N@w!r>MtKv$?XxHG_Wt=%Kx>N<$rfUyJE;*DIipI_!KXW!vaR}~UfKEqX2(*GA z5FCBxPQt~}|0bJI&6SZ6sxX%AvCAlfQ&c*wnubmxN{lvaz*7=I1lMqIG~;wqb?7)_ z;0~Qxu2D0XUJj6*J{iFZaap>dL7pHy@H_fx<;^=9!0w8~Sq)DpfO|R(rh!Qf{e$`t zmcv}k5jfSEV@y~OERl91G^)E+6?hoAEt}e)gTpl)$AC0xCnvo)X+TnH5CP4$Tor=m zqN5SwYIRYnW5j_)WGa9&nF^U9f@sw1OgFGzz>tBt3ZZo_f?!=)wYFjvoUDC`Z zBpG^kt-45x*0^2AC^(QT94tT`iY*8nRE$*?qFU7au!+UPzolD1+$6KoEKzV@3>{b4 zOFOH!tWMwzrNwZ2BWg-?_GlHJW~24pP#ehhM0>Mj>ZOS8{6;NSA}vyijdC;$tv039 zq1a4+qoOrAS1`#G$dqV}DXy5z@-xA?C?UVcv?nH@LHoTE%smA(w(9)?en=IFE{jy{6}uT;FPmB($~{pWtTvn zXzh@~0#^22k9NAdvQ0-N2l^#jlj*-EB>WA)IbS72*a%vWN- z(}vvPbP=@}Q>lpR{GQ(hpm*pXtF-ynu@x7#Vqzvr^zDMkx>#LDM*^j1Kz24Z1JsrH zI($iCC9t@xE@#OlX-e*(k0?DgvjP3L;tpLC`19sp z^LO(1KKDu^UT$Pzp!hs4ZQVJSev&WzaQNH9x375lx9&}O`QuoM0}FC?Ud}&|^S3T| zGJOQK+1EecSMd4@_vJ#6&&!JsX;FOJfLJe|#|YmF$0bR)kz*1pD=xnunvQ68@PVOV z$e{hr40iEX7ru{C7kq$&;{?#6*H^qR7uN#Cv=Kll5bFUA3J=mLHtHv^xk4)tDX|*z zfPf-CZG-qKVK!B!){-?)7J@~yZ3H~g{*U$;#a-i0Bsu-fT-H*9w8 z){)q!9dJ+j`USW{UfY0sy^a$!DB{ZvZZ{ZrTLR7T#={5Ls-h}BIc^=!GloxlWl3NxxNy+kJ zDx0K>uS&_Ciz%3(a8ete$E4)YQaqvpg{Y>KZ}{gqpSKVk)427X41_+CWpeaiF}eY9k0_#A z7ukrR_QaWxFsa^wTT!Oi)~R7*W-!y!?I~v388+Qs_=EmRI~!|2>hJ35c0)k7$%ckB@dY$w>r3r0zi5;e5}L4ylK( z(`>H24c$Fda$#BDi(GP&l4J?_X=9*?KDdLcdUvTad> z1Pv-8(7v#yX`>aS&3sKEBlCufFSt1HUh(qKD)e`U)-1GA`Jp`6?$?KN<$i5ASGq6U d6|QUVsh3ivrH75dRss}%0PD`Wu8DaF_y!Sqh>8FJ literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/cp949prober.cpython-312.pyc b/lib/chardet/__pycache__/cp949prober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..738253adfe08f8d6679ee8133337b033180dc154 GIT binary patch literal 1351 zcmah}&1>976n~?Yw6f#1T~mMcWZVxbOp=o3kdKm&u0x@*-4Hi9h=oCxW^FZ+R+*V4 zmGQv`LtIE`FU9>Ag8QHJ(vlpCh@sF^Z!YUV$f<8elCwE=KyTj1%)Ix0zlVNnwMGG# zWj^j+ZvyGWZ&m0|+4`F(kwzMCnFsBn_{j^+s$amS<_*jP0c9H3=B-6@=Cv zgf_Dd8|7P`lQ&)GAA*)kiuqgj+PCj6M?&&wqc5XgdNcLoTtotcQ|(?DrJL*0mu%G! zwxX1wcV@L8%jnBovi6qG*O|P-dmD^nWW0Un^2N(^eU+|$vwUkMsEXH{Q5l14s657A z7>rr-=wiguPtSskOuE)g7QU2_Rdi(MrMS>D?Xp?!7wxcCXtZkR#q} z?nq&Ye#SUgnF@!}D2*hg+(eVx$~O{d)Tv0g>ZF(shuERMqGy}&!s1LY=^BM8Sllf} zC=Fs?2ug+Ob7A+*{q~j4J;Au>toSHyX4$eY{mx1+@Z-+6EXg`ql%176-(>P^_krx@ z{86_PM;o0ims`EG6Ck}IljnmBS{uA_)oby8Z4QkwL_eysE{N+0(9 zxQu9^3kQM6agjNnRmndGCEd_i=-JX@Q3XCj@p=zV4BMJMo&U8j^M%(e0~IrC-wxH N`+e%uSAe^&^*{CVI|Kj# literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/enums.cpython-312.pyc b/lib/chardet/__pycache__/enums.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfacd6fd6f2f31ed9fdcff80f68b2b9bd0d8b035 GIT binary patch literal 2907 zcmbVOU2EG`7?!_eS#g}$8QmDAJ8bKi2X)6_y~xIxV=ImlM-H}AR%4JA={QjN40%;7S z{26I9kj6nOoRP)?X#%9;87Ut~=Rle~BaQdxv#9|S^Oi-NHu3f-k?dZ_g`VaSjZxBb zsR1MA^mg~0o)@U-dm1ySN4lDRPurzAQC!w~-k!sjNl~-Oily0s3i;H~?A*?D`0Z{- zGp(HNbh4s8s9I*&QZHA28o*a$TuMz|3*B8`|4ZSehAmiI;3?)JQzr+IWx z6A3)^J<}x=PE8o?GU`&>!}C*OnC&)YFeEOjyF?>B+k8Not62ojPj$~>M28daP-5D- zV6{U$%ORfVFbtq%Wiw{ag3gY{iLei?`hWLOI%eAM@N;d?W&~aYXw>M z6H=`(?XJnCHFf1qUHXYT!Yy8H6_%UZE*z#=)&TO|Zc+2JX4%m-t68U=ZnJB4Z+IHp zrQVJ9J+Iwo58F-4+-Y|Ez_s0+Sm7rAx|{3v8M;sa0(9K>03LBK!{M0lg6A?z!}ZZ( zdME?z%WPq)dd?2`!}uJn0Q|Qdj94RX@D0I;Hxe{TV}m%yHAE^>9(yz%jOY47HsPnr zn!VctA6YdmkFvqtH?$1$eq5<2YGHlDkL1f`KR%h{M?l0oIY54E?#}|;JJ8x zzc5}Omp*6Iw+XJ~7ISt?dv_dOr8hO!NqBW(I(;pq81jE=4hX3WsZSK8x>TskO34>i zE89v@mFqsQRO;%cG)o}C6%p{AarJZtynJC1nM>`jj#)vq|If;%rtg_H9kZgmH7fx< zq%&S*Hs8DqHX^kVY`8X*%Qz z(snG%c?jMZBy-5@4@{@$632#ugL!|3xx)yYL!Wwka4G;49-;p|=K7&*c(A<8sMlk* zy9{-M5=fosu(0!)bLdbkb{%Fy#W3w)b4;;0wgk%rj+hPk5#4fK+>9`cXg>p4S_Lij zbn@W(>uls+SNjU4yO@fG9OUW6bl|W`R=hAq1Vt+4>+)^M7q*qMydjnE`23_5wkkEq zPVj9`w=~!7P$&}y%fZsK;qw{F5Waxdy$NtyDWFKKO~VHg4+he&u|=#S>7xk8r-R-& zs&IvK{xfC&=wtYDx&L4R34A79m|DCr=Dk1o`Er*zt?Q>`laqo01)5qecn=F!X|-zL zLKa==dlYwasfS69vQ~@0MdH-o(Ab^>cNz4pybU!LUC*L!a2c{mp`z5Ql`?_LhVIy| zX~5OO0Ee}x2i`ilJp2RyefT%RUkHC9`~je36BpVu0clQJg^E-3#WFPN3Y3x!pRe87 zT&a}(SWzxP5{yswo;Bl_urfo)!|Q$sfM$$A8A)>KcOVM_tdHgw!HmfTi2PJ~zcjWS zPExYMxaRTB&Rw_*jqeXZX(I4BNF;%i1Y6AP{YvUxyp-&EOA9K(gU*kgy2e(kZaGW{YPlnP@Kp&dpYjdH@6aIG&n&80y E0zAjs<^TWy literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/escprober.cpython-312.pyc b/lib/chardet/__pycache__/escprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0037e843731d5a9406b7eddf1fcf623755d9a53 GIT binary patch literal 4244 zcmbtX&2JmW6`v)S)KXl1SfVY-vc#1f(PA8_fgHt(o5WTu*=B4}j;UN&)eDL{lqmDd zv#TZ~WWXo{LvyPL=#dZEkp$Y`;L?& z?Tk8k-Rj=Ixz(K;>@Q&QR!^`z^g^=WU^o0g-pKpf;O(OgSJb5r4gvtmEm zkgp3$Ukfk_3Rc7ExfqL3<08w>PzHjQ(^)No{OrH33Xy}Z2W@N5{gU?y*e~>I=ox$bx_wYlMjWcH$s9Qt9e|HZ@ZSlpXwDTQ*%jO**2jp=u}r?N^d-?QALl>(KPK< zV!0g4!qq8>EK@XU(6|9trO*s$K}UauTl-*+GCGr2XiQJ0@(QEz>})1kh|Q#^LiKno zM-^DE&m|LvqSLDjupIYd6jW15swvrwVr03gq((DFGLct|IjX~Id!s=<8+UBEMhr5% z$&H_b^q0bIV$>#$n%*M$*h|Qw@H^oFh6xmb%#uZ-+HU~;d8sn9wKjNgqhwy*DzEel zV2fRZmG0eh^8kjO#n@*{j263R`(w8Pdh);9^S#jCi%)jIUc1@yllA`~PuguO_KED4 zpX|k+9JJSNw*QAGhiogh2X>3}0&ib?AwFuhwfU&_QhZcBjai$G;#4l z=uBvQ%yI+%XhvfqYT*qs52{Mr|qhMQ&XBRSt zwNI_!mTGDo2vVnp)v_r%FVaJH^ODPrzrQ7dSCm)Pu6-z zOY%EA<)z`XYrW@6a%h{8;bQmjs(1LmQ$AMgKDO#T_WjEK!^>hxI%M|rVcTu?2C(&; z2M&VwUQ?29)!(T9Sl)nhl6aN0u+Pbk6W&7@yqNGd19NXEkCC4ONUjNsf-c;2YtX6~ zW4tU1^Y-`K7D2md@n*M342(5i_O@>W4!~BUG!CdbdmSIuNP)v=D(GPdMh+L&i9N(0 zpn!+85ptv^z_L+!w<41%6a$@RT|(RQSm(xr${q6HC)V*RCUO zogT-vjZj@DUpBRtoBE1PeGjF+AM6-=32X%g{s1h1#gYt2yr zki{KpZBOuhFFofK2w?DU#;B!8^B8733UELT=U}P!N!?V7I|SHIAQ7_d9JSPDQxnet zJN|mhj(a3A+jex$BT?)qHk*Maew%rLTSk=aD4T>C)t-3fbYqTJG@VlsYlakTM{v;Gb%DXet6S zOFA?8et1j`Ouba0eYD z0Dl*%q$4IM)e8G}!3D(;P}Tnm6@X-4$5Ybe2`rDAT|IX%-?{vhG&TfQJYTda_dMnP zk=6bY(|5@9_m}<0ivDB2A6@gmz9O5g{?FblA093q9$sx7Hjlir5-Ry#GJWl3U;nDF z|K4cPH}J^UZ?<)o+m067j^4Yv*7oY-z)(5xMltZluf$Khz|nULcM7HUpt-;2v*~i* zNU?8ZZU4yQ-obM3@nY}sm9bx(HwRuX4@?#ZCf5euTNx|)UN#4hmj_Q32T$SXsM+bi zd*aTClCSSc7dXA{gmbL-l4jqn!i~a1se>cFLVz-6bV$FD(bcPJI;$;0kOwp|_5`b$3;Eq$WG^)GfN& z|0TD$4pt6^w!^_jtD*Y+sHA2L8O>^`{_|mE*kL8&go|bt(mKy#83t=LgsC2f1Q(&t zvsRv~@*I^rf1gx#L}vd^db4tSZ!j*SS$7J8@O*>_!M~89zmd0!CD literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/escsm.cpython-312.pyc b/lib/chardet/__pycache__/escsm.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1f07b6e7682f1b84e48ede37a197ca8350c2a25 GIT binary patch literal 15014 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 w!+^u?Dz!kjZ=@*dUpLc4@6 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/euckrprober.cpython-312.pyc b/lib/chardet/__pycache__/euckrprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b149deccc1e2fc9c306a341e7a79a8229fd2979a GIT binary patch literal 1345 zcmah}&1>976n~?Yw6e2nCniqpoQ&H*L~s&Hprr{Wi5&v$TWSEYH%q8QV$Ss}nHb5rozb zgf=7lwel^`$?LB34?)W%#igZgETadxWOM62Ut#h)-dSZFBV%)&FiO`}q%YZ$AFM|y zL+|9nCvyvr=OZC`wAz(XC%vEgaV{c(!4Vy#D@%0g+xdr!LBDvt8GWNSi^_BCg@H#x z@Qht(laTB<@4gPw(UZNRp7;TiGjE8v>NIi0DjHBhZoOEsy!-Y+PAC3_&N z2*|1g*n(H*;4~2dS+5RBr_%QOuWkXYh5)j88tp3>J-xdHKVGQfANQ&q0y*Nn><$%{ z=w^&_m8ozjjnYU`%1tymjvtDlKm$)j!d2#CJRCrq`U>t%#tVxx!K7;xreJZq7@{;!(?`kp0OD~qxj>GL%vXWARGo%5&d zRvfLivRtlr(pG?s2${Uey1@p|G%s#sIY;PV^Wwk&Zd6Tth7oZK#edsy=rmt${C4{f z$31YaA5LEXefizwon7 z3mwkqAKVkh>~wXVO$&SFw|XVjg`N~m0}qeiYuq_h~OH0gxhSm_N)f9m>i z8PO0I4nmGZkvYGlu3te>H2YHySR7O85`G@Nx|(|$2F)rhrd2@CVh2tP(;7c+fIafB zL9B^h4YgyX9ouJoC(5Vm)K4g~jwY*p_(}qBHI!nkq^MB;hNS#AXaX1KHD?C+T2k1? zR|N7|@w+ThL#YtaWq)w)mPpL<&(WvGDyC2z*9al+zXEdm2);OiFOOjQ#BP#_w`14d J1Ma%k{{h(~JY@g? literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/euctwfreq.cpython-312.pyc b/lib/chardet/__pycache__/euctwfreq.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a0c174c8dfd4840802c0e7db5df03866055a5ef GIT binary patch literal 27193 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/euctwprober.cpython-312.pyc b/lib/chardet/__pycache__/euctwprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1dfcb7951393ec119d00b790ba089ab465356abd GIT binary patch literal 1345 zcmah}&uiR96n>+Xw6e2nCniqpo?O#FMB+4rKtfVXQacoi?F8&JAQlE$nzhwPT4iPy zN5%&q3~?c$y%hIf2=0H$TWSEYH%q8QV$Ss}nHb8wjl( z2yI68Yvo&>lh#SVmvxlFhCAe3{87ytB$UM#knkVU(^dOJA}@KUj}a zhTh3XPv=&i%|}A=XtgV&PWmwQ<6J}ngCjafmlx^c<@4gPw(UZNRp7;U)3v%ix;DIi0DjHBhZoOEsy!-cKlgCVL>O z2*|1g*n&6b;4~2dS+5RBr_%QOuWkXYh5)j88tp3>J-xdH-(RTW|Ls*f1aicC$sH;z z(ajj=DpTQ58l{n>l$&UB96uC8fd-z6gsaTOcsPJI^%dNkj29MXf=SmXOu^!IF+^z) z`$AAERG(AZpT3*B*Lo@#7p(;!#ltL{_od%j=mdV;T471n%A#yW`h1Panf7zp&iO{W z6-TSBESKw@v=tyDLMFdt-9T<+nin^+oFjCwd2wI>H>xJ4F(PiF_-7jqo#yN3zuf-A zao;)D4kxeux^yskf7g6Ha(HF-;L3wt^PMyOr_=ax_=n*)jUL{CGjmi9Jx7Jh9^}L| zmNsonI}?{#(OvJxtn>!^{d5-BZ)DNQN9C^F}l)b-C$6wUsW0~W`Wx`dxcude2ShC#DRi_cX+&teBo4AUAvZh$@V z!64Q|uZG&O(vIyjz7yrsb?PS+Sx1xAK71tsxEe|^R#H@`e?wCK8#IB7^O`dQd@U(# z<0}IBtoU7)sG(Gd=(0aKUzJGA@-NV*#ww;z9M=dTAMXOWeFV3T;LZ_DpO{TD@%z}- JkASUQle=AO920X<^8bIu``_VC>TsAF z(

LOqY1A<8_JOI{vT(1rv5ZbkJYdE5)vVGA5>g5IZ?>2sh$~@Ij&wUU(ve=BYwB ztD9NcM7k1ga>@|K2mRRJfv?3)m>rTLgoQ~%C?6)Gb3s1#vDvf1QtUdjyAp)Z8tzNA z(?|y-31Lq15XKAtpnnPdFx~jV0;FBd_6tkJ?ss|({#u|H5*vre2xG{#3b6?-7 zszySPCV@VBz}kJdV_Y@i;6LG}w1$cF(r!%7Nf<(6RQKp+0=b?xgxy>%0`8(#z*@sV z5>xxisj%+T?%*%t$uw%fbq$T^D>i1w?W@t$#C1X&@r^Xr)RzAdTH|ycOMItR!cDV1 z?NI~41a>o{f7V1}wRnLqdXLatqzQxzajwECdS2s*1^ZzB#aM4+=hY4Yza`8J-Doaw zc4=4L+HmVUj|Gf>=QNIkb{zCd6T)-SGr-RvsEObQ-BsKl=KgP?omDSrOqH&5_a}pw z=%k5CuA~EvS2gl5SpxkJSpL-5Z8qmqA+(TQvrGxK)5Pbq*4=DxhJIl@p*^0Uy8xsX zjnkM*x|{>T0NuN&a!MPU{SvOe#?J_@x%*8dGwKf0$R4akUogIxzwg*+pu3NaUNqh_ zTN?O7UQ%(e*+%CGy)RAgBBp^<7CIRFR45Z5(YNULn{5cUn1iy?QZzop(pN2q+N;!R zahi|&PHH{iio25cE!cp`hUhb@T_%~#*vn4e+2cIYts#wqVodC|uu*i^>6_4v@;M!X zYl0=4Q(1eoGuFfUKMAWjs7vx)X=5h80eL{}go%L~pJ4exJ;;CSTMSdC7E=h*<)6i3YVAh zGQvk3Y;_x%g}>l>yOPgI_Mny-K}KpPKq`e=^e^TtK{v|j)WX=JFcIyRZa_MRmrt=2 z!tw&O_c+~*?=Q71;S@bIkwonxmK(x8;Mb|`)5wLYmD(z`>FD28+saiFq}}noWw#3m zb_&}-{@`Gsu`Q_9xPv1m2AF-_#5|3&NQcwdrSYcOQdZ5(-;X9vX?%qsHQYPK+DbbU zA5JozQ$mtuUE;Uiwe}i`yj&C1s*zj{lF$3nQKPonNPN9HO-60Lu@^~x0X&tzI>3!V z&H(@9BR<-x99#$D_skCAemb=yy3G;H=k!a)_kzqaJKxwf%-c1ll1!{NOKn^ji_TmB z73qM$7cG;<2l<{xccjaLp=hK=HP*&xyldiT4jKw|SljJq=s3D%)Mm0)0M%_{#hhy6 ztEZ97)h!LRD8|x>5j=z|54QuZjxav1p*GT%cY=-UOVXms3e# z_M=cr7#Kn{M)ydt5&i1ak6LmB`#^3J8e!FpYOxGe@l-gKx1fL7*;~tdDIe{f9g537~6!wZ3Y*(Wj+0g`phAenDDM zt*Y>h*XM??P@|*Uy>6q3s|Fz>LVA?i>q5z3BdVu%%|uhod90N~S{~ILq=SW@t@Y69PmN<-jSt{x zA%Z))nUQX?)*fjZx-(I|ZT-B$XtO7=bO^?yIc6^yJ8Eo`Q+{Kw8OspIBHVBhU%9oB zLRzm%ezVEhm<`ewX(8Q(2-chU-3P2@oGV{ddF{3!oT7qeM{9fllEUmp{$_iOb=C3# z|K^mGh6my?{X6nX@wQB~dces|nVw-Q6C@O6)aNYAjFpS6it-qiTgozC#F ze=JQ){4-#xhDDg|X-s+-!G$5UzxMm+BV8 z*HN09q5TY8yatci(saN}KFt+-W*4|h6h)l0zRfLjWUQ0+&WR`(v<8)m=Nn5Wi9 z?N#XmlFuPHjntQRY!Q-qq>qiQN7a<8gT_XgNa@rcWT1(*-iWPCR(B<-jU~o13G-!P zqBPdTQ)Zt;`h|2p8=26Tfa|M!0yq-V`1TpB@iJU3;*UxGO{198$bgFmyZhqSpUB1= zCcZ_Q2Fqq?8_Y*_cNx1y{56e3AP?2nOFJ9;P{=@XE2oo2 z7dDTou~AMf0q`EDo(N{Tp%VNpG1ePFMfAU7PQ_YVr)k#O1UxzjMceV!=cRzLY2LL1 z9MluKkbF8oqSxT6gKQOkLcdSQEB%>`%bv_};dg1_AQXk~j_{=lcN}g42k%oGFYOtw zBq{<@l<`|`s85_YmUz;wVTI@pNIxs2#{4|+6T0_-Pui#pzRE75qotF>H4sWzwZ63~ zvr!WGQ)5Gf6~KdyHSr!K11X07D||V1kLZqe`i6ta+}{UT<)O^5Q88nOY5Ya4J>A^s zkGg|K+&{q52(DIOjwY$yQ|pEF6?~0M^ds~&$WI_e(5DL_`a~K-{B!iVP%U-`cWqQh zdPw)At6SmS7=d&k(%0dNV(#H9d@++LG@7H&;gl$Vqu?ieMcTYR$&S(u#_pS_98S@6 zwWa9y(YHz^mAh|TpaZXEryg zt!h(1PLnL}vX`;ZOs%OfFWgHsgui#Bt>NxE6{k@HRrk0+ZIkZ(a4%74h6m-w>pLCc z@1~cbKl;sXW48sHna#w;BGw+*?S#f9R2w~%%D~^i)sfcMeV%wDHU^lupu1Tp2$I>8 zsX(%(Fw?4Kgu2o$n5!VzYr;P-j4jAP4OI05E_#{gRVJ1RGYMS>>4Sa&`s*5(oel`U zVBU+lvx`_`qN!EaaGwi!F35W67U5CQjSdqk0Jq)5DFkgpH>#sC9qv#5?$EuAr7O>G zahhKGCdjNH8O<}XQ{y0(4o-goC*bdtyPw8EVtZ_GiLbcvZE)3S6fo9Uqp+~V9;3Kw zL_EK=zO)VS11$H|vI#2)jYW_iUu(EuohJBb3}P}r$OKd^oR$&)*$O+nb$iqrx{`1i z;k(4IM|1J*qV@%i)kqrvA2s_M`VVaMwe*&Ba#%I`5y2s8EP~&NcaL)b{HbtKnwXcH zAjtwj^idd#8k;Td!UpNa!rk|H`b*adeKBWce1>cKQ#!^(8@2iDe(W^K>{@9q#(RVi z-KVjiMjwy@X7ia%#zr-}J#DP2+bHN%hU7G-1wk!(!)zA&u1D~|L`E8SP@Mv)2=Xt< z8`j!Da=ls#6H@|Tv`;#M`-XIXMW2ymeAiwBeW}0~Wj9+FIJej5Lu#GjmZJZPZc?Oq z!YR55SB8xRAVb}AR=c&OafilXjb4Ez`UCie?g<1xXsmQsqF<^oa1S`8SqT^mW}l8lQo@!Bu;+rEJ*-!Bi%%hFWwn2t~hBn`Nw%v9TcCJmkMMwqgDO z^CS=Na~DxX+80X>VQGLwLs6|YQPae~aE;(zA-L0J4%s3_~e(bL*D%F)hjN zP-AHs>K1p|!uPH&7k|$QBSIP-LiG-Uml4be1W|a;!{<%ySvEdFwS>tXYOCOKV!kBI zRXaiVK8+`&^-Oftz2jn63iF6JH=9S}3!kG2LPi=rER)386Vj$WYIB@E5}rZ-5tfBs z$JYGi#MfT!J=Q9_*gf9ej#!f5yJ^eRBufFWcb&bY1?l$WbOkTj)shqH>NHCugNZ6w z+PUIy)y5!r$(Gk>{HxZ(OISf;xKL1-pfS?y$6W2CmR2PDWh5qag(_LZnpRkm4>gNusn|Kk+^&lA)#k|nfl?Ul)tefx-NFk^8 zNGF6}rA$-$71_zC3J}-kc zo(r{TfOJ0xJ4ud5f79uL(+}=%2C8NtIZ;h=ddt=2qE?XcCxv0sSx65e&E$q+nCxln zLt`tPcEPpepbm|9oZc0>GoHXRichz`Z<=30KEpCm+Ml)Rx}Q6}sqwWi9erNm1N2LI zZXhgxTZd&D&w0GhznVBMY@%C(t7p6*Eu40!b>$_Ubfi5_J2kNbrVP0ZlYgjOPOQQ^`k5PRcSfZwC zrLml5t&VOcdsKIcXPkCn{*l^0#tyuf4J0PwkRCgzYx^ zlY@gMs_Cv4UeR6W^a;MRAUApb##*J~o)NW62zuK*9*qw67^)jFbPVZdY7c;OgG@2; zukOeAiib41z~sL)-V%OAP#<`WvBzvQvF|UsO@%3Hm6$AmuaDZ>LI-vacuz}#WMu6> zHlCK|)7>a!;owR1gD_WzTaBtX@lHZF{wjm4mVPC@Eh?u>z;GEh%~G2mud~s@3hfGEQvtsBc1A0SL0n1CwN{Z?PNB!eY=}@TK76v zubBAK>0P8x2@4s2+G#ZKrVP2y!AyS1es3NI5{AiSzE z9{7qoSRlOzQrFl|gxbd~EzM{1kAeSkN*cEj-R*G=kk)E>LmExv^gVoo@clup8C+Ir zdZcNDmOTG$>p3t&GKb`gwg%?w0PrR}Q3Y4u8fT=J+1MexYvK^9&Il5~r8K*o+F5t?kw#(Q z={|#X82Ul2Gvk?9`;YPIP9Nc$q5C56R<*h$i#ipCtB5L*T2`l3H0qn^DzvrROorYf zRL$5uV~>Ep11aR;JXZ8wX7ML9Gdm{Jad}{=Cx=;8%n_NWa!7!u?ojL5;a^S3@Ie;N7@^<-Epy zcE56J8$vWn_c`Fo)=G&gv2F_!Yk{}wzOPnHceC0u-9gmWu=|GYc(`8DN^$P-6$W|H zswF@gs4di8fNGA3Vj9grx`chBT@3A3>!5{@m)^Zx)0oQhPz3EXP6b@_rrB3$JWIT+v;y2|EG^*X(EY%(%tdz*p_OVs z@>kRcwzlWi+-|#smxa~dgYz00(Z`smZ1x#ms`-zh2H{Jh>l-CD1xT%MVNoYG#o{Z zu?iaHd?4~8-A(O%w|3vyVQDr_t2niHDh_u;cbwT>sK#i-;+vyZPwft&#i-r}9_&;I z%WAj#p@|b9Gl3(JJsO|GZL;bmmvh-hi*&1-c-jhkr7_ehn%yM*Q+N#|9+qS_zl1)& zC-WeTMJ-WnaxZ(Z{HA-r*b<(5p-N!(X%5 zwgt;=4`nR+`Ir+s4R^bXOtj&z8}Lf$6jaBonw6JtLmJ({Hc{`)<&PzL(|$c}()A*QceiL#WmS(&!nGTr>`H z`nSdeYP*F$j1^FOQM!%zUAW)k0-^G5GAn{#Y+2fsbPO*|v={SF(jst80!#F^+5)qy zjs1+i4_Ck0{2jQ7(%aH%ARB~_HOdO3qyq?5_bDqaz2PQb#hg*?B)bO@9CJ;t**Brt ztuD5v?iGz!H9B&z&<)j=_QSVdEg4*I?&|?pkv?_@KcPA+9j;s2=HEzj8LKVKj{7u* zT6C4GG9XEOj(VE?(Is|3I!F4Z+o%ds0ez#m`x6eT<+ke1uuL=o)kns@LKpB)N+CGPgEKEeqy&PCo_u zXdKB?CORXH^-ea`eV%wP52Xjl4Ui0|j`K1f_+@D$@7hr5e^wX{+}hGFAb1T`CJS!h zAQ{{Qr(3#pkWTUw=Tm8E%nf|#E-?Nhr)N>ELC}fXT#XFEGP)_)odx&E`ZGMsYSO)g z4&oc{TFj>@CTaBcsT1q=3IIg>ngWGCPtJPLp&PH<%jvCvp zyF_EMjVi*W)cu;!EaIi$5(Nj*4A*o$5JZKYma)4}=mz|@NBhWZTJC%E+?<1#G-^8) z1n??R#%^z#{gSJ?POH=|djNk3uUVm_@IJmf{G|sTiXgsINwsgy zb~l?7eQDtnkl%G@S#=e@?F_vIH$rVVf~hv&?X+C&b85Rl9;$ukt~TO}FT76ZSEouK zsnDMYYem~!)9WVcYOKMs&+J7L+cB@yEf;Pr8Xv&XIukXB_YBseHqx)nmNQn)L=Nvz zP9bv$(O8gF_&Nv+U1vpJI$5=uN0H4#IUKf(HUlq2f6Duk0rM8?7dN(3Z8rChq%~-K zs&)=@7mekZ|IxjtRw8T^%|iN{-L{hK8$JtBWwqnz?@>EowmC=!kf~wm=nTky;!Ofo zbV^#y16`^%nQlGdd1}3c9r$jbIzrs{YwQja?YU~>CcC0fr#3{mBK;mXp=I8YHbAh= zL{Sq1T~0^Li8S^KtGyQ28DDJTBiFtH!BSL@LAp!7G`5||{J_iLmS9d~g{Rd%uxfL= zqf;QW&Q;C8$MH&Ax;xrP*4>>LZwBcAR}{nH|DGKj7Q;cneDo zV-4U2hK-`xy7N4b6uR4-n&7+WRL9Z{N#=!1>7HA`#j{`nrycmpk~|}H)VNQ4i`n$S zU-ZcA4DRz|jy2W;WG%=jUK;W@41Fby!NU8(1N7D5{$Xg2+4mT_hxAt+$Vse z->{?uc|zF9%L=uNaK}vaM}O9ZWtB#8u3YB}Aj5^PK}Kq{LOLaG8Q@2{gLvs`qAh>f z)NZ-DO>j?{-Dx%>lZ|wLr}iv@?<|wRDJCvuavApzU3LZOERZU?e@U|uI->i#(_P{P zXsi(W(1;g8RGN6>AQZjt^aS0$UeP7!7c$gO+RvBZTHVFm_i@S~3=3*e7PDiJmJ?!v zm*}Y43(}p$=W+D{f1Nq4#?^8D_UYzBI)r3Ojhi5O=;ma%JX}5m8-yz$1--EyICz7` zo6_tE&H}H~sHM>fOAWgB%vR8CqR|gaO;^0mmiyWG-q<4IAJDCdZ=~7hb?>Xq1WAOn zlu#N=UgC!XeN@5Hn-O%j(F|(+={{$+4c%&}*60=&$`k)kZ5J<_seMWJ9HG&u-ouhZ zcm}Qq$;EIFgzwq74p$KU7@w_=q*pP2M*MF=g*cdnG!25MbyKP3^$ju&eNtmrfak#_ z5jMgVrF#ivIcw$VrU3qqrp7}; zV_fGC#D7Hkhtu=6j5X1kS`DF{cd`n|L!Q&B^(I+{E<`~g>*s?kAl7MEw8bg(-^=1?Xz@h8>K;-Kv-m>>U3kJy%1z^`bA@-(~qvR zh*M$rd<(d%T3M&V0T<1r_Nx`n1xS=b`U~BeYJHtX0ry8*R@yUeUxt>sjWvF)EwA>2 zt9uZ@(a%`kluihZD3TU8+nD$Xx>wX@gIqD2n#rHtP@}jfLvn7M=b#b&3EaYLGFxUd zaT)jpxCfZ0>wYV(i|V{|utr1RZ(UtMAv@Bdx|c(UR$(sWveRi)37?thlG;F2Z7p4p zF7QQ_ zh-c-m0-={}SsgB~?i$@=CcYtgoQ&*W2LFA@HT=2(wssOkkMwBq8es4uUB*| z@twA8&(IDR@foUwSPpoCci@un+!Le$s!ebogVX|k7V~;k3F+<#8qr_Cf2y5=yCr16 zSIW}Qvyn1bi)z6YWO5p+?7Elnt@Qx1a5{(D`*f3InE;#`E}8CE(!xR=PREnn%*IiC z3Cy;VRsm_l!LGpKzgY?IJsXX&yoUZf++qYRHR73gQDYIcrNVQ-FKB$nWGiWMZ|4r( zr_82jvYbW{>B|~p)qX+0(P^XEFG1#oTJ#|=owzekw1?9uHj-;pGBE@}YGXT1TmtEcuYlTIr|h8- zm0~_@H5LE9AF_$>Ok#z#O!NFvw zcLG)PO|TKY$V(o&%dFoJOI?t6vHVV`h4eg=84$c7-EQe8seKSa6pN*vMq%L#VHRtp zkq%^IgxVFCogQgz>8Bd~ZB#~@PU8b(FG_!)aoo~1q~(Fv3eVF`;bLE)o0jJ?gsxgT zDR3;IwV2x=jjuK~tl(dg1xZ)@p0RYopCGFPb2L!*i-3t5I-Ni|#%w#c@!08gVImu= z{Sc|gUwVf8<`7%R4P~J_LgQJ6w%Fq>1cj)Tb4uts|F&v;8czuEJgBcQe1ue*Zo6}2mBRXy&FCNfKtU~c1d&gl-) zW|nD*FO%8Px)*i-LI1YeNzCstxeMPo^et_Ep6B5jr?Ip%n+nx(=_Ul93+>@XnXRQU zAUu?4sombv0UR|m(HDJVPG@^E zRgq=~&S8b$LL(Xk_p_y2VIIY9H>ca)l7Fm~5Wx&4_v>y{I~(^7v34B6RRn#}*FoRT zr(%mnbKu?7hJqXx2C6;c{#zH;K9ELPfjhx%rq(EYNyIi5ng~sWW+5~znBY{dT2)Jy zDp9h1^OqafsaB}$u$2@FNtwNg?gSrkJ)TVyN5UTX=U%lhtj&17q z>)f$-o912n^l#HYwttbq9S3&rI=D!;UW2<08#ts}o8GaV+VmebxJSRfZ94bpIIv6C z!Nt0F;;-Alt^-tF)o{pT%kBqrCn Yr!pRiNpm}4?*!T6AC1X0(4T7l4{g4P5C8xG literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/gb2312prober.cpython-312.pyc b/lib/chardet/__pycache__/gb2312prober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..23607495c7240276c2269f9e66ccbb69f9eab7a1 GIT binary patch literal 1358 zcmah}&1)M+6o0eYmDa8lr!G#SoSZMn=BusSLntAMV~0SolYmMy3}AVbt%f$Uw5?ptBnF z8G29Nxi$CImvf7ekUVM+Wi;r|_k%bSk-+Fw9;GYGbot)m?WImpzS*q87+pu@0d~W{ zCn5OO7IaBSHeJ8M?9keTo#LSHpj{cWt6T6Z@oOvK*{YtW%FFHOZpx+m)W6XmDE=hd zAj=5IvIba(N1wo9CIYfn9+GaU?G&%B11;wOvT+zK6pS9;U56h(E#vR@vL6B&LVnkq zP>vX;jB}kyxs*ozNK(peG&wQ=)I`T%PesCYW;GLz;Y|Y#_!{HN;Y={;S;`hH?y3n& zJ8>Wcr9$^PyYcpig>PEl3&urjDL^rwri+0LT1$gY5VyW#N!m)I^s)?ikIBp3pJX@V zzjRx1)NZAjTpjdV9VA7_7I_1`Cdn|xFs;T?EylGEItA(#=dYm%{!k?Ohr&=<9X0G3V{T67 zD!w9+*_!Eji3U(T1XK1~_gap`b$%9o8e=hwV!uKNd3_bg*LyIx2Uqvt%z@n?&3`}h KUIXr?*8c%Q^*nF@ literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/hebrewprober.cpython-312.pyc b/lib/chardet/__pycache__/hebrewprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99a481cd9a12251c1147e952df1d5eecdf577ed1 GIT binary patch literal 5023 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 G1pfm7u9(IE literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc b/lib/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4948235d3a160b4a5a535bbeaeb3c7024fe242f2 GIT binary patch literal 83102 zcmeI531D4Swf>W~Nz;)|w55~|N#}V2%A9nb=ecRqv^#CnrcIir^Q3}Mcs@l@K}19Z z1VltcL_`$D5r2#?uy*poXQ;6jQ_dj zx8%AOE(e+?nlIW?v_Q0#Xlv0nqHRUniMAI#Pqc$*N6}8AovAoZ7oqb-yNY%b?JjzO zXb;f~MSF@~B-%@~w`d>HzM{=V3*`!msQ2J*70qN_&N*}I@(POdn#H>0{$j-eq60+-iJEmeXQ=cH6CEx( zLUg3)DACcPV?@V_nswEp4b`lh7g(3ql_yu7FWS-#Mo)pXTS>dMXdCHiEA4jDZZCSC zXb0)+-eC zldbbb&3AeJW?i;3S(n?IbvY+)U7Vv>mm}u8Jnz%9F8AF_tk_%5tBvDgsp>%YB>gvK^1RoNw0UkxvUG@)?ev7-@??~yfxXYeQzN^+%i<%#Y)-5=tb$NC1xXa^MR^xeDWZ=xW@3N

Em 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/langgreekmodel.cpython-312.pyc b/lib/chardet/__pycache__/langgreekmodel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2a227e62b9374f0b7ec49de9e8b9abf9814b1eb GIT binary patch literal 76967 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/langhebrewmodel.cpython-312.pyc b/lib/chardet/__pycache__/langhebrewmodel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b3697872f9d48dac3093486e760d61008563fb9 GIT binary patch literal 77478 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/langhungarianmodel.cpython-312.pyc b/lib/chardet/__pycache__/langhungarianmodel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5d5506eb9f2714743f01118b140f4ee365e4993 GIT binary patch literal 83062 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Ï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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/langthaimodel.cpython-312.pyc b/lib/chardet/__pycache__/langthaimodel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33721d971deb26692e2cd31ec28a08b92fae737b GIT binary patch literal 77656 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 yMLkD1^?BjuJI>v`?%W*Y$nc literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/langturkishmodel.cpython-312.pyc b/lib/chardet/__pycache__/langturkishmodel.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f8cbed66193ffa9d6b51967e791106899333446 GIT binary patch literal 77498 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/latin1prober.cpython-312.pyc b/lib/chardet/__pycache__/latin1prober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54bb80f0bd6b8a2dbe68a1133760af2b8cab6cf6 GIT binary patch literal 6805 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 TM82x;RqF4ZekoAMKe+z|GX)`_ literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/mbcharsetprober.cpython-312.pyc b/lib/chardet/__pycache__/mbcharsetprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc4664ee41a2922cf028680255fc359fcecb881a GIT binary patch literal 3727 zcmb6cT})fo`5gOR=YkD3#ZC)OiOmX&QGqejDy4*t#WX=8W&d>$%rk zu^b6aNF`IMq+P2}snYVWha&cn?4_MFY3z9~TtK_tRi#B*U-CvrQdND~zH|H&`vTea z3C=y|eCPYl_jkVU^IzNAS`h%xy|=W`hR{Fhq6U0*a`ZY(?jZ?DIE^wmiZPvA(w2-h zYRzy_4kHV?f+XuYk~kS}TPt)?ew7c{9%EPqu+esTIZozf^`|7aD3gH2aL`#Qo19nU zs%$u}#S_b^tjt!4>c#9+<%W);uzU~XkWmy%C~A>#)G7%ZXbDS}^_D2dX4Z8f%F8y1 zTSwbfF3~fv<{Q?6WLrnk7U>L(tsCfF9JSA*K#OtqS|P2bezK~{O|lk!tv-O0kqniv zGzd)PrT<4U7(T}LkXlEo^>Zckz8#?w{ypBN_5q+aEg`X{ZDqw(a0sj|S&|mO*L;Fj zQNS7oyV}$7Y*JiGrB#_crpE&|gI5Z9nUFKEG6YdfWmBps8XhU7s3f&mP*b_A7|+Jj zt3{a@Es2~2ZV;7>(JH3niYg|+Qvs{NDRO#=v`{83qL=`bB8mzX(C1tGE_!(^wxGyF ziOs}en9S!xaWx*B$tB|HSVYd`WBF8mP>qwMtPU>SP?uK8FPCEJ)M6~ZsxIfUF?x$6 ztHYT^I#Xmd&mvF^L;p^`~Ze;*U*x)Z(?)*U|0 z;X82j!nSVj+q3rpLU;6Qj(*+os^)n0z%kU|F474so7_cR$J|9lZ+u_B!dp1Jg^kW| zPMyx=({e`6sHRp&N!qQ3U#m3-P3UYS`Bfyg|v&(Sg~eo>5?jzISGqKfnlfsfV~qcNvuG z`KFe4Lg+5O4oq)Cc3G+Co7#DVRw!2!lyJ$?1$#9fH?1YBS`X9}R#BQsZd?F?r{MJ$?&xnFGH zNiA;z6VH#Ec=nhM!;KR{n9Q6aElpDx)$D=T?mK7 z>4?G4M<(YYMkiEsF;O4{k}K;K=*9F6vnpb6OR_9M3&PsEme5pW>T+Z{e8q4kbE+t3 zbA{xxC_$@Wv@<@r>{3dSvkBRFVgBmuT;%dXM2uXWn}WqmD8RF%Z3t9(kc${N1!=q5 zu&^5hnx91wL7}SBMy-ELjTZl_9JEU;%{#5ck~^hj+Tjy z$+GwSZzn#P(7mIYcl5#AU&J5&eBV2{F;jMWKP~C!N3`=Jd(M%v%YD!Ofn9g`HJ5+4 zcdFdmulEME-r$4C=hq)z-l>7^^2eFbo_B)XJqG{zr40PI$a(e|Hg_v z6Ni3K{;(hQ^xt3nB(}lbao%!nVom6N1SNdz*4U@#^sZs8Yk1E-465s{0nIg_yT&xv z*nw-j?CH`y7c|d>eb2yW5q&VE4TknSp(gbnIXmwZZxwfiuH&VX1~sc+mERliPGG|f zEA?9T3{!ib^N5vL=wVntGXf{fm6p)WV&5rY(HxQV2Zusy_8KZXJ9TG3a|U$hMa_9} z-#NA`j4=%=H#%saP1^|Qvs* zZFr6}a+#b)Tea^_$mz5w25_YtsDq3!tIzieK<`}Qt#RwB*5(ucs3QhHgR*dn}afAc^K!Z literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc b/lib/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12a258219aa65a3ab7548778abb968cfabd49ffb GIT binary patch literal 1394 zcmZWo&u`pB6n?Y2&U(EzAt_12Ekaerg3^i>q!v{Ove1Z~w1r+`O{s%5a;$&@3a6#e_6e_BocyH`=qGV*f`QA4_{NDH8{OULs z;4mtWy5lOqALLAik%QxJ5j=$e0wy40E@OmCq7;?gvc_dmi451!xFV*as$13A5N1?! zYZ^}pE2_J7jjO_r9M{p<6t6_n?zF}=@oF^V&M+v!3Ix_J1oe;|l(RV8*^%9F{$l7g zSUTIh=gC&6R^(t9uggIvl*n3}8@F$qc&$61whFKQ$!7D;dg0nD%h#^IbFJ`c`Li!h z+~)etcW)N1wcPK$S9r8{dOhSdySCUY4 zC1se_IQNB@B%CLt_u}Himu~a@_GS{wq`m5)`6!M*_LSFN9r&JTZ-i0Yj{EVF@?38$?pZ5Iz>NqnO_wSDFh5fa$t&ui*717a5ZNb{BJhqQs zgPQZb^_}&^KE_M&>8v#j5^&p#Le5i*^JowZ1!0@>uZEt;R&a&Wm06uVfo@{{R|!ak6QxaUq>0RZ#v@f=E(4wT7yDBU4D1G_{hg zev%VZ-n1SL{jFR?UF+2Db?5=-o2c@7(|wsU)COtYkMSAj4E026b?_zU1oekLq#oo9 zHH%K?C&)slBww1hGL1fvm(iu{ldEWs%8aq+w}4$ggg5ke=@2d-0$Ti#x%BUp!{(mN Lzxf<+)))Q{q8UiJ literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/mbcssm.cpython-312.pyc b/lib/chardet/__pycache__/mbcssm.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fdadbed704bad5a608fcd768dfefe44cdd089ffa GIT binary patch literal 34682 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 H2WI~djTQ+# literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/sbcharsetprober.cpython-312.pyc b/lib/chardet/__pycache__/sbcharsetprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5727cb926f238c46284f254fe2bb02ca6fd802e9 GIT binary patch literal 5391 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc b/lib/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a1b1e57e02da916fa8431172fd735fb6f42e04e2 GIT binary patch literal 2322 zcmaJ>%}*Og6rb@IYqN`i@L>>bO-l=o1cao3`AqmKSQtoc5bDa+$k=P+uxq=s>!wsj z$^j`GlWmG!v@_igHZh%(o0S%^ zh3Rg&Rq=^F2y9>;Bt5$zSu4SPyKzUcZJQ4W|3R_}K)rEhGmfK@Hji_K{9~NkkT9|G z3(^Lbo|1qTOFWGx!Kx(2fj4c)N% z%7?$_zqk?#qR0*Zwxy|=nXe+Da5yw`18T3h)4+9%=5aL?MML-Rq1A<{ka<<8UmZV! zR@Wknq3A*xYmH{IX<3@y)+DnAM!FLwmDpr67iS+5GmKrNG%;67(nd3TPGrH0u~p1TSj=*f$Xfv>MCFvh6_4 zZP_%|5OkG<#WKNmY`1#YDm?5(_(ZUxT+KyW(Y|lqg`9nLPMzhmZ@#DkBdutRTd>9| zSW^|Or3&V&g0)w{I;vo_x@_F?2EPe`Td8e3B(tj5A|BBt{B*|-*ug>xioY*kY7 zv3w@qtHp6z(t1-{T520VO~vHQMl8RrZRWDE1o=gilGd+oB-AwhN{yTM<+pJwIpurb zjn3?|GT2X0^=~5HJ_E;`@FMrK_J->{&+X7Xd0q#EuEVa$694d+|KzYM zSmH;RGG5{*m@-k~C$B?gpV1OOcHOxg=TV8DI`^>HLnVH=>~+Mq9r2w-T~ zyx>po0=Mv^=LgSA{*1g5kQx&9WaEm2knTa0ECreBJVM`)Y8ePinl6~7N=UMdPyphO zXtL-J@Cf^fWMpKbj{=lrZ+F3^t;^Yb3W&g+meX>eU2mi{A}p#X52pX2&KtBbD#jSC zH_GvBdZQqx<2Vz~GD2SwRIj6G8cWiafs{$CdnsasGa%L#_0)TWTyOyP5z7hq{M_{^Y(8k| Kxd3ElvHu4xBY{!s_ z_R79Yigl;bR;2Z$lB#rFEkV~HS{NA+28Me3`h6DNfqR&& zbw{2#+bELP1^Za?gY_T)AAxEl5~3mrS!T&N73obrWMz;AAe+RA)|=#Eeo4pcgJH3e!O0BUh<-5aQtCN4u_^(I{Wn&+luiY(AUU$xFDlW9qo zK|Z4Mf)GtcRY8z#FqCm8y)wegD<}yW<zphplDc5g zZHg2h*DD1f5)UhiASkFD?~U&-^&A_$q)4(d+8>6lJDu(gtKrf9R3sc94N8ghXgZoc zq=w}QNj)@vRUMy_e>OfEkB*I|r_?K{$|zID|bSn(b~ zaA%Hp+^M=%^|50emXkMo!B2tmwq5`hLamjxSi$;5LaEhc^a-C$hUh?;)#R-RZNbhB zU0$)W2N6h`b`@Q>otfhxPHTm(R0nO(_MrT!!xz`ZA3BYMjiRh*C-@(av z+8gABb8FVQM|1AUI{li{zs&nzml-A+GNW71lPT)64C?&Fa5|g>_go6WNKg(M-5|gRx!df$`oj6^+4u5D^OTLPacV8EW2l^V>`2=;gbF%veCB zC}&xV74ChJkf9k%0}M?bGuDi?7*S#@l@w7+#vPCQ_K|Dnr5$ zu;_7REn|6@mmFdonuoR6HWMm-A&wO!pm6f!whfXu7H66eliX9n6>V15HgZk=a|6%j zvdJ(+o(jGF`%N_7^7;z%CeGM07SY0F8qZLXSpm4b2?BDzfQf{ z3wN>p?L8W}yx~MxoeWO5v?*Tr841vPC8~NMC#Pg@SoMxU%?7lWD1eNP^OAKKieCO3 zny(SEG=w`zx5lNUjF(-nNuD_jWb+(@u{IH+%hWG+M|Wm!tX7xDmXtXBz8 z85lz&L)gY8NtCh3fg%M((JOoVf_*)~3xnr$=R`^sq-1Jx;))z6Ytb#3dUzVg&;cdlvIuTOn)D%;elHFZAvU@`po zCo4_ev;8?|)2Es2F2A{-S_D)-p%>^k6IR*=6dIc?hZZZ*4%q@?(JE(PjmaS?sm=H{<-?Q z4;MaMytdT!B(pfP+%b^rI12LA|L_IQ!x>q3KywEk^?ot*cxdT^zq$t*rG&%vMY`Di zgj?dZuJd2kefj>M>T}1=er=@}X%Af^^qpRs>l;9xL$sXf`Nj8_>YiL$@-JQc|5iy2I*$fc~s{@WT$@yUQm-%J2zO=UCczoWp?xG>g4_`1(( zxI1__duj>r9oHTC`kjpw+_T{0xO}>y#K$*YsUHJb!8tcb&eN3j9Mn7qv!3Ic=lF`} zXI4CCXC14~EpsOx>{xNOFZ1oJP=Xf+yfU!n69l;OLLwzj#u0W1 z!nMh8+@P@fomH1iMDC$&6w86_Lqa=Dw{y`Cu;&DOnQ5kCuR>_?)?rk+r#cmH0 z&OrCwP4ddZarLiiE!^HUp4e-@wovZyx)q=`gx2hNTw?*(_%Hh|uJPNm)XH_RV=$J3 zzFOUx7|R!?M(mYQqxu#jsIaJ&Fy6%MNd+$?e6Ezdpo~YAJ(i9n)$7J9$_^|Qcy6)h z7bhhr6AFv3ED{?f|1Q|Xki!Ge_xuS%ji=;(7^1f-d!bviQcAz+BDC{4IsBZw`<(21 XPFns(4!yE>(T?T1ecurHGCuzSkr83J literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/universaldetector.cpython-312.pyc b/lib/chardet/__pycache__/universaldetector.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2384dfca88c99df6f8f92e0da23a555511832810 GIT binary patch literal 9997 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/__pycache__/version.cpython-312.pyc b/lib/chardet/__pycache__/version.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..409138a3f15668ae9730b77675f18ead3bf9a3d5 GIT binary patch literal 475 zcmYLGJx{|h5RGZ0BBR0t3(K+5fxy62A;jl^gh1kJs3Jvf;xvZDwrmFo6HNRB_zQ@U zpTUF}KwbF*K(|h~Z7OcKyQh27y?6IouVcrCTfL8eZT%X6aa78t=h^1LiJX=bp%$X( z+#OT?Yc%nUMyORODvj#R3qDDhhD=0xN`YQ8Z8Qj;7GMNumdTXG1t@A1qnC_#z$6qd zsnSev;Ca@j3PcQHLR3Tzj+MyZikXCQ(A4D8lLZhS!EjKrK<8~q!VA)&+QYa>a+3(v zgdM_RDDJD6kB;{a51yRfz;^#=yXl{5E8pKIHf>6|Lk#ivMMzTrgl5v0OfDIsI@B!17bY&$ zRqUs%?aRW7or#|uQ2cCb! P^N-u_818Cn(z5;ljxdjm literal 0 HcmV?d00001 diff --git a/lib/chardet/big5freq.py b/lib/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/lib/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/lib/chardet/big5prober.py b/lib/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/lib/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/lib/chardet/chardistribution.py b/lib/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/lib/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/lib/chardet/charsetgroupprober.py b/lib/chardet/charsetgroupprober.py new file mode 100644 index 0000000..5812cef --- /dev/null +++ b/lib/chardet/charsetgroupprober.py @@ -0,0 +1,107 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + self._state = ProbingState.FOUND_IT + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/lib/chardet/charsetprober.py b/lib/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/lib/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/lib/chardet/cli/__init__.py b/lib/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/lib/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/lib/chardet/cli/__pycache__/__init__.cpython-312.pyc b/lib/chardet/cli/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d1859edfbfe916210357d224acb60ba1321dbd5 GIT binary patch literal 184 zcmX@j%ge<81gtFWX^cSnF^Gc>KC=KtrZZGBXfpb(WGG?+@;-yq{0euriU}=FEh>)j zNdyv(1qCjNC5bUU`N@enF(IkB1u+Gg1-d1PMd_&}x@p-ZX_ZCgX)!sONihYLB^mj7 zG07Q;MJcHz`pG$&`tk9Zd6^~g@p=W7zc_4i^HWN5QtgUZf%bqLRt#c%WM*V!EMf+- E0LGy(uK)l5 literal 0 HcmV?d00001 diff --git a/lib/chardet/cli/__pycache__/chardetect.cpython-312.pyc b/lib/chardet/cli/__pycache__/chardetect.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a973f85318d9e6fe0b45955c3c74349ca2fa260a GIT binary patch literal 3619 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 literal 0 HcmV?d00001 diff --git a/lib/chardet/cli/chardetect.py b/lib/chardet/cli/chardetect.py new file mode 100644 index 0000000..e1d8cd6 --- /dev/null +++ b/lib/chardet/cli/chardetect.py @@ -0,0 +1,84 @@ +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from chardet import __version__ +from chardet.compat import PY2 +from chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{}: {} with confidence {}'.format(name, result['encoding'], + result['confidence']) + else: + return '{}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/lib/chardet/codingstatemachine.py b/lib/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/lib/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/lib/chardet/compat.py b/lib/chardet/compat.py new file mode 100644 index 0000000..8941572 --- /dev/null +++ b/lib/chardet/compat.py @@ -0,0 +1,36 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + string_types = (str, unicode) + text_type = unicode + iteritems = dict.iteritems +else: + PY2 = False + PY3 = True + string_types = (bytes, str) + text_type = str + iteritems = dict.items diff --git a/lib/chardet/cp949prober.py b/lib/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/lib/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/lib/chardet/enums.py b/lib/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/lib/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/lib/chardet/escprober.py b/lib/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/lib/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/lib/chardet/escsm.py b/lib/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/lib/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/lib/chardet/eucjpprober.py b/lib/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/lib/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/lib/chardet/euckrfreq.py b/lib/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/lib/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/lib/chardet/euckrprober.py b/lib/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/lib/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/lib/chardet/euctwfreq.py b/lib/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/lib/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/lib/chardet/euctwprober.py b/lib/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/lib/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/lib/chardet/gb2312freq.py b/lib/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/lib/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/lib/chardet/gb2312prober.py b/lib/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/lib/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/lib/chardet/hebrewprober.py b/lib/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/lib/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/lib/chardet/jisfreq.py b/lib/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/lib/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/lib/chardet/jpcntx.py b/lib/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/lib/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/lib/chardet/langbulgarianmodel.py b/lib/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..561bfd9 --- /dev/null +++ b/lib/chardet/langbulgarianmodel.py @@ -0,0 +1,4650 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +BULGARIAN_LANG_MODEL = { + 63: { # 'e' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 1, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 45: { # '\xad' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 1, # 'М' + 36: 0, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 31: { # 'А' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 1, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 1, # 'О' + 30: 2, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 2, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 0, # 'и' + 26: 2, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 1, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 32: { # 'Б' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 2, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 1, # 'Щ' + 61: 2, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 1, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 35: { # 'В' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 2, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 2, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 43: { # 'Г' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 1, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 37: { # 'Д' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 2, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 44: { # 'Е' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 2, # 'Ф' + 49: 1, # 'Х' + 53: 2, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 0, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 1, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 55: { # 'Ж' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 47: { # 'З' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 2, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 40: { # 'И' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 2, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 2, # 'М' + 36: 2, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 2, # 'Я' + 1: 1, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 3, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 0, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 59: { # 'Й' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 33: { # 'К' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 46: { # 'Л' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 2, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 38: { # 'М' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 36: { # 'Н' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 2, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 1, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 2, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 41: { # 'О' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 1, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 1, # 'Й' + 33: 2, # 'К' + 46: 2, # 'Л' + 38: 2, # 'М' + 36: 2, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 0, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 1, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 0, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 2, # 'ч' + 27: 0, # 'ш' + 24: 2, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 30: { # 'П' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 2, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 39: { # 'Р' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 2, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 1, # 'с' + 5: 0, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 28: { # 'С' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 3, # 'А' + 32: 2, # 'Б' + 35: 2, # 'В' + 43: 1, # 'Г' + 37: 2, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 2, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 1, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 34: { # 'Т' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 2, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 2, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 1, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 1, # 'Ъ' + 60: 0, # 'Ю' + 56: 1, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 3, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 51: { # 'У' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 2, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 2, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 2, # 'с' + 5: 1, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 48: { # 'Ф' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 2, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 1, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 2, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 49: { # 'Х' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 1, # 'П' + 39: 1, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 53: { # 'Ц' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 2, # 'И' + 59: 0, # 'Й' + 33: 2, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 2, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 50: { # 'Ч' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 2, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 2, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 54: { # 'Ш' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 1, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 1, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 2, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 1, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 57: { # 'Щ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 1, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 1, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 1, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 61: { # 'Ъ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 1, # 'Ж' + 47: 1, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 2, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 2, # 'Р' + 28: 1, # 'С' + 34: 1, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 1, # 'Х' + 53: 1, # 'Ц' + 50: 1, # 'Ч' + 54: 1, # 'Ш' + 57: 1, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 1, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 60: { # 'Ю' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 1, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 0, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 0, # 'е' + 23: 2, # 'ж' + 15: 1, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 0, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 56: { # 'Я' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 1, # 'В' + 43: 1, # 'Г' + 37: 1, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 1, # 'Л' + 38: 1, # 'М' + 36: 1, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 2, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 1, # 'и' + 26: 1, # 'й' + 12: 1, # 'к' + 10: 1, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 0, # 'о' + 13: 2, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 1: { # 'а' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 1, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 18: { # 'б' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 0, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 2, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 3, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 9: { # 'в' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 1, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 0, # 'в' + 20: 2, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 20: { # 'г' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 11: { # 'д' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 1, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 3: { # 'е' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 2, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 23: { # 'ж' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 15: { # 'з' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 2: { # 'и' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 1, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 1, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 1, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 1, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 26: { # 'й' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 2, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 12: { # 'к' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 1, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 1, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 3, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 10: { # 'л' + 63: 1, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 1, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 1, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 3, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 14: { # 'м' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 1, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 1, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 6: { # 'н' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 1, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 2, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 2, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 3, # 'ф' + 25: 2, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 4: { # 'о' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 2, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 3, # 'и' + 26: 3, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 2, # 'у' + 29: 3, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 3, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 13: { # 'п' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 3, # 'л' + 14: 1, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 7: { # 'р' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 3, # 'е' + 23: 3, # 'ж' + 15: 2, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 1, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 3, # 'х' + 22: 3, # 'ц' + 21: 2, # 'ч' + 27: 3, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 1, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 8: { # 'с' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 2, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 2, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 2, # 'ш' + 24: 0, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 5: { # 'т' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 2, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 3, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 2, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 3, # 'ъ' + 52: 2, # 'ь' + 42: 2, # 'ю' + 16: 3, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 19: { # 'у' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 2, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 2, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 3, # 'ш' + 24: 2, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 29: { # 'ф' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 1, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 2, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 2, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 25: { # 'х' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 2, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 1, # 'п' + 7: 3, # 'р' + 8: 1, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 1, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 22: { # 'ц' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 2, # 'в' + 20: 1, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 1, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 2, # 'к' + 10: 1, # 'л' + 14: 1, # 'м' + 6: 1, # 'н' + 4: 2, # 'о' + 13: 1, # 'п' + 7: 1, # 'р' + 8: 1, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 1, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 0, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 21: { # 'ч' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 1, # 'б' + 9: 3, # 'в' + 20: 1, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 1, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 2, # 'р' + 8: 0, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 1, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 27: { # 'ш' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 2, # 'в' + 20: 0, # 'г' + 11: 1, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 3, # 'к' + 10: 2, # 'л' + 14: 1, # 'м' + 6: 3, # 'н' + 4: 2, # 'о' + 13: 2, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 1, # 'т' + 19: 2, # 'у' + 29: 1, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 1, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 2, # 'ъ' + 52: 1, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 24: { # 'щ' + 63: 1, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 3, # 'а' + 18: 0, # 'б' + 9: 1, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 3, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 3, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 2, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 1, # 'р' + 8: 0, # 'с' + 5: 2, # 'т' + 19: 3, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 1, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 2, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 17: { # 'ъ' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 3, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 3, # 'ж' + 15: 3, # 'з' + 2: 1, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 3, # 'о' + 13: 3, # 'п' + 7: 3, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 2, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 2, # 'ш' + 24: 3, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 2, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 52: { # 'ь' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 1, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 1, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 1, # 'н' + 4: 3, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 1, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 1, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 1, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 42: { # 'ю' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 1, # 'а' + 18: 2, # 'б' + 9: 1, # 'в' + 20: 2, # 'г' + 11: 2, # 'д' + 3: 1, # 'е' + 23: 2, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 1, # 'й' + 12: 2, # 'к' + 10: 2, # 'л' + 14: 2, # 'м' + 6: 2, # 'н' + 4: 1, # 'о' + 13: 1, # 'п' + 7: 2, # 'р' + 8: 2, # 'с' + 5: 2, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 1, # 'х' + 22: 2, # 'ц' + 21: 3, # 'ч' + 27: 1, # 'ш' + 24: 1, # 'щ' + 17: 1, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 16: { # 'я' + 63: 0, # 'e' + 45: 1, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 3, # 'б' + 9: 3, # 'в' + 20: 2, # 'г' + 11: 3, # 'д' + 3: 2, # 'е' + 23: 1, # 'ж' + 15: 2, # 'з' + 2: 1, # 'и' + 26: 2, # 'й' + 12: 3, # 'к' + 10: 3, # 'л' + 14: 3, # 'м' + 6: 3, # 'н' + 4: 1, # 'о' + 13: 2, # 'п' + 7: 2, # 'р' + 8: 3, # 'с' + 5: 3, # 'т' + 19: 1, # 'у' + 29: 1, # 'ф' + 25: 3, # 'х' + 22: 2, # 'ц' + 21: 1, # 'ч' + 27: 1, # 'ш' + 24: 2, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 1, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 58: { # 'є' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, + 62: { # '№' + 63: 0, # 'e' + 45: 0, # '\xad' + 31: 0, # 'А' + 32: 0, # 'Б' + 35: 0, # 'В' + 43: 0, # 'Г' + 37: 0, # 'Д' + 44: 0, # 'Е' + 55: 0, # 'Ж' + 47: 0, # 'З' + 40: 0, # 'И' + 59: 0, # 'Й' + 33: 0, # 'К' + 46: 0, # 'Л' + 38: 0, # 'М' + 36: 0, # 'Н' + 41: 0, # 'О' + 30: 0, # 'П' + 39: 0, # 'Р' + 28: 0, # 'С' + 34: 0, # 'Т' + 51: 0, # 'У' + 48: 0, # 'Ф' + 49: 0, # 'Х' + 53: 0, # 'Ц' + 50: 0, # 'Ч' + 54: 0, # 'Ш' + 57: 0, # 'Щ' + 61: 0, # 'Ъ' + 60: 0, # 'Ю' + 56: 0, # 'Я' + 1: 0, # 'а' + 18: 0, # 'б' + 9: 0, # 'в' + 20: 0, # 'г' + 11: 0, # 'д' + 3: 0, # 'е' + 23: 0, # 'ж' + 15: 0, # 'з' + 2: 0, # 'и' + 26: 0, # 'й' + 12: 0, # 'к' + 10: 0, # 'л' + 14: 0, # 'м' + 6: 0, # 'н' + 4: 0, # 'о' + 13: 0, # 'п' + 7: 0, # 'р' + 8: 0, # 'с' + 5: 0, # 'т' + 19: 0, # 'у' + 29: 0, # 'ф' + 25: 0, # 'х' + 22: 0, # 'ц' + 21: 0, # 'ч' + 27: 0, # 'ш' + 24: 0, # 'щ' + 17: 0, # 'ъ' + 52: 0, # 'ь' + 42: 0, # 'ю' + 16: 0, # 'я' + 58: 0, # 'є' + 62: 0, # '№' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +ISO_8859_5_BULGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 77, # 'A' + 66: 90, # 'B' + 67: 99, # 'C' + 68: 100, # 'D' + 69: 72, # 'E' + 70: 109, # 'F' + 71: 107, # 'G' + 72: 101, # 'H' + 73: 79, # 'I' + 74: 185, # 'J' + 75: 81, # 'K' + 76: 102, # 'L' + 77: 76, # 'M' + 78: 94, # 'N' + 79: 82, # 'O' + 80: 110, # 'P' + 81: 186, # 'Q' + 82: 108, # 'R' + 83: 91, # 'S' + 84: 74, # 'T' + 85: 119, # 'U' + 86: 84, # 'V' + 87: 96, # 'W' + 88: 111, # 'X' + 89: 187, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 65, # 'a' + 98: 69, # 'b' + 99: 70, # 'c' + 100: 66, # 'd' + 101: 63, # 'e' + 102: 68, # 'f' + 103: 112, # 'g' + 104: 103, # 'h' + 105: 92, # 'i' + 106: 194, # 'j' + 107: 104, # 'k' + 108: 95, # 'l' + 109: 86, # 'm' + 110: 87, # 'n' + 111: 71, # 'o' + 112: 116, # 'p' + 113: 195, # 'q' + 114: 85, # 'r' + 115: 93, # 's' + 116: 97, # 't' + 117: 113, # 'u' + 118: 196, # 'v' + 119: 197, # 'w' + 120: 198, # 'x' + 121: 199, # 'y' + 122: 200, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 194, # '\x80' + 129: 195, # '\x81' + 130: 196, # '\x82' + 131: 197, # '\x83' + 132: 198, # '\x84' + 133: 199, # '\x85' + 134: 200, # '\x86' + 135: 201, # '\x87' + 136: 202, # '\x88' + 137: 203, # '\x89' + 138: 204, # '\x8a' + 139: 205, # '\x8b' + 140: 206, # '\x8c' + 141: 207, # '\x8d' + 142: 208, # '\x8e' + 143: 209, # '\x8f' + 144: 210, # '\x90' + 145: 211, # '\x91' + 146: 212, # '\x92' + 147: 213, # '\x93' + 148: 214, # '\x94' + 149: 215, # '\x95' + 150: 216, # '\x96' + 151: 217, # '\x97' + 152: 218, # '\x98' + 153: 219, # '\x99' + 154: 220, # '\x9a' + 155: 221, # '\x9b' + 156: 222, # '\x9c' + 157: 223, # '\x9d' + 158: 224, # '\x9e' + 159: 225, # '\x9f' + 160: 81, # '\xa0' + 161: 226, # 'Ё' + 162: 227, # 'Ђ' + 163: 228, # 'Ѓ' + 164: 229, # 'Є' + 165: 230, # 'Ѕ' + 166: 105, # 'І' + 167: 231, # 'Ї' + 168: 232, # 'Ј' + 169: 233, # 'Љ' + 170: 234, # 'Њ' + 171: 235, # 'Ћ' + 172: 236, # 'Ќ' + 173: 45, # '\xad' + 174: 237, # 'Ў' + 175: 238, # 'Џ' + 176: 31, # 'А' + 177: 32, # 'Б' + 178: 35, # 'В' + 179: 43, # 'Г' + 180: 37, # 'Д' + 181: 44, # 'Е' + 182: 55, # 'Ж' + 183: 47, # 'З' + 184: 40, # 'И' + 185: 59, # 'Й' + 186: 33, # 'К' + 187: 46, # 'Л' + 188: 38, # 'М' + 189: 36, # 'Н' + 190: 41, # 'О' + 191: 30, # 'П' + 192: 39, # 'Р' + 193: 28, # 'С' + 194: 34, # 'Т' + 195: 51, # 'У' + 196: 48, # 'Ф' + 197: 49, # 'Х' + 198: 53, # 'Ц' + 199: 50, # 'Ч' + 200: 54, # 'Ш' + 201: 57, # 'Щ' + 202: 61, # 'Ъ' + 203: 239, # 'Ы' + 204: 67, # 'Ь' + 205: 240, # 'Э' + 206: 60, # 'Ю' + 207: 56, # 'Я' + 208: 1, # 'а' + 209: 18, # 'б' + 210: 9, # 'в' + 211: 20, # 'г' + 212: 11, # 'д' + 213: 3, # 'е' + 214: 23, # 'ж' + 215: 15, # 'з' + 216: 2, # 'и' + 217: 26, # 'й' + 218: 12, # 'к' + 219: 10, # 'л' + 220: 14, # 'м' + 221: 6, # 'н' + 222: 4, # 'о' + 223: 13, # 'п' + 224: 7, # 'р' + 225: 8, # 'с' + 226: 5, # 'т' + 227: 19, # 'у' + 228: 29, # 'ф' + 229: 25, # 'х' + 230: 22, # 'ц' + 231: 21, # 'ч' + 232: 27, # 'ш' + 233: 24, # 'щ' + 234: 17, # 'ъ' + 235: 75, # 'ы' + 236: 52, # 'ь' + 237: 241, # 'э' + 238: 42, # 'ю' + 239: 16, # 'я' + 240: 62, # '№' + 241: 242, # 'ё' + 242: 243, # 'ђ' + 243: 244, # 'ѓ' + 244: 58, # 'є' + 245: 245, # 'ѕ' + 246: 98, # 'і' + 247: 246, # 'ї' + 248: 247, # 'ј' + 249: 248, # 'љ' + 250: 249, # 'њ' + 251: 250, # 'ћ' + 252: 251, # 'ќ' + 253: 91, # '§' + 254: 252, # 'ў' + 255: 253, # 'џ' +} + +ISO_8859_5_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', + language='Bulgarian', + char_to_order_map=ISO_8859_5_BULGARIAN_CHAR_TO_ORDER, + language_model=BULGARIAN_LANG_MODEL, + typical_positive_ratio=0.969392, + keep_ascii_letters=False, + alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') + +WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 77, # 'A' + 66: 90, # 'B' + 67: 99, # 'C' + 68: 100, # 'D' + 69: 72, # 'E' + 70: 109, # 'F' + 71: 107, # 'G' + 72: 101, # 'H' + 73: 79, # 'I' + 74: 185, # 'J' + 75: 81, # 'K' + 76: 102, # 'L' + 77: 76, # 'M' + 78: 94, # 'N' + 79: 82, # 'O' + 80: 110, # 'P' + 81: 186, # 'Q' + 82: 108, # 'R' + 83: 91, # 'S' + 84: 74, # 'T' + 85: 119, # 'U' + 86: 84, # 'V' + 87: 96, # 'W' + 88: 111, # 'X' + 89: 187, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 65, # 'a' + 98: 69, # 'b' + 99: 70, # 'c' + 100: 66, # 'd' + 101: 63, # 'e' + 102: 68, # 'f' + 103: 112, # 'g' + 104: 103, # 'h' + 105: 92, # 'i' + 106: 194, # 'j' + 107: 104, # 'k' + 108: 95, # 'l' + 109: 86, # 'm' + 110: 87, # 'n' + 111: 71, # 'o' + 112: 116, # 'p' + 113: 195, # 'q' + 114: 85, # 'r' + 115: 93, # 's' + 116: 97, # 't' + 117: 113, # 'u' + 118: 196, # 'v' + 119: 197, # 'w' + 120: 198, # 'x' + 121: 199, # 'y' + 122: 200, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 206, # 'Ђ' + 129: 207, # 'Ѓ' + 130: 208, # '‚' + 131: 209, # 'ѓ' + 132: 210, # '„' + 133: 211, # '…' + 134: 212, # '†' + 135: 213, # '‡' + 136: 120, # '€' + 137: 214, # '‰' + 138: 215, # 'Љ' + 139: 216, # '‹' + 140: 217, # 'Њ' + 141: 218, # 'Ќ' + 142: 219, # 'Ћ' + 143: 220, # 'Џ' + 144: 221, # 'ђ' + 145: 78, # '‘' + 146: 64, # '’' + 147: 83, # '“' + 148: 121, # '”' + 149: 98, # '•' + 150: 117, # '–' + 151: 105, # '—' + 152: 222, # None + 153: 223, # '™' + 154: 224, # 'љ' + 155: 225, # '›' + 156: 226, # 'њ' + 157: 227, # 'ќ' + 158: 228, # 'ћ' + 159: 229, # 'џ' + 160: 88, # '\xa0' + 161: 230, # 'Ў' + 162: 231, # 'ў' + 163: 232, # 'Ј' + 164: 233, # '¤' + 165: 122, # 'Ґ' + 166: 89, # '¦' + 167: 106, # '§' + 168: 234, # 'Ё' + 169: 235, # '©' + 170: 236, # 'Є' + 171: 237, # '«' + 172: 238, # '¬' + 173: 45, # '\xad' + 174: 239, # '®' + 175: 240, # 'Ї' + 176: 73, # '°' + 177: 80, # '±' + 178: 118, # 'І' + 179: 114, # 'і' + 180: 241, # 'ґ' + 181: 242, # 'µ' + 182: 243, # '¶' + 183: 244, # '·' + 184: 245, # 'ё' + 185: 62, # '№' + 186: 58, # 'є' + 187: 246, # '»' + 188: 247, # 'ј' + 189: 248, # 'Ѕ' + 190: 249, # 'ѕ' + 191: 250, # 'ї' + 192: 31, # 'А' + 193: 32, # 'Б' + 194: 35, # 'В' + 195: 43, # 'Г' + 196: 37, # 'Д' + 197: 44, # 'Е' + 198: 55, # 'Ж' + 199: 47, # 'З' + 200: 40, # 'И' + 201: 59, # 'Й' + 202: 33, # 'К' + 203: 46, # 'Л' + 204: 38, # 'М' + 205: 36, # 'Н' + 206: 41, # 'О' + 207: 30, # 'П' + 208: 39, # 'Р' + 209: 28, # 'С' + 210: 34, # 'Т' + 211: 51, # 'У' + 212: 48, # 'Ф' + 213: 49, # 'Х' + 214: 53, # 'Ц' + 215: 50, # 'Ч' + 216: 54, # 'Ш' + 217: 57, # 'Щ' + 218: 61, # 'Ъ' + 219: 251, # 'Ы' + 220: 67, # 'Ь' + 221: 252, # 'Э' + 222: 60, # 'Ю' + 223: 56, # 'Я' + 224: 1, # 'а' + 225: 18, # 'б' + 226: 9, # 'в' + 227: 20, # 'г' + 228: 11, # 'д' + 229: 3, # 'е' + 230: 23, # 'ж' + 231: 15, # 'з' + 232: 2, # 'и' + 233: 26, # 'й' + 234: 12, # 'к' + 235: 10, # 'л' + 236: 14, # 'м' + 237: 6, # 'н' + 238: 4, # 'о' + 239: 13, # 'п' + 240: 7, # 'р' + 241: 8, # 'с' + 242: 5, # 'т' + 243: 19, # 'у' + 244: 29, # 'ф' + 245: 25, # 'х' + 246: 22, # 'ц' + 247: 21, # 'ч' + 248: 27, # 'ш' + 249: 24, # 'щ' + 250: 17, # 'ъ' + 251: 75, # 'ы' + 252: 52, # 'ь' + 253: 253, # 'э' + 254: 42, # 'ю' + 255: 16, # 'я' +} + +WINDOWS_1251_BULGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', + language='Bulgarian', + char_to_order_map=WINDOWS_1251_BULGARIAN_CHAR_TO_ORDER, + language_model=BULGARIAN_LANG_MODEL, + typical_positive_ratio=0.969392, + keep_ascii_letters=False, + alphabet='АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЮЯабвгдежзийклмнопрстуфхцчшщъьюя') + diff --git a/lib/chardet/langgreekmodel.py b/lib/chardet/langgreekmodel.py new file mode 100644 index 0000000..02b94de --- /dev/null +++ b/lib/chardet/langgreekmodel.py @@ -0,0 +1,4398 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +GREEK_LANG_MODEL = { + 60: { # 'e' + 60: 2, # 'e' + 55: 1, # 'o' + 58: 2, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 55: { # 'o' + 60: 0, # 'e' + 55: 2, # 'o' + 58: 2, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 1, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 58: { # 't' + 60: 2, # 'e' + 55: 1, # 'o' + 58: 1, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 1, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 36: { # '·' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 61: { # 'Ά' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 1, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 1, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 46: { # 'Έ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 2, # 'β' + 20: 2, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 1, # 'σ' + 2: 2, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 54: { # 'Ό' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 31: { # 'Α' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 2, # 'Β' + 43: 2, # 'Γ' + 41: 1, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 2, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 1, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 2, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 2, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 1, # 'θ' + 5: 0, # 'ι' + 11: 2, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 2, # 'ς' + 7: 2, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 51: { # 'Β' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 1, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 43: { # 'Γ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 1, # 'Α' + 51: 0, # 'Β' + 43: 2, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 1, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 41: { # 'Δ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 1, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 34: { # 'Ε' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 2, # 'Γ' + 41: 2, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 1, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 2, # 'Χ' + 57: 2, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 1, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 1, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 2, # 'τ' + 12: 2, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 1, # 'ύ' + 27: 0, # 'ώ' + }, + 40: { # 'Η' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 1, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 2, # 'Θ' + 47: 0, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 52: { # 'Θ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 1, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 47: { # 'Ι' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 1, # 'Β' + 43: 1, # 'Γ' + 41: 2, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 2, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 1, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 1, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 44: { # 'Κ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 1, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 1, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 53: { # 'Λ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 2, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 2, # 'Σ' + 33: 0, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 1, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 38: { # 'Μ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 2, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 2, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 49: { # 'Ν' + 60: 2, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 1, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 1, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 59: { # 'Ξ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 39: { # 'Ο' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 1, # 'Β' + 43: 2, # 'Γ' + 41: 2, # 'Δ' + 34: 2, # 'Ε' + 40: 1, # 'Η' + 52: 2, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 2, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 2, # 'Φ' + 50: 2, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 2, # 'υ' + 28: 1, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 35: { # 'Π' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 2, # 'Λ' + 38: 1, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 1, # 'έ' + 22: 1, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 3, # 'ώ' + }, + 48: { # 'Ρ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 1, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 1, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 1, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 37: { # 'Σ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 1, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 2, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 2, # 'Υ' + 56: 0, # 'Φ' + 50: 2, # 'Χ' + 57: 2, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 2, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 2, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 2, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 33: { # 'Τ' + 60: 0, # 'e' + 55: 1, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 2, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 2, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 1, # 'Τ' + 45: 1, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 2, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 2, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 3, # 'ώ' + }, + 45: { # 'Υ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 2, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 2, # 'Η' + 52: 2, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 2, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 2, # 'Π' + 48: 1, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 56: { # 'Φ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 1, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 1, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 2, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 1, # 'ύ' + 27: 1, # 'ώ' + }, + 50: { # 'Χ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 1, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 2, # 'Ε' + 40: 2, # 'Η' + 52: 0, # 'Θ' + 47: 2, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 1, # 'Ν' + 59: 0, # 'Ξ' + 39: 1, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 1, # 'Χ' + 57: 1, # 'Ω' + 17: 2, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 2, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 57: { # 'Ω' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 1, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 1, # 'Λ' + 38: 0, # 'Μ' + 49: 2, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 2, # 'Ρ' + 37: 2, # 'Σ' + 33: 2, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 2, # 'ρ' + 14: 2, # 'ς' + 7: 2, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 17: { # 'ά' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 3, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 3, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 18: { # 'έ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 3, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 22: { # 'ή' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 1, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 15: { # 'ί' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 3, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 1, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 1: { # 'α' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 2, # 'ε' + 32: 3, # 'ζ' + 13: 1, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 0, # 'ώ' + }, + 29: { # 'β' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 2, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 3, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 20: { # 'γ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 3, # 'ώ' + }, + 21: { # 'δ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 3: { # 'ε' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 3, # 'ί' + 1: 2, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 2, # 'ε' + 32: 2, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ό' + 26: 3, # 'ύ' + 27: 2, # 'ώ' + }, + 32: { # 'ζ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 2, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 1, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 2, # 'ώ' + }, + 13: { # 'η' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 25: { # 'θ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 1, # 'λ' + 10: 3, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 5: { # 'ι' + 60: 0, # 'e' + 55: 1, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 0, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 0, # 'ύ' + 27: 3, # 'ώ' + }, + 11: { # 'κ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 2, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 16: { # 'λ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 1, # 'β' + 20: 2, # 'γ' + 21: 1, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 3, # 'λ' + 10: 2, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 10: { # 'μ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 1, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 2, # 'υ' + 28: 3, # 'φ' + 23: 0, # 'χ' + 42: 2, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 6: { # 'ν' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 1, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 30: { # 'ξ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 2, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 2, # 'ό' + 26: 3, # 'ύ' + 27: 1, # 'ώ' + }, + 4: { # 'ο' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 2, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 1, # 'ό' + 26: 3, # 'ύ' + 27: 2, # 'ώ' + }, + 9: { # 'π' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 3, # 'λ' + 10: 0, # 'μ' + 6: 2, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 2, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 3, # 'ώ' + }, + 8: { # 'ρ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 1, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 3, # 'ο' + 9: 2, # 'π' + 8: 2, # 'ρ' + 14: 0, # 'ς' + 7: 2, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 14: { # 'ς' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 2, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 0, # 'θ' + 5: 0, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 0, # 'τ' + 12: 0, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 7: { # 'σ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 3, # 'β' + 20: 0, # 'γ' + 21: 2, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 3, # 'θ' + 5: 3, # 'ι' + 11: 3, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 3, # 'φ' + 23: 3, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 2, # 'ώ' + }, + 2: { # 'τ' + 60: 0, # 'e' + 55: 2, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 2, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 3, # 'ι' + 11: 2, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 2, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 12: { # 'υ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 2, # 'ί' + 1: 3, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 2, # 'ε' + 32: 2, # 'ζ' + 13: 2, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 3, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 2, # 'ό' + 26: 0, # 'ύ' + 27: 2, # 'ώ' + }, + 28: { # 'φ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 3, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 0, # 'μ' + 6: 1, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 1, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 2, # 'ύ' + 27: 2, # 'ώ' + }, + 23: { # 'χ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 3, # 'ά' + 18: 2, # 'έ' + 22: 3, # 'ή' + 15: 3, # 'ί' + 1: 3, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 3, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 2, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 3, # 'ο' + 9: 0, # 'π' + 8: 3, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 3, # 'τ' + 12: 3, # 'υ' + 28: 0, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 3, # 'ω' + 19: 3, # 'ό' + 26: 3, # 'ύ' + 27: 3, # 'ώ' + }, + 42: { # 'ψ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 2, # 'ά' + 18: 2, # 'έ' + 22: 1, # 'ή' + 15: 2, # 'ί' + 1: 2, # 'α' + 29: 0, # 'β' + 20: 0, # 'γ' + 21: 0, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 3, # 'η' + 25: 0, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 0, # 'λ' + 10: 0, # 'μ' + 6: 0, # 'ν' + 30: 0, # 'ξ' + 4: 2, # 'ο' + 9: 0, # 'π' + 8: 0, # 'ρ' + 14: 0, # 'ς' + 7: 0, # 'σ' + 2: 2, # 'τ' + 12: 1, # 'υ' + 28: 0, # 'φ' + 23: 0, # 'χ' + 42: 0, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 24: { # 'ω' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 1, # 'ά' + 18: 0, # 'έ' + 22: 2, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 2, # 'β' + 20: 3, # 'γ' + 21: 2, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 0, # 'η' + 25: 3, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 0, # 'ξ' + 4: 0, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 19: { # 'ό' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 3, # 'β' + 20: 3, # 'γ' + 21: 3, # 'δ' + 3: 1, # 'ε' + 32: 2, # 'ζ' + 13: 2, # 'η' + 25: 2, # 'θ' + 5: 2, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 1, # 'ξ' + 4: 2, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 3, # 'χ' + 42: 2, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 26: { # 'ύ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 2, # 'α' + 29: 2, # 'β' + 20: 2, # 'γ' + 21: 1, # 'δ' + 3: 3, # 'ε' + 32: 0, # 'ζ' + 13: 2, # 'η' + 25: 3, # 'θ' + 5: 0, # 'ι' + 11: 3, # 'κ' + 16: 3, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 2, # 'ξ' + 4: 3, # 'ο' + 9: 3, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 2, # 'φ' + 23: 2, # 'χ' + 42: 2, # 'ψ' + 24: 2, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, + 27: { # 'ώ' + 60: 0, # 'e' + 55: 0, # 'o' + 58: 0, # 't' + 36: 0, # '·' + 61: 0, # 'Ά' + 46: 0, # 'Έ' + 54: 0, # 'Ό' + 31: 0, # 'Α' + 51: 0, # 'Β' + 43: 0, # 'Γ' + 41: 0, # 'Δ' + 34: 0, # 'Ε' + 40: 0, # 'Η' + 52: 0, # 'Θ' + 47: 0, # 'Ι' + 44: 0, # 'Κ' + 53: 0, # 'Λ' + 38: 0, # 'Μ' + 49: 0, # 'Ν' + 59: 0, # 'Ξ' + 39: 0, # 'Ο' + 35: 0, # 'Π' + 48: 0, # 'Ρ' + 37: 0, # 'Σ' + 33: 0, # 'Τ' + 45: 0, # 'Υ' + 56: 0, # 'Φ' + 50: 0, # 'Χ' + 57: 0, # 'Ω' + 17: 0, # 'ά' + 18: 0, # 'έ' + 22: 0, # 'ή' + 15: 0, # 'ί' + 1: 0, # 'α' + 29: 1, # 'β' + 20: 0, # 'γ' + 21: 3, # 'δ' + 3: 0, # 'ε' + 32: 0, # 'ζ' + 13: 1, # 'η' + 25: 2, # 'θ' + 5: 2, # 'ι' + 11: 0, # 'κ' + 16: 2, # 'λ' + 10: 3, # 'μ' + 6: 3, # 'ν' + 30: 1, # 'ξ' + 4: 0, # 'ο' + 9: 2, # 'π' + 8: 3, # 'ρ' + 14: 3, # 'ς' + 7: 3, # 'σ' + 2: 3, # 'τ' + 12: 0, # 'υ' + 28: 1, # 'φ' + 23: 1, # 'χ' + 42: 0, # 'ψ' + 24: 0, # 'ω' + 19: 0, # 'ό' + 26: 0, # 'ύ' + 27: 0, # 'ώ' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1253_GREEK_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 82, # 'A' + 66: 100, # 'B' + 67: 104, # 'C' + 68: 94, # 'D' + 69: 98, # 'E' + 70: 101, # 'F' + 71: 116, # 'G' + 72: 102, # 'H' + 73: 111, # 'I' + 74: 187, # 'J' + 75: 117, # 'K' + 76: 92, # 'L' + 77: 88, # 'M' + 78: 113, # 'N' + 79: 85, # 'O' + 80: 79, # 'P' + 81: 118, # 'Q' + 82: 105, # 'R' + 83: 83, # 'S' + 84: 67, # 'T' + 85: 114, # 'U' + 86: 119, # 'V' + 87: 95, # 'W' + 88: 99, # 'X' + 89: 109, # 'Y' + 90: 188, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 72, # 'a' + 98: 70, # 'b' + 99: 80, # 'c' + 100: 81, # 'd' + 101: 60, # 'e' + 102: 96, # 'f' + 103: 93, # 'g' + 104: 89, # 'h' + 105: 68, # 'i' + 106: 120, # 'j' + 107: 97, # 'k' + 108: 77, # 'l' + 109: 86, # 'm' + 110: 69, # 'n' + 111: 55, # 'o' + 112: 78, # 'p' + 113: 115, # 'q' + 114: 65, # 'r' + 115: 66, # 's' + 116: 58, # 't' + 117: 76, # 'u' + 118: 106, # 'v' + 119: 103, # 'w' + 120: 87, # 'x' + 121: 107, # 'y' + 122: 112, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 255, # '€' + 129: 255, # None + 130: 255, # '‚' + 131: 255, # 'ƒ' + 132: 255, # '„' + 133: 255, # '…' + 134: 255, # '†' + 135: 255, # '‡' + 136: 255, # None + 137: 255, # '‰' + 138: 255, # None + 139: 255, # '‹' + 140: 255, # None + 141: 255, # None + 142: 255, # None + 143: 255, # None + 144: 255, # None + 145: 255, # '‘' + 146: 255, # '’' + 147: 255, # '“' + 148: 255, # '”' + 149: 255, # '•' + 150: 255, # '–' + 151: 255, # '—' + 152: 255, # None + 153: 255, # '™' + 154: 255, # None + 155: 255, # '›' + 156: 255, # None + 157: 255, # None + 158: 255, # None + 159: 255, # None + 160: 253, # '\xa0' + 161: 233, # '΅' + 162: 61, # 'Ά' + 163: 253, # '£' + 164: 253, # '¤' + 165: 253, # '¥' + 166: 253, # '¦' + 167: 253, # '§' + 168: 253, # '¨' + 169: 253, # '©' + 170: 253, # None + 171: 253, # '«' + 172: 253, # '¬' + 173: 74, # '\xad' + 174: 253, # '®' + 175: 253, # '―' + 176: 253, # '°' + 177: 253, # '±' + 178: 253, # '²' + 179: 253, # '³' + 180: 247, # '΄' + 181: 253, # 'µ' + 182: 253, # '¶' + 183: 36, # '·' + 184: 46, # 'Έ' + 185: 71, # 'Ή' + 186: 73, # 'Ί' + 187: 253, # '»' + 188: 54, # 'Ό' + 189: 253, # '½' + 190: 108, # 'Ύ' + 191: 123, # 'Ώ' + 192: 110, # 'ΐ' + 193: 31, # 'Α' + 194: 51, # 'Β' + 195: 43, # 'Γ' + 196: 41, # 'Δ' + 197: 34, # 'Ε' + 198: 91, # 'Ζ' + 199: 40, # 'Η' + 200: 52, # 'Θ' + 201: 47, # 'Ι' + 202: 44, # 'Κ' + 203: 53, # 'Λ' + 204: 38, # 'Μ' + 205: 49, # 'Ν' + 206: 59, # 'Ξ' + 207: 39, # 'Ο' + 208: 35, # 'Π' + 209: 48, # 'Ρ' + 210: 250, # None + 211: 37, # 'Σ' + 212: 33, # 'Τ' + 213: 45, # 'Υ' + 214: 56, # 'Φ' + 215: 50, # 'Χ' + 216: 84, # 'Ψ' + 217: 57, # 'Ω' + 218: 120, # 'Ϊ' + 219: 121, # 'Ϋ' + 220: 17, # 'ά' + 221: 18, # 'έ' + 222: 22, # 'ή' + 223: 15, # 'ί' + 224: 124, # 'ΰ' + 225: 1, # 'α' + 226: 29, # 'β' + 227: 20, # 'γ' + 228: 21, # 'δ' + 229: 3, # 'ε' + 230: 32, # 'ζ' + 231: 13, # 'η' + 232: 25, # 'θ' + 233: 5, # 'ι' + 234: 11, # 'κ' + 235: 16, # 'λ' + 236: 10, # 'μ' + 237: 6, # 'ν' + 238: 30, # 'ξ' + 239: 4, # 'ο' + 240: 9, # 'π' + 241: 8, # 'ρ' + 242: 14, # 'ς' + 243: 7, # 'σ' + 244: 2, # 'τ' + 245: 12, # 'υ' + 246: 28, # 'φ' + 247: 23, # 'χ' + 248: 42, # 'ψ' + 249: 24, # 'ω' + 250: 64, # 'ϊ' + 251: 75, # 'ϋ' + 252: 19, # 'ό' + 253: 26, # 'ύ' + 254: 27, # 'ώ' + 255: 253, # None +} + +WINDOWS_1253_GREEK_MODEL = SingleByteCharSetModel(charset_name='windows-1253', + language='Greek', + char_to_order_map=WINDOWS_1253_GREEK_CHAR_TO_ORDER, + language_model=GREEK_LANG_MODEL, + typical_positive_ratio=0.982851, + keep_ascii_letters=False, + alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') + +ISO_8859_7_GREEK_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 82, # 'A' + 66: 100, # 'B' + 67: 104, # 'C' + 68: 94, # 'D' + 69: 98, # 'E' + 70: 101, # 'F' + 71: 116, # 'G' + 72: 102, # 'H' + 73: 111, # 'I' + 74: 187, # 'J' + 75: 117, # 'K' + 76: 92, # 'L' + 77: 88, # 'M' + 78: 113, # 'N' + 79: 85, # 'O' + 80: 79, # 'P' + 81: 118, # 'Q' + 82: 105, # 'R' + 83: 83, # 'S' + 84: 67, # 'T' + 85: 114, # 'U' + 86: 119, # 'V' + 87: 95, # 'W' + 88: 99, # 'X' + 89: 109, # 'Y' + 90: 188, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 72, # 'a' + 98: 70, # 'b' + 99: 80, # 'c' + 100: 81, # 'd' + 101: 60, # 'e' + 102: 96, # 'f' + 103: 93, # 'g' + 104: 89, # 'h' + 105: 68, # 'i' + 106: 120, # 'j' + 107: 97, # 'k' + 108: 77, # 'l' + 109: 86, # 'm' + 110: 69, # 'n' + 111: 55, # 'o' + 112: 78, # 'p' + 113: 115, # 'q' + 114: 65, # 'r' + 115: 66, # 's' + 116: 58, # 't' + 117: 76, # 'u' + 118: 106, # 'v' + 119: 103, # 'w' + 120: 87, # 'x' + 121: 107, # 'y' + 122: 112, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 255, # '\x80' + 129: 255, # '\x81' + 130: 255, # '\x82' + 131: 255, # '\x83' + 132: 255, # '\x84' + 133: 255, # '\x85' + 134: 255, # '\x86' + 135: 255, # '\x87' + 136: 255, # '\x88' + 137: 255, # '\x89' + 138: 255, # '\x8a' + 139: 255, # '\x8b' + 140: 255, # '\x8c' + 141: 255, # '\x8d' + 142: 255, # '\x8e' + 143: 255, # '\x8f' + 144: 255, # '\x90' + 145: 255, # '\x91' + 146: 255, # '\x92' + 147: 255, # '\x93' + 148: 255, # '\x94' + 149: 255, # '\x95' + 150: 255, # '\x96' + 151: 255, # '\x97' + 152: 255, # '\x98' + 153: 255, # '\x99' + 154: 255, # '\x9a' + 155: 255, # '\x9b' + 156: 255, # '\x9c' + 157: 255, # '\x9d' + 158: 255, # '\x9e' + 159: 255, # '\x9f' + 160: 253, # '\xa0' + 161: 233, # '‘' + 162: 90, # '’' + 163: 253, # '£' + 164: 253, # '€' + 165: 253, # '₯' + 166: 253, # '¦' + 167: 253, # '§' + 168: 253, # '¨' + 169: 253, # '©' + 170: 253, # 'ͺ' + 171: 253, # '«' + 172: 253, # '¬' + 173: 74, # '\xad' + 174: 253, # None + 175: 253, # '―' + 176: 253, # '°' + 177: 253, # '±' + 178: 253, # '²' + 179: 253, # '³' + 180: 247, # '΄' + 181: 248, # '΅' + 182: 61, # 'Ά' + 183: 36, # '·' + 184: 46, # 'Έ' + 185: 71, # 'Ή' + 186: 73, # 'Ί' + 187: 253, # '»' + 188: 54, # 'Ό' + 189: 253, # '½' + 190: 108, # 'Ύ' + 191: 123, # 'Ώ' + 192: 110, # 'ΐ' + 193: 31, # 'Α' + 194: 51, # 'Β' + 195: 43, # 'Γ' + 196: 41, # 'Δ' + 197: 34, # 'Ε' + 198: 91, # 'Ζ' + 199: 40, # 'Η' + 200: 52, # 'Θ' + 201: 47, # 'Ι' + 202: 44, # 'Κ' + 203: 53, # 'Λ' + 204: 38, # 'Μ' + 205: 49, # 'Ν' + 206: 59, # 'Ξ' + 207: 39, # 'Ο' + 208: 35, # 'Π' + 209: 48, # 'Ρ' + 210: 250, # None + 211: 37, # 'Σ' + 212: 33, # 'Τ' + 213: 45, # 'Υ' + 214: 56, # 'Φ' + 215: 50, # 'Χ' + 216: 84, # 'Ψ' + 217: 57, # 'Ω' + 218: 120, # 'Ϊ' + 219: 121, # 'Ϋ' + 220: 17, # 'ά' + 221: 18, # 'έ' + 222: 22, # 'ή' + 223: 15, # 'ί' + 224: 124, # 'ΰ' + 225: 1, # 'α' + 226: 29, # 'β' + 227: 20, # 'γ' + 228: 21, # 'δ' + 229: 3, # 'ε' + 230: 32, # 'ζ' + 231: 13, # 'η' + 232: 25, # 'θ' + 233: 5, # 'ι' + 234: 11, # 'κ' + 235: 16, # 'λ' + 236: 10, # 'μ' + 237: 6, # 'ν' + 238: 30, # 'ξ' + 239: 4, # 'ο' + 240: 9, # 'π' + 241: 8, # 'ρ' + 242: 14, # 'ς' + 243: 7, # 'σ' + 244: 2, # 'τ' + 245: 12, # 'υ' + 246: 28, # 'φ' + 247: 23, # 'χ' + 248: 42, # 'ψ' + 249: 24, # 'ω' + 250: 64, # 'ϊ' + 251: 75, # 'ϋ' + 252: 19, # 'ό' + 253: 26, # 'ύ' + 254: 27, # 'ώ' + 255: 253, # None +} + +ISO_8859_7_GREEK_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-7', + language='Greek', + char_to_order_map=ISO_8859_7_GREEK_CHAR_TO_ORDER, + language_model=GREEK_LANG_MODEL, + typical_positive_ratio=0.982851, + keep_ascii_letters=False, + alphabet='ΆΈΉΊΌΎΏΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩάέήίαβγδεζηθικλμνξοπρςστυφχψωόύώ') + diff --git a/lib/chardet/langhebrewmodel.py b/lib/chardet/langhebrewmodel.py new file mode 100644 index 0000000..40fd674 --- /dev/null +++ b/lib/chardet/langhebrewmodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +HEBREW_LANG_MODEL = { + 50: { # 'a' + 50: 0, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 2, # 'l' + 54: 2, # 'n' + 49: 0, # 'o' + 51: 2, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 1, # 'ק' + 7: 0, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 60: { # 'c' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 61: { # 'd' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 0, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 42: { # 'e' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 2, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 2, # 'l' + 54: 2, # 'n' + 49: 1, # 'o' + 51: 2, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 1, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 53: { # 'i' + 50: 1, # 'a' + 60: 2, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 0, # 'i' + 56: 1, # 'l' + 54: 2, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 56: { # 'l' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 2, # 'e' + 53: 2, # 'i' + 56: 2, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 54: { # 'n' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 49: { # 'o' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 2, # 'n' + 49: 1, # 'o' + 51: 2, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 51: { # 'r' + 50: 2, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 2, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 2, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 43: { # 's' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 2, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 2, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 44: { # 't' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 0, # 'd' + 42: 2, # 'e' + 53: 2, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 2, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 63: { # 'u' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 34: { # '\xa0' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 1, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 2, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 55: { # '´' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 1, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 2, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 1, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 48: { # '¼' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 39: { # '½' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 57: { # '¾' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 30: { # 'ְ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 2, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 1, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 2, # 'ע' + 26: 0, # 'ף' + 18: 2, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 59: { # 'ֱ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 1, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 0, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 41: { # 'ֲ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 0, # 'ם' + 6: 2, # 'מ' + 23: 0, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 33: { # 'ִ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 1, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 0, # 'ַ' + 29: 1, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 2, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 37: { # 'ֵ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 1, # 'ַ' + 29: 1, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 1, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 36: { # 'ֶ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 1, # 'ַ' + 29: 1, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 1, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 2, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 31: { # 'ַ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 1, # 'ֶ' + 31: 0, # 'ַ' + 29: 2, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 2, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 29: { # 'ָ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 1, # 'ַ' + 29: 2, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 2, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 35: { # 'ֹ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 2, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 2, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 62: { # 'ֻ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 2, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 1, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 28: { # 'ּ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 3, # 'ְ' + 59: 0, # 'ֱ' + 41: 1, # 'ֲ' + 33: 3, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 3, # 'ַ' + 29: 3, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 2, # 'ׁ' + 45: 1, # 'ׂ' + 9: 2, # 'א' + 8: 2, # 'ב' + 20: 1, # 'ג' + 16: 2, # 'ד' + 3: 1, # 'ה' + 2: 2, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 2, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 2, # 'ל' + 11: 1, # 'ם' + 6: 2, # 'מ' + 23: 1, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 2, # 'ר' + 10: 2, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 38: { # 'ׁ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 2, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 45: { # 'ׂ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 2, # 'ֶ' + 31: 1, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 2, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 9: { # 'א' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 2, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 2, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 8: { # 'ב' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 3, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 1, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 20: { # 'ג' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 2, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 1, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 0, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 16: { # 'ד' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 1, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 3: { # 'ה' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 1, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 3, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 0, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 2: { # 'ו' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 3, # 'ֹ' + 62: 0, # 'ֻ' + 28: 3, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 3, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 24: { # 'ז' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 1, # 'ֲ' + 33: 1, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 2, # 'ב' + 20: 2, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 2, # 'ח' + 22: 1, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 2, # 'נ' + 19: 1, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 1, # 'ש' + 5: 2, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 14: { # 'ח' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 1, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 2, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 1, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 22: { # 'ט' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 1, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 1, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 3, # 'ר' + 10: 2, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 1: { # 'י' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 3, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 25: { # 'ך' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 2, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 1, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 15: { # 'כ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 3, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 2, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 2, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 4: { # 'ל' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 3, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 11: { # 'ם' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 1, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 6: { # 'מ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 0, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 23: { # 'ן' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 1, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 1, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 12: { # 'נ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 19: { # 'ס' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 1, # 'ָ' + 35: 1, # 'ֹ' + 62: 2, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 1, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 3, # 'ף' + 18: 3, # 'פ' + 27: 0, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 1, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 13: { # 'ע' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 1, # 'ֱ' + 41: 2, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 1, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 2, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 2, # 'ע' + 26: 1, # 'ף' + 18: 2, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 26: { # 'ף' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 1, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 18: { # 'פ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 1, # 'ֵ' + 36: 2, # 'ֶ' + 31: 1, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 2, # 'ב' + 20: 3, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 2, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 2, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 27: { # 'ץ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 1, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 21: { # 'צ' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 1, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 1, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 0, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 17: { # 'ק' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 1, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 1, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 2, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 1, # 'ך' + 15: 1, # 'כ' + 4: 3, # 'ל' + 11: 2, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 2, # 'ץ' + 21: 3, # 'צ' + 17: 2, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 7: { # 'ר' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 2, # '´' + 48: 1, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 1, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 2, # 'ֹ' + 62: 1, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 3, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 3, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 3, # 'ץ' + 21: 3, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 10: { # 'ש' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 1, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 1, # 'ִ' + 37: 1, # 'ֵ' + 36: 1, # 'ֶ' + 31: 1, # 'ַ' + 29: 1, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 3, # 'ׁ' + 45: 2, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 3, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 3, # 'ט' + 1: 3, # 'י' + 25: 3, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 2, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 1, # '…' + }, + 5: { # 'ת' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 1, # '\xa0' + 55: 0, # '´' + 48: 1, # '¼' + 39: 1, # '½' + 57: 0, # '¾' + 30: 2, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 2, # 'ִ' + 37: 2, # 'ֵ' + 36: 2, # 'ֶ' + 31: 2, # 'ַ' + 29: 2, # 'ָ' + 35: 1, # 'ֹ' + 62: 1, # 'ֻ' + 28: 2, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 3, # 'א' + 8: 3, # 'ב' + 20: 3, # 'ג' + 16: 2, # 'ד' + 3: 3, # 'ה' + 2: 3, # 'ו' + 24: 2, # 'ז' + 14: 3, # 'ח' + 22: 2, # 'ט' + 1: 3, # 'י' + 25: 2, # 'ך' + 15: 3, # 'כ' + 4: 3, # 'ל' + 11: 3, # 'ם' + 6: 3, # 'מ' + 23: 3, # 'ן' + 12: 3, # 'נ' + 19: 2, # 'ס' + 13: 3, # 'ע' + 26: 2, # 'ף' + 18: 3, # 'פ' + 27: 1, # 'ץ' + 21: 2, # 'צ' + 17: 3, # 'ק' + 7: 3, # 'ר' + 10: 3, # 'ש' + 5: 3, # 'ת' + 32: 1, # '–' + 52: 1, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, + 32: { # '–' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 1, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 52: { # '’' + 50: 1, # 'a' + 60: 0, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 2, # 's' + 44: 2, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 1, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 47: { # '“' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 1, # 'l' + 54: 1, # 'n' + 49: 1, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 1, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 2, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 1, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 1, # 'ח' + 22: 1, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 1, # 'ס' + 13: 1, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 1, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 46: { # '”' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 1, # 'ב' + 20: 1, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 1, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 0, # '†' + 40: 0, # '…' + }, + 58: { # '†' + 50: 0, # 'a' + 60: 0, # 'c' + 61: 0, # 'd' + 42: 0, # 'e' + 53: 0, # 'i' + 56: 0, # 'l' + 54: 0, # 'n' + 49: 0, # 'o' + 51: 0, # 'r' + 43: 0, # 's' + 44: 0, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 0, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 0, # 'ה' + 2: 0, # 'ו' + 24: 0, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 0, # 'י' + 25: 0, # 'ך' + 15: 0, # 'כ' + 4: 0, # 'ל' + 11: 0, # 'ם' + 6: 0, # 'מ' + 23: 0, # 'ן' + 12: 0, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 0, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 0, # 'ר' + 10: 0, # 'ש' + 5: 0, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 0, # '”' + 58: 2, # '†' + 40: 0, # '…' + }, + 40: { # '…' + 50: 1, # 'a' + 60: 1, # 'c' + 61: 1, # 'd' + 42: 1, # 'e' + 53: 1, # 'i' + 56: 0, # 'l' + 54: 1, # 'n' + 49: 0, # 'o' + 51: 1, # 'r' + 43: 1, # 's' + 44: 1, # 't' + 63: 0, # 'u' + 34: 0, # '\xa0' + 55: 0, # '´' + 48: 0, # '¼' + 39: 0, # '½' + 57: 0, # '¾' + 30: 0, # 'ְ' + 59: 0, # 'ֱ' + 41: 0, # 'ֲ' + 33: 0, # 'ִ' + 37: 0, # 'ֵ' + 36: 0, # 'ֶ' + 31: 0, # 'ַ' + 29: 0, # 'ָ' + 35: 0, # 'ֹ' + 62: 0, # 'ֻ' + 28: 0, # 'ּ' + 38: 0, # 'ׁ' + 45: 0, # 'ׂ' + 9: 1, # 'א' + 8: 0, # 'ב' + 20: 0, # 'ג' + 16: 0, # 'ד' + 3: 1, # 'ה' + 2: 1, # 'ו' + 24: 1, # 'ז' + 14: 0, # 'ח' + 22: 0, # 'ט' + 1: 1, # 'י' + 25: 0, # 'ך' + 15: 1, # 'כ' + 4: 1, # 'ל' + 11: 0, # 'ם' + 6: 1, # 'מ' + 23: 0, # 'ן' + 12: 1, # 'נ' + 19: 0, # 'ס' + 13: 0, # 'ע' + 26: 0, # 'ף' + 18: 1, # 'פ' + 27: 0, # 'ץ' + 21: 0, # 'צ' + 17: 0, # 'ק' + 7: 1, # 'ר' + 10: 1, # 'ש' + 5: 1, # 'ת' + 32: 0, # '–' + 52: 0, # '’' + 47: 0, # '“' + 46: 1, # '”' + 58: 0, # '†' + 40: 2, # '…' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1255_HEBREW_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 69, # 'A' + 66: 91, # 'B' + 67: 79, # 'C' + 68: 80, # 'D' + 69: 92, # 'E' + 70: 89, # 'F' + 71: 97, # 'G' + 72: 90, # 'H' + 73: 68, # 'I' + 74: 111, # 'J' + 75: 112, # 'K' + 76: 82, # 'L' + 77: 73, # 'M' + 78: 95, # 'N' + 79: 85, # 'O' + 80: 78, # 'P' + 81: 121, # 'Q' + 82: 86, # 'R' + 83: 71, # 'S' + 84: 67, # 'T' + 85: 102, # 'U' + 86: 107, # 'V' + 87: 84, # 'W' + 88: 114, # 'X' + 89: 103, # 'Y' + 90: 115, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 50, # 'a' + 98: 74, # 'b' + 99: 60, # 'c' + 100: 61, # 'd' + 101: 42, # 'e' + 102: 76, # 'f' + 103: 70, # 'g' + 104: 64, # 'h' + 105: 53, # 'i' + 106: 105, # 'j' + 107: 93, # 'k' + 108: 56, # 'l' + 109: 65, # 'm' + 110: 54, # 'n' + 111: 49, # 'o' + 112: 66, # 'p' + 113: 110, # 'q' + 114: 51, # 'r' + 115: 43, # 's' + 116: 44, # 't' + 117: 63, # 'u' + 118: 81, # 'v' + 119: 77, # 'w' + 120: 98, # 'x' + 121: 75, # 'y' + 122: 108, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 124, # '€' + 129: 202, # None + 130: 203, # '‚' + 131: 204, # 'ƒ' + 132: 205, # '„' + 133: 40, # '…' + 134: 58, # '†' + 135: 206, # '‡' + 136: 207, # 'ˆ' + 137: 208, # '‰' + 138: 209, # None + 139: 210, # '‹' + 140: 211, # None + 141: 212, # None + 142: 213, # None + 143: 214, # None + 144: 215, # None + 145: 83, # '‘' + 146: 52, # '’' + 147: 47, # '“' + 148: 46, # '”' + 149: 72, # '•' + 150: 32, # '–' + 151: 94, # '—' + 152: 216, # '˜' + 153: 113, # '™' + 154: 217, # None + 155: 109, # '›' + 156: 218, # None + 157: 219, # None + 158: 220, # None + 159: 221, # None + 160: 34, # '\xa0' + 161: 116, # '¡' + 162: 222, # '¢' + 163: 118, # '£' + 164: 100, # '₪' + 165: 223, # '¥' + 166: 224, # '¦' + 167: 117, # '§' + 168: 119, # '¨' + 169: 104, # '©' + 170: 125, # '×' + 171: 225, # '«' + 172: 226, # '¬' + 173: 87, # '\xad' + 174: 99, # '®' + 175: 227, # '¯' + 176: 106, # '°' + 177: 122, # '±' + 178: 123, # '²' + 179: 228, # '³' + 180: 55, # '´' + 181: 229, # 'µ' + 182: 230, # '¶' + 183: 101, # '·' + 184: 231, # '¸' + 185: 232, # '¹' + 186: 120, # '÷' + 187: 233, # '»' + 188: 48, # '¼' + 189: 39, # '½' + 190: 57, # '¾' + 191: 234, # '¿' + 192: 30, # 'ְ' + 193: 59, # 'ֱ' + 194: 41, # 'ֲ' + 195: 88, # 'ֳ' + 196: 33, # 'ִ' + 197: 37, # 'ֵ' + 198: 36, # 'ֶ' + 199: 31, # 'ַ' + 200: 29, # 'ָ' + 201: 35, # 'ֹ' + 202: 235, # None + 203: 62, # 'ֻ' + 204: 28, # 'ּ' + 205: 236, # 'ֽ' + 206: 126, # '־' + 207: 237, # 'ֿ' + 208: 238, # '׀' + 209: 38, # 'ׁ' + 210: 45, # 'ׂ' + 211: 239, # '׃' + 212: 240, # 'װ' + 213: 241, # 'ױ' + 214: 242, # 'ײ' + 215: 243, # '׳' + 216: 127, # '״' + 217: 244, # None + 218: 245, # None + 219: 246, # None + 220: 247, # None + 221: 248, # None + 222: 249, # None + 223: 250, # None + 224: 9, # 'א' + 225: 8, # 'ב' + 226: 20, # 'ג' + 227: 16, # 'ד' + 228: 3, # 'ה' + 229: 2, # 'ו' + 230: 24, # 'ז' + 231: 14, # 'ח' + 232: 22, # 'ט' + 233: 1, # 'י' + 234: 25, # 'ך' + 235: 15, # 'כ' + 236: 4, # 'ל' + 237: 11, # 'ם' + 238: 6, # 'מ' + 239: 23, # 'ן' + 240: 12, # 'נ' + 241: 19, # 'ס' + 242: 13, # 'ע' + 243: 26, # 'ף' + 244: 18, # 'פ' + 245: 27, # 'ץ' + 246: 21, # 'צ' + 247: 17, # 'ק' + 248: 7, # 'ר' + 249: 10, # 'ש' + 250: 5, # 'ת' + 251: 251, # None + 252: 252, # None + 253: 128, # '\u200e' + 254: 96, # '\u200f' + 255: 253, # None +} + +WINDOWS_1255_HEBREW_MODEL = SingleByteCharSetModel(charset_name='windows-1255', + language='Hebrew', + char_to_order_map=WINDOWS_1255_HEBREW_CHAR_TO_ORDER, + language_model=HEBREW_LANG_MODEL, + typical_positive_ratio=0.984004, + keep_ascii_letters=False, + alphabet='אבגדהוזחטיךכלםמןנסעףפץצקרשתװױײ') + diff --git a/lib/chardet/langhungarianmodel.py b/lib/chardet/langhungarianmodel.py new file mode 100644 index 0000000..24a097f --- /dev/null +++ b/lib/chardet/langhungarianmodel.py @@ -0,0 +1,4650 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +HUNGARIAN_LANG_MODEL = { + 28: { # 'A' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 2, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 2, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 2, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 1, # 'Á' + 44: 0, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 40: { # 'B' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 3, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 54: { # 'C' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 3, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 45: { # 'D' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 32: { # 'E' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 2, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 50: { # 'F' + 28: 1, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 0, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 49: { # 'G' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 2, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 38: { # 'H' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 0, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 1, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 2, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 2, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 39: { # 'I' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 2, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 53: { # 'J' + 28: 2, # 'A' + 40: 0, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 0, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 36: { # 'K' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 2, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 41: { # 'L' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 1, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 34: { # 'M' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 3, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 1, # 'ű' + }, + 35: { # 'N' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 2, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 2, # 'Y' + 52: 1, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 47: { # 'O' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 2, # 'K' + 41: 2, # 'L' + 34: 2, # 'M' + 35: 2, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 1, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 1, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 46: { # 'P' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 3, # 'á' + 15: 2, # 'é' + 30: 0, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 0, # 'ű' + }, + 43: { # 'R' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 2, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 2, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 33: { # 'S' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 3, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 1, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 37: { # 'T' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 1, # 'S' + 37: 2, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 2, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 1, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 2, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 2, # 'Á' + 44: 2, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 57: { # 'U' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 48: { # 'V' + 28: 2, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 2, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 2, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 2, # 'o' + 23: 0, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 2, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 0, # 'Ú' + 63: 1, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 55: { # 'Y' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 1, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 2, # 'Z' + 2: 1, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 0, # 'r' + 5: 0, # 's' + 3: 0, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 1, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 52: { # 'Z' + 28: 2, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 2, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 2, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 2, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 1, # 'U' + 48: 1, # 'V' + 55: 1, # 'Y' + 52: 1, # 'Z' + 2: 1, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 0, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 2, # 'Á' + 44: 1, # 'É' + 61: 1, # 'Í' + 58: 1, # 'Ó' + 59: 1, # 'Ö' + 60: 1, # 'Ú' + 63: 1, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 2: { # 'a' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 18: { # 'b' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 26: { # 'c' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 1, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 2, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 2, # 'á' + 15: 2, # 'é' + 30: 2, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 17: { # 'd' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 2, # 'k' + 6: 1, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 1: { # 'e' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 2, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 27: { # 'f' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 3, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 2, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 3, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 12: { # 'g' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 20: { # 'h' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 3, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 1, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 1, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 9: { # 'i' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 2, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 3, # 'ó' + 24: 1, # 'ö' + 31: 2, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 1, # 'ű' + }, + 22: { # 'j' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 1, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 1, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 7: { # 'k' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 2, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 1, # 'ú' + 29: 3, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 6: { # 'l' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 1, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 3, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 3, # 'ő' + 56: 1, # 'ű' + }, + 13: { # 'm' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 1, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 3, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 3, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 2, # 'ű' + }, + 4: { # 'n' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 1, # 'x' + 16: 3, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 8: { # 'o' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 1, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 23: { # 'p' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 3, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 10: { # 'r' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 2, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 2, # 'ű' + }, + 5: { # 's' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 2, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 3: { # 't' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 1, # 'g' + 20: 3, # 'h' + 9: 3, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 3, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 3, # 'ú' + 29: 3, # 'ü' + 42: 3, # 'ő' + 56: 2, # 'ű' + }, + 21: { # 'u' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 2, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 2, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 1, # 'u' + 19: 3, # 'v' + 62: 1, # 'x' + 16: 1, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 2, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 1, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 19: { # 'v' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 2, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 2, # 'ö' + 31: 1, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 1, # 'ű' + }, + 62: { # 'x' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 0, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 1, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 1, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 1, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 16: { # 'y' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 3, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 2, # 'j' + 7: 2, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 2, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 2, # 'í' + 25: 2, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 2, # 'ü' + 42: 1, # 'ő' + 56: 2, # 'ű' + }, + 11: { # 'z' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 3, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 3, # 'd' + 1: 3, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 3, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 3, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 3, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 3, # 'á' + 15: 3, # 'é' + 30: 3, # 'í' + 25: 3, # 'ó' + 24: 3, # 'ö' + 31: 2, # 'ú' + 29: 3, # 'ü' + 42: 2, # 'ő' + 56: 1, # 'ű' + }, + 51: { # 'Á' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 1, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 44: { # 'É' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 1, # 'E' + 50: 0, # 'F' + 49: 2, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 2, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 2, # 'R' + 33: 2, # 'S' + 37: 2, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 3, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 61: { # 'Í' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 0, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 1, # 'm' + 4: 0, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 0, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 58: { # 'Ó' + 28: 1, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 1, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 2, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 2, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 0, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 1, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 59: { # 'Ö' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 1, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 1, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 0, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 2, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 60: { # 'Ú' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 1, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 1, # 'F' + 49: 1, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 0, # 'b' + 26: 0, # 'c' + 17: 0, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 2, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 2, # 'j' + 7: 0, # 'k' + 6: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 0, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 0, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 63: { # 'Ü' + 28: 0, # 'A' + 40: 1, # 'B' + 54: 0, # 'C' + 45: 1, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 1, # 'G' + 38: 1, # 'H' + 39: 0, # 'I' + 53: 1, # 'J' + 36: 1, # 'K' + 41: 1, # 'L' + 34: 1, # 'M' + 35: 1, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 1, # 'R' + 33: 1, # 'S' + 37: 1, # 'T' + 57: 0, # 'U' + 48: 1, # 'V' + 55: 0, # 'Y' + 52: 1, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 0, # 'f' + 12: 1, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 0, # 'j' + 7: 0, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 1, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 14: { # 'á' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 3, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 3, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 2, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 1, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 2, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 15: { # 'é' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 3, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 3, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 30: { # 'í' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 0, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 0, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 2, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 2, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 25: { # 'ó' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 2, # 'a' + 18: 3, # 'b' + 26: 2, # 'c' + 17: 3, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 2, # 'g' + 20: 2, # 'h' + 9: 2, # 'i' + 22: 2, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 8: 1, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 1, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 1, # 'ö' + 31: 1, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 24: { # 'ö' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 0, # 'a' + 18: 3, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 0, # 'e' + 27: 1, # 'f' + 12: 2, # 'g' + 20: 1, # 'h' + 9: 0, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 2, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 3, # 't' + 21: 0, # 'u' + 19: 3, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 3, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 31: { # 'ú' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 2, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 2, # 'f' + 12: 3, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 3, # 'j' + 7: 1, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 3, # 'r' + 5: 3, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 1, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 29: { # 'ü' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 3, # 'g' + 20: 2, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 3, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 8: 0, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 0, # 'u' + 19: 2, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 1, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 42: { # 'ő' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 2, # 'b' + 26: 1, # 'c' + 17: 2, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 2, # 'k' + 6: 3, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 8: 1, # 'o' + 23: 1, # 'p' + 10: 2, # 'r' + 5: 2, # 's' + 3: 2, # 't' + 21: 1, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 1, # 'é' + 30: 1, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 1, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, + 56: { # 'ű' + 28: 0, # 'A' + 40: 0, # 'B' + 54: 0, # 'C' + 45: 0, # 'D' + 32: 0, # 'E' + 50: 0, # 'F' + 49: 0, # 'G' + 38: 0, # 'H' + 39: 0, # 'I' + 53: 0, # 'J' + 36: 0, # 'K' + 41: 0, # 'L' + 34: 0, # 'M' + 35: 0, # 'N' + 47: 0, # 'O' + 46: 0, # 'P' + 43: 0, # 'R' + 33: 0, # 'S' + 37: 0, # 'T' + 57: 0, # 'U' + 48: 0, # 'V' + 55: 0, # 'Y' + 52: 0, # 'Z' + 2: 1, # 'a' + 18: 1, # 'b' + 26: 0, # 'c' + 17: 1, # 'd' + 1: 1, # 'e' + 27: 1, # 'f' + 12: 1, # 'g' + 20: 1, # 'h' + 9: 1, # 'i' + 22: 1, # 'j' + 7: 1, # 'k' + 6: 1, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 8: 0, # 'o' + 23: 0, # 'p' + 10: 1, # 'r' + 5: 1, # 's' + 3: 1, # 't' + 21: 0, # 'u' + 19: 1, # 'v' + 62: 0, # 'x' + 16: 0, # 'y' + 11: 2, # 'z' + 51: 0, # 'Á' + 44: 0, # 'É' + 61: 0, # 'Í' + 58: 0, # 'Ó' + 59: 0, # 'Ö' + 60: 0, # 'Ú' + 63: 0, # 'Ü' + 14: 0, # 'á' + 15: 0, # 'é' + 30: 0, # 'í' + 25: 0, # 'ó' + 24: 0, # 'ö' + 31: 0, # 'ú' + 29: 0, # 'ü' + 42: 0, # 'ő' + 56: 0, # 'ű' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 28, # 'A' + 66: 40, # 'B' + 67: 54, # 'C' + 68: 45, # 'D' + 69: 32, # 'E' + 70: 50, # 'F' + 71: 49, # 'G' + 72: 38, # 'H' + 73: 39, # 'I' + 74: 53, # 'J' + 75: 36, # 'K' + 76: 41, # 'L' + 77: 34, # 'M' + 78: 35, # 'N' + 79: 47, # 'O' + 80: 46, # 'P' + 81: 72, # 'Q' + 82: 43, # 'R' + 83: 33, # 'S' + 84: 37, # 'T' + 85: 57, # 'U' + 86: 48, # 'V' + 87: 64, # 'W' + 88: 68, # 'X' + 89: 55, # 'Y' + 90: 52, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 2, # 'a' + 98: 18, # 'b' + 99: 26, # 'c' + 100: 17, # 'd' + 101: 1, # 'e' + 102: 27, # 'f' + 103: 12, # 'g' + 104: 20, # 'h' + 105: 9, # 'i' + 106: 22, # 'j' + 107: 7, # 'k' + 108: 6, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 8, # 'o' + 112: 23, # 'p' + 113: 67, # 'q' + 114: 10, # 'r' + 115: 5, # 's' + 116: 3, # 't' + 117: 21, # 'u' + 118: 19, # 'v' + 119: 65, # 'w' + 120: 62, # 'x' + 121: 16, # 'y' + 122: 11, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 161, # '€' + 129: 162, # None + 130: 163, # '‚' + 131: 164, # None + 132: 165, # '„' + 133: 166, # '…' + 134: 167, # '†' + 135: 168, # '‡' + 136: 169, # None + 137: 170, # '‰' + 138: 171, # 'Š' + 139: 172, # '‹' + 140: 173, # 'Ś' + 141: 174, # 'Ť' + 142: 175, # 'Ž' + 143: 176, # 'Ź' + 144: 177, # None + 145: 178, # '‘' + 146: 179, # '’' + 147: 180, # '“' + 148: 78, # '”' + 149: 181, # '•' + 150: 69, # '–' + 151: 182, # '—' + 152: 183, # None + 153: 184, # '™' + 154: 185, # 'š' + 155: 186, # '›' + 156: 187, # 'ś' + 157: 188, # 'ť' + 158: 189, # 'ž' + 159: 190, # 'ź' + 160: 191, # '\xa0' + 161: 192, # 'ˇ' + 162: 193, # '˘' + 163: 194, # 'Ł' + 164: 195, # '¤' + 165: 196, # 'Ą' + 166: 197, # '¦' + 167: 76, # '§' + 168: 198, # '¨' + 169: 199, # '©' + 170: 200, # 'Ş' + 171: 201, # '«' + 172: 202, # '¬' + 173: 203, # '\xad' + 174: 204, # '®' + 175: 205, # 'Ż' + 176: 81, # '°' + 177: 206, # '±' + 178: 207, # '˛' + 179: 208, # 'ł' + 180: 209, # '´' + 181: 210, # 'µ' + 182: 211, # '¶' + 183: 212, # '·' + 184: 213, # '¸' + 185: 214, # 'ą' + 186: 215, # 'ş' + 187: 216, # '»' + 188: 217, # 'Ľ' + 189: 218, # '˝' + 190: 219, # 'ľ' + 191: 220, # 'ż' + 192: 221, # 'Ŕ' + 193: 51, # 'Á' + 194: 83, # 'Â' + 195: 222, # 'Ă' + 196: 80, # 'Ä' + 197: 223, # 'Ĺ' + 198: 224, # 'Ć' + 199: 225, # 'Ç' + 200: 226, # 'Č' + 201: 44, # 'É' + 202: 227, # 'Ę' + 203: 228, # 'Ë' + 204: 229, # 'Ě' + 205: 61, # 'Í' + 206: 230, # 'Î' + 207: 231, # 'Ď' + 208: 232, # 'Đ' + 209: 233, # 'Ń' + 210: 234, # 'Ň' + 211: 58, # 'Ó' + 212: 235, # 'Ô' + 213: 66, # 'Ő' + 214: 59, # 'Ö' + 215: 236, # '×' + 216: 237, # 'Ř' + 217: 238, # 'Ů' + 218: 60, # 'Ú' + 219: 70, # 'Ű' + 220: 63, # 'Ü' + 221: 239, # 'Ý' + 222: 240, # 'Ţ' + 223: 241, # 'ß' + 224: 84, # 'ŕ' + 225: 14, # 'á' + 226: 75, # 'â' + 227: 242, # 'ă' + 228: 71, # 'ä' + 229: 82, # 'ĺ' + 230: 243, # 'ć' + 231: 73, # 'ç' + 232: 244, # 'č' + 233: 15, # 'é' + 234: 85, # 'ę' + 235: 79, # 'ë' + 236: 86, # 'ě' + 237: 30, # 'í' + 238: 77, # 'î' + 239: 87, # 'ď' + 240: 245, # 'đ' + 241: 246, # 'ń' + 242: 247, # 'ň' + 243: 25, # 'ó' + 244: 74, # 'ô' + 245: 42, # 'ő' + 246: 24, # 'ö' + 247: 248, # '÷' + 248: 249, # 'ř' + 249: 250, # 'ů' + 250: 31, # 'ú' + 251: 56, # 'ű' + 252: 29, # 'ü' + 253: 251, # 'ý' + 254: 252, # 'ţ' + 255: 253, # '˙' +} + +WINDOWS_1250_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1250', + language='Hungarian', + char_to_order_map=WINDOWS_1250_HUNGARIAN_CHAR_TO_ORDER, + language_model=HUNGARIAN_LANG_MODEL, + typical_positive_ratio=0.947368, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') + +ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 28, # 'A' + 66: 40, # 'B' + 67: 54, # 'C' + 68: 45, # 'D' + 69: 32, # 'E' + 70: 50, # 'F' + 71: 49, # 'G' + 72: 38, # 'H' + 73: 39, # 'I' + 74: 53, # 'J' + 75: 36, # 'K' + 76: 41, # 'L' + 77: 34, # 'M' + 78: 35, # 'N' + 79: 47, # 'O' + 80: 46, # 'P' + 81: 71, # 'Q' + 82: 43, # 'R' + 83: 33, # 'S' + 84: 37, # 'T' + 85: 57, # 'U' + 86: 48, # 'V' + 87: 64, # 'W' + 88: 68, # 'X' + 89: 55, # 'Y' + 90: 52, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 2, # 'a' + 98: 18, # 'b' + 99: 26, # 'c' + 100: 17, # 'd' + 101: 1, # 'e' + 102: 27, # 'f' + 103: 12, # 'g' + 104: 20, # 'h' + 105: 9, # 'i' + 106: 22, # 'j' + 107: 7, # 'k' + 108: 6, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 8, # 'o' + 112: 23, # 'p' + 113: 67, # 'q' + 114: 10, # 'r' + 115: 5, # 's' + 116: 3, # 't' + 117: 21, # 'u' + 118: 19, # 'v' + 119: 65, # 'w' + 120: 62, # 'x' + 121: 16, # 'y' + 122: 11, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 159, # '\x80' + 129: 160, # '\x81' + 130: 161, # '\x82' + 131: 162, # '\x83' + 132: 163, # '\x84' + 133: 164, # '\x85' + 134: 165, # '\x86' + 135: 166, # '\x87' + 136: 167, # '\x88' + 137: 168, # '\x89' + 138: 169, # '\x8a' + 139: 170, # '\x8b' + 140: 171, # '\x8c' + 141: 172, # '\x8d' + 142: 173, # '\x8e' + 143: 174, # '\x8f' + 144: 175, # '\x90' + 145: 176, # '\x91' + 146: 177, # '\x92' + 147: 178, # '\x93' + 148: 179, # '\x94' + 149: 180, # '\x95' + 150: 181, # '\x96' + 151: 182, # '\x97' + 152: 183, # '\x98' + 153: 184, # '\x99' + 154: 185, # '\x9a' + 155: 186, # '\x9b' + 156: 187, # '\x9c' + 157: 188, # '\x9d' + 158: 189, # '\x9e' + 159: 190, # '\x9f' + 160: 191, # '\xa0' + 161: 192, # 'Ą' + 162: 193, # '˘' + 163: 194, # 'Ł' + 164: 195, # '¤' + 165: 196, # 'Ľ' + 166: 197, # 'Ś' + 167: 75, # '§' + 168: 198, # '¨' + 169: 199, # 'Š' + 170: 200, # 'Ş' + 171: 201, # 'Ť' + 172: 202, # 'Ź' + 173: 203, # '\xad' + 174: 204, # 'Ž' + 175: 205, # 'Ż' + 176: 79, # '°' + 177: 206, # 'ą' + 178: 207, # '˛' + 179: 208, # 'ł' + 180: 209, # '´' + 181: 210, # 'ľ' + 182: 211, # 'ś' + 183: 212, # 'ˇ' + 184: 213, # '¸' + 185: 214, # 'š' + 186: 215, # 'ş' + 187: 216, # 'ť' + 188: 217, # 'ź' + 189: 218, # '˝' + 190: 219, # 'ž' + 191: 220, # 'ż' + 192: 221, # 'Ŕ' + 193: 51, # 'Á' + 194: 81, # 'Â' + 195: 222, # 'Ă' + 196: 78, # 'Ä' + 197: 223, # 'Ĺ' + 198: 224, # 'Ć' + 199: 225, # 'Ç' + 200: 226, # 'Č' + 201: 44, # 'É' + 202: 227, # 'Ę' + 203: 228, # 'Ë' + 204: 229, # 'Ě' + 205: 61, # 'Í' + 206: 230, # 'Î' + 207: 231, # 'Ď' + 208: 232, # 'Đ' + 209: 233, # 'Ń' + 210: 234, # 'Ň' + 211: 58, # 'Ó' + 212: 235, # 'Ô' + 213: 66, # 'Ő' + 214: 59, # 'Ö' + 215: 236, # '×' + 216: 237, # 'Ř' + 217: 238, # 'Ů' + 218: 60, # 'Ú' + 219: 69, # 'Ű' + 220: 63, # 'Ü' + 221: 239, # 'Ý' + 222: 240, # 'Ţ' + 223: 241, # 'ß' + 224: 82, # 'ŕ' + 225: 14, # 'á' + 226: 74, # 'â' + 227: 242, # 'ă' + 228: 70, # 'ä' + 229: 80, # 'ĺ' + 230: 243, # 'ć' + 231: 72, # 'ç' + 232: 244, # 'č' + 233: 15, # 'é' + 234: 83, # 'ę' + 235: 77, # 'ë' + 236: 84, # 'ě' + 237: 30, # 'í' + 238: 76, # 'î' + 239: 85, # 'ď' + 240: 245, # 'đ' + 241: 246, # 'ń' + 242: 247, # 'ň' + 243: 25, # 'ó' + 244: 73, # 'ô' + 245: 42, # 'ő' + 246: 24, # 'ö' + 247: 248, # '÷' + 248: 249, # 'ř' + 249: 250, # 'ů' + 250: 31, # 'ú' + 251: 56, # 'ű' + 252: 29, # 'ü' + 253: 251, # 'ý' + 254: 252, # 'ţ' + 255: 253, # '˙' +} + +ISO_8859_2_HUNGARIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-2', + language='Hungarian', + char_to_order_map=ISO_8859_2_HUNGARIAN_CHAR_TO_ORDER, + language_model=HUNGARIAN_LANG_MODEL, + typical_positive_ratio=0.947368, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVZabcdefghijklmnoprstuvzÁÉÍÓÖÚÜáéíóöúüŐőŰű') + diff --git a/lib/chardet/langrussianmodel.py b/lib/chardet/langrussianmodel.py new file mode 100644 index 0000000..569689d --- /dev/null +++ b/lib/chardet/langrussianmodel.py @@ -0,0 +1,5718 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +RUSSIAN_LANG_MODEL = { + 37: { # 'А' + 37: 0, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 44: { # 'Б' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 2, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 33: { # 'В' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 0, # 'ю' + 16: 1, # 'я' + }, + 46: { # 'Г' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 41: { # 'Д' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 3, # 'ж' + 20: 1, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 48: { # 'Е' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 2, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 1, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'р' + 7: 3, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 56: { # 'Ж' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 1, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 2, # 'ю' + 16: 0, # 'я' + }, + 51: { # 'З' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 1, # 'я' + }, + 42: { # 'И' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 2, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 60: { # 'Й' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 36: { # 'К' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 2, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 49: { # 'Л' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 0, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 2, # 'ю' + 16: 1, # 'я' + }, + 38: { # 'М' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 1, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 31: { # 'Н' + 37: 2, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 2, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 34: { # 'О' + 37: 0, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 2, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 1, # 'З' + 42: 1, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 2, # 'Л' + 38: 1, # 'М' + 31: 2, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 1, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 35: { # 'П' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 2, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 1, # 'с' + 6: 1, # 'т' + 14: 2, # 'у' + 39: 1, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 2, # 'я' + }, + 45: { # 'Р' + 37: 2, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 2, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 2, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 2, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 2, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 2, # 'я' + }, + 32: { # 'С' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 2, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 2, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 40: { # 'Т' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 2, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 1, # 'Ь' + 47: 1, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 52: { # 'У' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 1, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 1, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 1, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 1, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 0, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 53: { # 'Ф' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 1, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 55: { # 'Х' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 2, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 0, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 58: { # 'Ц' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 1, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 50: { # 'Ч' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 1, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 1, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 57: { # 'Ш' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 1, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 63: { # 'Щ' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 1, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 62: { # 'Ы' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 1, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 61: { # 'Ь' + 37: 0, # 'А' + 44: 1, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 1, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 1, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 47: { # 'Э' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 1, # 'Й' + 36: 1, # 'К' + 49: 1, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 1, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 59: { # 'Ю' + 37: 1, # 'А' + 44: 1, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 1, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 0, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 0, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 43: { # 'Я' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 1, # 'В' + 46: 1, # 'Г' + 41: 0, # 'Д' + 48: 1, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 1, # 'С' + 40: 1, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 1, # 'Х' + 58: 0, # 'Ц' + 50: 1, # 'Ч' + 57: 0, # 'Ш' + 63: 1, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 1, # 'Ю' + 43: 1, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 0, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 1, # 'й' + 11: 1, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 1, # 'п' + 9: 1, # 'р' + 7: 1, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 3: { # 'а' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 1, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 21: { # 'б' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 1, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 2, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 10: { # 'в' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 19: { # 'г' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 13: { # 'д' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 3, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 2: { # 'е' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 24: { # 'ж' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 1, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 0, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 20: { # 'з' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 1, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 4: { # 'и' + 37: 1, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 23: { # 'й' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 1, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 2, # 'я' + }, + 11: { # 'к' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 3, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 1, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 8: { # 'л' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 3, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 1, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 1, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 12: { # 'м' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 5: { # 'н' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 3, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 2, # 'щ' + 54: 1, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 1: { # 'о' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 3, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 15: { # 'п' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 3, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 0, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 1, # 'ш' + 29: 1, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 2, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 3, # 'я' + }, + 9: { # 'р' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 2, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 7: { # 'с' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 1, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 2, # 'ш' + 29: 1, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 6: { # 'т' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 2, # 'щ' + 54: 2, # 'ъ' + 18: 3, # 'ы' + 17: 3, # 'ь' + 30: 2, # 'э' + 27: 2, # 'ю' + 16: 3, # 'я' + }, + 14: { # 'у' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 3, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 2, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 2, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 2, # 'э' + 27: 3, # 'ю' + 16: 2, # 'я' + }, + 39: { # 'ф' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 0, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 2, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 2, # 'ы' + 17: 1, # 'ь' + 30: 2, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 26: { # 'х' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 3, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 1, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 1, # 'п' + 9: 3, # 'р' + 7: 2, # 'с' + 6: 2, # 'т' + 14: 2, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 1, # 'ъ' + 18: 0, # 'ы' + 17: 1, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 28: { # 'ц' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 1, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 2, # 'к' + 8: 1, # 'л' + 12: 1, # 'м' + 5: 1, # 'н' + 1: 3, # 'о' + 15: 0, # 'п' + 9: 1, # 'р' + 7: 0, # 'с' + 6: 1, # 'т' + 14: 3, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 1, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 3, # 'ы' + 17: 1, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 22: { # 'ч' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 2, # 'л' + 12: 1, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 3, # 'т' + 14: 3, # 'у' + 39: 1, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 1, # 'ч' + 25: 2, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 3, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 25: { # 'ш' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 1, # 'б' + 10: 2, # 'в' + 19: 1, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 2, # 'м' + 5: 3, # 'н' + 1: 3, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 1, # 'с' + 6: 2, # 'т' + 14: 3, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 1, # 'ц' + 22: 1, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 3, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 0, # 'я' + }, + 29: { # 'щ' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 3, # 'а' + 21: 0, # 'б' + 10: 1, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 3, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 3, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 1, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 0, # 'п' + 9: 2, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 2, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 2, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 0, # 'я' + }, + 54: { # 'ъ' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 0, # 'б' + 10: 0, # 'в' + 19: 0, # 'г' + 13: 0, # 'д' + 2: 2, # 'е' + 24: 0, # 'ж' + 20: 0, # 'з' + 4: 0, # 'и' + 23: 0, # 'й' + 11: 0, # 'к' + 8: 0, # 'л' + 12: 0, # 'м' + 5: 0, # 'н' + 1: 0, # 'о' + 15: 0, # 'п' + 9: 0, # 'р' + 7: 0, # 'с' + 6: 0, # 'т' + 14: 0, # 'у' + 39: 0, # 'ф' + 26: 0, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 0, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 1, # 'ю' + 16: 2, # 'я' + }, + 18: { # 'ы' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 3, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 2, # 'и' + 23: 3, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 1, # 'о' + 15: 3, # 'п' + 9: 3, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 0, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 3, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 0, # 'ю' + 16: 2, # 'я' + }, + 17: { # 'ь' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 2, # 'б' + 10: 2, # 'в' + 19: 2, # 'г' + 13: 2, # 'д' + 2: 3, # 'е' + 24: 1, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 0, # 'й' + 11: 3, # 'к' + 8: 0, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 2, # 'о' + 15: 2, # 'п' + 9: 1, # 'р' + 7: 3, # 'с' + 6: 2, # 'т' + 14: 0, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 3, # 'ш' + 29: 2, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 3, # 'ю' + 16: 3, # 'я' + }, + 30: { # 'э' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 1, # 'М' + 31: 1, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 1, # 'Р' + 32: 1, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 1, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 1, # 'б' + 10: 1, # 'в' + 19: 1, # 'г' + 13: 2, # 'д' + 2: 1, # 'е' + 24: 0, # 'ж' + 20: 1, # 'з' + 4: 0, # 'и' + 23: 2, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 2, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 2, # 'ф' + 26: 1, # 'х' + 28: 0, # 'ц' + 22: 0, # 'ч' + 25: 1, # 'ш' + 29: 0, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 1, # 'ю' + 16: 1, # 'я' + }, + 27: { # 'ю' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 2, # 'а' + 21: 3, # 'б' + 10: 1, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 1, # 'е' + 24: 2, # 'ж' + 20: 2, # 'з' + 4: 1, # 'и' + 23: 1, # 'й' + 11: 2, # 'к' + 8: 2, # 'л' + 12: 2, # 'м' + 5: 2, # 'н' + 1: 1, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 0, # 'у' + 39: 1, # 'ф' + 26: 2, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 1, # 'э' + 27: 2, # 'ю' + 16: 1, # 'я' + }, + 16: { # 'я' + 37: 0, # 'А' + 44: 0, # 'Б' + 33: 0, # 'В' + 46: 0, # 'Г' + 41: 0, # 'Д' + 48: 0, # 'Е' + 56: 0, # 'Ж' + 51: 0, # 'З' + 42: 0, # 'И' + 60: 0, # 'Й' + 36: 0, # 'К' + 49: 0, # 'Л' + 38: 0, # 'М' + 31: 0, # 'Н' + 34: 0, # 'О' + 35: 0, # 'П' + 45: 0, # 'Р' + 32: 0, # 'С' + 40: 0, # 'Т' + 52: 0, # 'У' + 53: 0, # 'Ф' + 55: 0, # 'Х' + 58: 0, # 'Ц' + 50: 0, # 'Ч' + 57: 0, # 'Ш' + 63: 0, # 'Щ' + 62: 0, # 'Ы' + 61: 0, # 'Ь' + 47: 0, # 'Э' + 59: 0, # 'Ю' + 43: 0, # 'Я' + 3: 0, # 'а' + 21: 2, # 'б' + 10: 3, # 'в' + 19: 2, # 'г' + 13: 3, # 'д' + 2: 3, # 'е' + 24: 3, # 'ж' + 20: 3, # 'з' + 4: 2, # 'и' + 23: 2, # 'й' + 11: 3, # 'к' + 8: 3, # 'л' + 12: 3, # 'м' + 5: 3, # 'н' + 1: 0, # 'о' + 15: 2, # 'п' + 9: 2, # 'р' + 7: 3, # 'с' + 6: 3, # 'т' + 14: 1, # 'у' + 39: 1, # 'ф' + 26: 3, # 'х' + 28: 2, # 'ц' + 22: 2, # 'ч' + 25: 2, # 'ш' + 29: 3, # 'щ' + 54: 0, # 'ъ' + 18: 0, # 'ы' + 17: 0, # 'ь' + 30: 0, # 'э' + 27: 2, # 'ю' + 16: 2, # 'я' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +IBM866_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 37, # 'А' + 129: 44, # 'Б' + 130: 33, # 'В' + 131: 46, # 'Г' + 132: 41, # 'Д' + 133: 48, # 'Е' + 134: 56, # 'Ж' + 135: 51, # 'З' + 136: 42, # 'И' + 137: 60, # 'Й' + 138: 36, # 'К' + 139: 49, # 'Л' + 140: 38, # 'М' + 141: 31, # 'Н' + 142: 34, # 'О' + 143: 35, # 'П' + 144: 45, # 'Р' + 145: 32, # 'С' + 146: 40, # 'Т' + 147: 52, # 'У' + 148: 53, # 'Ф' + 149: 55, # 'Х' + 150: 58, # 'Ц' + 151: 50, # 'Ч' + 152: 57, # 'Ш' + 153: 63, # 'Щ' + 154: 70, # 'Ъ' + 155: 62, # 'Ы' + 156: 61, # 'Ь' + 157: 47, # 'Э' + 158: 59, # 'Ю' + 159: 43, # 'Я' + 160: 3, # 'а' + 161: 21, # 'б' + 162: 10, # 'в' + 163: 19, # 'г' + 164: 13, # 'д' + 165: 2, # 'е' + 166: 24, # 'ж' + 167: 20, # 'з' + 168: 4, # 'и' + 169: 23, # 'й' + 170: 11, # 'к' + 171: 8, # 'л' + 172: 12, # 'м' + 173: 5, # 'н' + 174: 1, # 'о' + 175: 15, # 'п' + 176: 191, # '░' + 177: 192, # '▒' + 178: 193, # '▓' + 179: 194, # '│' + 180: 195, # '┤' + 181: 196, # '╡' + 182: 197, # '╢' + 183: 198, # '╖' + 184: 199, # '╕' + 185: 200, # '╣' + 186: 201, # '║' + 187: 202, # '╗' + 188: 203, # '╝' + 189: 204, # '╜' + 190: 205, # '╛' + 191: 206, # '┐' + 192: 207, # '└' + 193: 208, # '┴' + 194: 209, # '┬' + 195: 210, # '├' + 196: 211, # '─' + 197: 212, # '┼' + 198: 213, # '╞' + 199: 214, # '╟' + 200: 215, # '╚' + 201: 216, # '╔' + 202: 217, # '╩' + 203: 218, # '╦' + 204: 219, # '╠' + 205: 220, # '═' + 206: 221, # '╬' + 207: 222, # '╧' + 208: 223, # '╨' + 209: 224, # '╤' + 210: 225, # '╥' + 211: 226, # '╙' + 212: 227, # '╘' + 213: 228, # '╒' + 214: 229, # '╓' + 215: 230, # '╫' + 216: 231, # '╪' + 217: 232, # '┘' + 218: 233, # '┌' + 219: 234, # '█' + 220: 235, # '▄' + 221: 236, # '▌' + 222: 237, # '▐' + 223: 238, # '▀' + 224: 9, # 'р' + 225: 7, # 'с' + 226: 6, # 'т' + 227: 14, # 'у' + 228: 39, # 'ф' + 229: 26, # 'х' + 230: 28, # 'ц' + 231: 22, # 'ч' + 232: 25, # 'ш' + 233: 29, # 'щ' + 234: 54, # 'ъ' + 235: 18, # 'ы' + 236: 17, # 'ь' + 237: 30, # 'э' + 238: 27, # 'ю' + 239: 16, # 'я' + 240: 239, # 'Ё' + 241: 68, # 'ё' + 242: 240, # 'Є' + 243: 241, # 'є' + 244: 242, # 'Ї' + 245: 243, # 'ї' + 246: 244, # 'Ў' + 247: 245, # 'ў' + 248: 246, # '°' + 249: 247, # '∙' + 250: 248, # '·' + 251: 249, # '√' + 252: 250, # '№' + 253: 251, # '¤' + 254: 252, # '■' + 255: 255, # '\xa0' +} + +IBM866_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM866', + language='Russian', + char_to_order_map=IBM866_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # 'Ђ' + 129: 192, # 'Ѓ' + 130: 193, # '‚' + 131: 194, # 'ѓ' + 132: 195, # '„' + 133: 196, # '…' + 134: 197, # '†' + 135: 198, # '‡' + 136: 199, # '€' + 137: 200, # '‰' + 138: 201, # 'Љ' + 139: 202, # '‹' + 140: 203, # 'Њ' + 141: 204, # 'Ќ' + 142: 205, # 'Ћ' + 143: 206, # 'Џ' + 144: 207, # 'ђ' + 145: 208, # '‘' + 146: 209, # '’' + 147: 210, # '“' + 148: 211, # '”' + 149: 212, # '•' + 150: 213, # '–' + 151: 214, # '—' + 152: 215, # None + 153: 216, # '™' + 154: 217, # 'љ' + 155: 218, # '›' + 156: 219, # 'њ' + 157: 220, # 'ќ' + 158: 221, # 'ћ' + 159: 222, # 'џ' + 160: 223, # '\xa0' + 161: 224, # 'Ў' + 162: 225, # 'ў' + 163: 226, # 'Ј' + 164: 227, # '¤' + 165: 228, # 'Ґ' + 166: 229, # '¦' + 167: 230, # '§' + 168: 231, # 'Ё' + 169: 232, # '©' + 170: 233, # 'Є' + 171: 234, # '«' + 172: 235, # '¬' + 173: 236, # '\xad' + 174: 237, # '®' + 175: 238, # 'Ї' + 176: 239, # '°' + 177: 240, # '±' + 178: 241, # 'І' + 179: 242, # 'і' + 180: 243, # 'ґ' + 181: 244, # 'µ' + 182: 245, # '¶' + 183: 246, # '·' + 184: 68, # 'ё' + 185: 247, # '№' + 186: 248, # 'є' + 187: 249, # '»' + 188: 250, # 'ј' + 189: 251, # 'Ѕ' + 190: 252, # 'ѕ' + 191: 253, # 'ї' + 192: 37, # 'А' + 193: 44, # 'Б' + 194: 33, # 'В' + 195: 46, # 'Г' + 196: 41, # 'Д' + 197: 48, # 'Е' + 198: 56, # 'Ж' + 199: 51, # 'З' + 200: 42, # 'И' + 201: 60, # 'Й' + 202: 36, # 'К' + 203: 49, # 'Л' + 204: 38, # 'М' + 205: 31, # 'Н' + 206: 34, # 'О' + 207: 35, # 'П' + 208: 45, # 'Р' + 209: 32, # 'С' + 210: 40, # 'Т' + 211: 52, # 'У' + 212: 53, # 'Ф' + 213: 55, # 'Х' + 214: 58, # 'Ц' + 215: 50, # 'Ч' + 216: 57, # 'Ш' + 217: 63, # 'Щ' + 218: 70, # 'Ъ' + 219: 62, # 'Ы' + 220: 61, # 'Ь' + 221: 47, # 'Э' + 222: 59, # 'Ю' + 223: 43, # 'Я' + 224: 3, # 'а' + 225: 21, # 'б' + 226: 10, # 'в' + 227: 19, # 'г' + 228: 13, # 'д' + 229: 2, # 'е' + 230: 24, # 'ж' + 231: 20, # 'з' + 232: 4, # 'и' + 233: 23, # 'й' + 234: 11, # 'к' + 235: 8, # 'л' + 236: 12, # 'м' + 237: 5, # 'н' + 238: 1, # 'о' + 239: 15, # 'п' + 240: 9, # 'р' + 241: 7, # 'с' + 242: 6, # 'т' + 243: 14, # 'у' + 244: 39, # 'ф' + 245: 26, # 'х' + 246: 28, # 'ц' + 247: 22, # 'ч' + 248: 25, # 'ш' + 249: 29, # 'щ' + 250: 54, # 'ъ' + 251: 18, # 'ы' + 252: 17, # 'ь' + 253: 30, # 'э' + 254: 27, # 'ю' + 255: 16, # 'я' +} + +WINDOWS_1251_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='windows-1251', + language='Russian', + char_to_order_map=WINDOWS_1251_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +IBM855_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # 'ђ' + 129: 192, # 'Ђ' + 130: 193, # 'ѓ' + 131: 194, # 'Ѓ' + 132: 68, # 'ё' + 133: 195, # 'Ё' + 134: 196, # 'є' + 135: 197, # 'Є' + 136: 198, # 'ѕ' + 137: 199, # 'Ѕ' + 138: 200, # 'і' + 139: 201, # 'І' + 140: 202, # 'ї' + 141: 203, # 'Ї' + 142: 204, # 'ј' + 143: 205, # 'Ј' + 144: 206, # 'љ' + 145: 207, # 'Љ' + 146: 208, # 'њ' + 147: 209, # 'Њ' + 148: 210, # 'ћ' + 149: 211, # 'Ћ' + 150: 212, # 'ќ' + 151: 213, # 'Ќ' + 152: 214, # 'ў' + 153: 215, # 'Ў' + 154: 216, # 'џ' + 155: 217, # 'Џ' + 156: 27, # 'ю' + 157: 59, # 'Ю' + 158: 54, # 'ъ' + 159: 70, # 'Ъ' + 160: 3, # 'а' + 161: 37, # 'А' + 162: 21, # 'б' + 163: 44, # 'Б' + 164: 28, # 'ц' + 165: 58, # 'Ц' + 166: 13, # 'д' + 167: 41, # 'Д' + 168: 2, # 'е' + 169: 48, # 'Е' + 170: 39, # 'ф' + 171: 53, # 'Ф' + 172: 19, # 'г' + 173: 46, # 'Г' + 174: 218, # '«' + 175: 219, # '»' + 176: 220, # '░' + 177: 221, # '▒' + 178: 222, # '▓' + 179: 223, # '│' + 180: 224, # '┤' + 181: 26, # 'х' + 182: 55, # 'Х' + 183: 4, # 'и' + 184: 42, # 'И' + 185: 225, # '╣' + 186: 226, # '║' + 187: 227, # '╗' + 188: 228, # '╝' + 189: 23, # 'й' + 190: 60, # 'Й' + 191: 229, # '┐' + 192: 230, # '└' + 193: 231, # '┴' + 194: 232, # '┬' + 195: 233, # '├' + 196: 234, # '─' + 197: 235, # '┼' + 198: 11, # 'к' + 199: 36, # 'К' + 200: 236, # '╚' + 201: 237, # '╔' + 202: 238, # '╩' + 203: 239, # '╦' + 204: 240, # '╠' + 205: 241, # '═' + 206: 242, # '╬' + 207: 243, # '¤' + 208: 8, # 'л' + 209: 49, # 'Л' + 210: 12, # 'м' + 211: 38, # 'М' + 212: 5, # 'н' + 213: 31, # 'Н' + 214: 1, # 'о' + 215: 34, # 'О' + 216: 15, # 'п' + 217: 244, # '┘' + 218: 245, # '┌' + 219: 246, # '█' + 220: 247, # '▄' + 221: 35, # 'П' + 222: 16, # 'я' + 223: 248, # '▀' + 224: 43, # 'Я' + 225: 9, # 'р' + 226: 45, # 'Р' + 227: 7, # 'с' + 228: 32, # 'С' + 229: 6, # 'т' + 230: 40, # 'Т' + 231: 14, # 'у' + 232: 52, # 'У' + 233: 24, # 'ж' + 234: 56, # 'Ж' + 235: 10, # 'в' + 236: 33, # 'В' + 237: 17, # 'ь' + 238: 61, # 'Ь' + 239: 249, # '№' + 240: 250, # '\xad' + 241: 18, # 'ы' + 242: 62, # 'Ы' + 243: 20, # 'з' + 244: 51, # 'З' + 245: 25, # 'ш' + 246: 57, # 'Ш' + 247: 30, # 'э' + 248: 47, # 'Э' + 249: 29, # 'щ' + 250: 63, # 'Щ' + 251: 22, # 'ч' + 252: 50, # 'Ч' + 253: 251, # '§' + 254: 252, # '■' + 255: 255, # '\xa0' +} + +IBM855_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='IBM855', + language='Russian', + char_to_order_map=IBM855_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +KOI8_R_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # '─' + 129: 192, # '│' + 130: 193, # '┌' + 131: 194, # '┐' + 132: 195, # '└' + 133: 196, # '┘' + 134: 197, # '├' + 135: 198, # '┤' + 136: 199, # '┬' + 137: 200, # '┴' + 138: 201, # '┼' + 139: 202, # '▀' + 140: 203, # '▄' + 141: 204, # '█' + 142: 205, # '▌' + 143: 206, # '▐' + 144: 207, # '░' + 145: 208, # '▒' + 146: 209, # '▓' + 147: 210, # '⌠' + 148: 211, # '■' + 149: 212, # '∙' + 150: 213, # '√' + 151: 214, # '≈' + 152: 215, # '≤' + 153: 216, # '≥' + 154: 217, # '\xa0' + 155: 218, # '⌡' + 156: 219, # '°' + 157: 220, # '²' + 158: 221, # '·' + 159: 222, # '÷' + 160: 223, # '═' + 161: 224, # '║' + 162: 225, # '╒' + 163: 68, # 'ё' + 164: 226, # '╓' + 165: 227, # '╔' + 166: 228, # '╕' + 167: 229, # '╖' + 168: 230, # '╗' + 169: 231, # '╘' + 170: 232, # '╙' + 171: 233, # '╚' + 172: 234, # '╛' + 173: 235, # '╜' + 174: 236, # '╝' + 175: 237, # '╞' + 176: 238, # '╟' + 177: 239, # '╠' + 178: 240, # '╡' + 179: 241, # 'Ё' + 180: 242, # '╢' + 181: 243, # '╣' + 182: 244, # '╤' + 183: 245, # '╥' + 184: 246, # '╦' + 185: 247, # '╧' + 186: 248, # '╨' + 187: 249, # '╩' + 188: 250, # '╪' + 189: 251, # '╫' + 190: 252, # '╬' + 191: 253, # '©' + 192: 27, # 'ю' + 193: 3, # 'а' + 194: 21, # 'б' + 195: 28, # 'ц' + 196: 13, # 'д' + 197: 2, # 'е' + 198: 39, # 'ф' + 199: 19, # 'г' + 200: 26, # 'х' + 201: 4, # 'и' + 202: 23, # 'й' + 203: 11, # 'к' + 204: 8, # 'л' + 205: 12, # 'м' + 206: 5, # 'н' + 207: 1, # 'о' + 208: 15, # 'п' + 209: 16, # 'я' + 210: 9, # 'р' + 211: 7, # 'с' + 212: 6, # 'т' + 213: 14, # 'у' + 214: 24, # 'ж' + 215: 10, # 'в' + 216: 17, # 'ь' + 217: 18, # 'ы' + 218: 20, # 'з' + 219: 25, # 'ш' + 220: 30, # 'э' + 221: 29, # 'щ' + 222: 22, # 'ч' + 223: 54, # 'ъ' + 224: 59, # 'Ю' + 225: 37, # 'А' + 226: 44, # 'Б' + 227: 58, # 'Ц' + 228: 41, # 'Д' + 229: 48, # 'Е' + 230: 53, # 'Ф' + 231: 46, # 'Г' + 232: 55, # 'Х' + 233: 42, # 'И' + 234: 60, # 'Й' + 235: 36, # 'К' + 236: 49, # 'Л' + 237: 38, # 'М' + 238: 31, # 'Н' + 239: 34, # 'О' + 240: 35, # 'П' + 241: 43, # 'Я' + 242: 45, # 'Р' + 243: 32, # 'С' + 244: 40, # 'Т' + 245: 52, # 'У' + 246: 56, # 'Ж' + 247: 33, # 'В' + 248: 61, # 'Ь' + 249: 62, # 'Ы' + 250: 51, # 'З' + 251: 57, # 'Ш' + 252: 47, # 'Э' + 253: 63, # 'Щ' + 254: 50, # 'Ч' + 255: 70, # 'Ъ' +} + +KOI8_R_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='KOI8-R', + language='Russian', + char_to_order_map=KOI8_R_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 37, # 'А' + 129: 44, # 'Б' + 130: 33, # 'В' + 131: 46, # 'Г' + 132: 41, # 'Д' + 133: 48, # 'Е' + 134: 56, # 'Ж' + 135: 51, # 'З' + 136: 42, # 'И' + 137: 60, # 'Й' + 138: 36, # 'К' + 139: 49, # 'Л' + 140: 38, # 'М' + 141: 31, # 'Н' + 142: 34, # 'О' + 143: 35, # 'П' + 144: 45, # 'Р' + 145: 32, # 'С' + 146: 40, # 'Т' + 147: 52, # 'У' + 148: 53, # 'Ф' + 149: 55, # 'Х' + 150: 58, # 'Ц' + 151: 50, # 'Ч' + 152: 57, # 'Ш' + 153: 63, # 'Щ' + 154: 70, # 'Ъ' + 155: 62, # 'Ы' + 156: 61, # 'Ь' + 157: 47, # 'Э' + 158: 59, # 'Ю' + 159: 43, # 'Я' + 160: 191, # '†' + 161: 192, # '°' + 162: 193, # 'Ґ' + 163: 194, # '£' + 164: 195, # '§' + 165: 196, # '•' + 166: 197, # '¶' + 167: 198, # 'І' + 168: 199, # '®' + 169: 200, # '©' + 170: 201, # '™' + 171: 202, # 'Ђ' + 172: 203, # 'ђ' + 173: 204, # '≠' + 174: 205, # 'Ѓ' + 175: 206, # 'ѓ' + 176: 207, # '∞' + 177: 208, # '±' + 178: 209, # '≤' + 179: 210, # '≥' + 180: 211, # 'і' + 181: 212, # 'µ' + 182: 213, # 'ґ' + 183: 214, # 'Ј' + 184: 215, # 'Є' + 185: 216, # 'є' + 186: 217, # 'Ї' + 187: 218, # 'ї' + 188: 219, # 'Љ' + 189: 220, # 'љ' + 190: 221, # 'Њ' + 191: 222, # 'њ' + 192: 223, # 'ј' + 193: 224, # 'Ѕ' + 194: 225, # '¬' + 195: 226, # '√' + 196: 227, # 'ƒ' + 197: 228, # '≈' + 198: 229, # '∆' + 199: 230, # '«' + 200: 231, # '»' + 201: 232, # '…' + 202: 233, # '\xa0' + 203: 234, # 'Ћ' + 204: 235, # 'ћ' + 205: 236, # 'Ќ' + 206: 237, # 'ќ' + 207: 238, # 'ѕ' + 208: 239, # '–' + 209: 240, # '—' + 210: 241, # '“' + 211: 242, # '”' + 212: 243, # '‘' + 213: 244, # '’' + 214: 245, # '÷' + 215: 246, # '„' + 216: 247, # 'Ў' + 217: 248, # 'ў' + 218: 249, # 'Џ' + 219: 250, # 'џ' + 220: 251, # '№' + 221: 252, # 'Ё' + 222: 68, # 'ё' + 223: 16, # 'я' + 224: 3, # 'а' + 225: 21, # 'б' + 226: 10, # 'в' + 227: 19, # 'г' + 228: 13, # 'д' + 229: 2, # 'е' + 230: 24, # 'ж' + 231: 20, # 'з' + 232: 4, # 'и' + 233: 23, # 'й' + 234: 11, # 'к' + 235: 8, # 'л' + 236: 12, # 'м' + 237: 5, # 'н' + 238: 1, # 'о' + 239: 15, # 'п' + 240: 9, # 'р' + 241: 7, # 'с' + 242: 6, # 'т' + 243: 14, # 'у' + 244: 39, # 'ф' + 245: 26, # 'х' + 246: 28, # 'ц' + 247: 22, # 'ч' + 248: 25, # 'ш' + 249: 29, # 'щ' + 250: 54, # 'ъ' + 251: 18, # 'ы' + 252: 17, # 'ь' + 253: 30, # 'э' + 254: 27, # 'ю' + 255: 255, # '€' +} + +MACCYRILLIC_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='MacCyrillic', + language='Russian', + char_to_order_map=MACCYRILLIC_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + +ISO_8859_5_RUSSIAN_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 142, # 'A' + 66: 143, # 'B' + 67: 144, # 'C' + 68: 145, # 'D' + 69: 146, # 'E' + 70: 147, # 'F' + 71: 148, # 'G' + 72: 149, # 'H' + 73: 150, # 'I' + 74: 151, # 'J' + 75: 152, # 'K' + 76: 74, # 'L' + 77: 153, # 'M' + 78: 75, # 'N' + 79: 154, # 'O' + 80: 155, # 'P' + 81: 156, # 'Q' + 82: 157, # 'R' + 83: 158, # 'S' + 84: 159, # 'T' + 85: 160, # 'U' + 86: 161, # 'V' + 87: 162, # 'W' + 88: 163, # 'X' + 89: 164, # 'Y' + 90: 165, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 71, # 'a' + 98: 172, # 'b' + 99: 66, # 'c' + 100: 173, # 'd' + 101: 65, # 'e' + 102: 174, # 'f' + 103: 76, # 'g' + 104: 175, # 'h' + 105: 64, # 'i' + 106: 176, # 'j' + 107: 177, # 'k' + 108: 77, # 'l' + 109: 72, # 'm' + 110: 178, # 'n' + 111: 69, # 'o' + 112: 67, # 'p' + 113: 179, # 'q' + 114: 78, # 'r' + 115: 73, # 's' + 116: 180, # 't' + 117: 181, # 'u' + 118: 79, # 'v' + 119: 182, # 'w' + 120: 183, # 'x' + 121: 184, # 'y' + 122: 185, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 191, # '\x80' + 129: 192, # '\x81' + 130: 193, # '\x82' + 131: 194, # '\x83' + 132: 195, # '\x84' + 133: 196, # '\x85' + 134: 197, # '\x86' + 135: 198, # '\x87' + 136: 199, # '\x88' + 137: 200, # '\x89' + 138: 201, # '\x8a' + 139: 202, # '\x8b' + 140: 203, # '\x8c' + 141: 204, # '\x8d' + 142: 205, # '\x8e' + 143: 206, # '\x8f' + 144: 207, # '\x90' + 145: 208, # '\x91' + 146: 209, # '\x92' + 147: 210, # '\x93' + 148: 211, # '\x94' + 149: 212, # '\x95' + 150: 213, # '\x96' + 151: 214, # '\x97' + 152: 215, # '\x98' + 153: 216, # '\x99' + 154: 217, # '\x9a' + 155: 218, # '\x9b' + 156: 219, # '\x9c' + 157: 220, # '\x9d' + 158: 221, # '\x9e' + 159: 222, # '\x9f' + 160: 223, # '\xa0' + 161: 224, # 'Ё' + 162: 225, # 'Ђ' + 163: 226, # 'Ѓ' + 164: 227, # 'Є' + 165: 228, # 'Ѕ' + 166: 229, # 'І' + 167: 230, # 'Ї' + 168: 231, # 'Ј' + 169: 232, # 'Љ' + 170: 233, # 'Њ' + 171: 234, # 'Ћ' + 172: 235, # 'Ќ' + 173: 236, # '\xad' + 174: 237, # 'Ў' + 175: 238, # 'Џ' + 176: 37, # 'А' + 177: 44, # 'Б' + 178: 33, # 'В' + 179: 46, # 'Г' + 180: 41, # 'Д' + 181: 48, # 'Е' + 182: 56, # 'Ж' + 183: 51, # 'З' + 184: 42, # 'И' + 185: 60, # 'Й' + 186: 36, # 'К' + 187: 49, # 'Л' + 188: 38, # 'М' + 189: 31, # 'Н' + 190: 34, # 'О' + 191: 35, # 'П' + 192: 45, # 'Р' + 193: 32, # 'С' + 194: 40, # 'Т' + 195: 52, # 'У' + 196: 53, # 'Ф' + 197: 55, # 'Х' + 198: 58, # 'Ц' + 199: 50, # 'Ч' + 200: 57, # 'Ш' + 201: 63, # 'Щ' + 202: 70, # 'Ъ' + 203: 62, # 'Ы' + 204: 61, # 'Ь' + 205: 47, # 'Э' + 206: 59, # 'Ю' + 207: 43, # 'Я' + 208: 3, # 'а' + 209: 21, # 'б' + 210: 10, # 'в' + 211: 19, # 'г' + 212: 13, # 'д' + 213: 2, # 'е' + 214: 24, # 'ж' + 215: 20, # 'з' + 216: 4, # 'и' + 217: 23, # 'й' + 218: 11, # 'к' + 219: 8, # 'л' + 220: 12, # 'м' + 221: 5, # 'н' + 222: 1, # 'о' + 223: 15, # 'п' + 224: 9, # 'р' + 225: 7, # 'с' + 226: 6, # 'т' + 227: 14, # 'у' + 228: 39, # 'ф' + 229: 26, # 'х' + 230: 28, # 'ц' + 231: 22, # 'ч' + 232: 25, # 'ш' + 233: 29, # 'щ' + 234: 54, # 'ъ' + 235: 18, # 'ы' + 236: 17, # 'ь' + 237: 30, # 'э' + 238: 27, # 'ю' + 239: 16, # 'я' + 240: 239, # '№' + 241: 68, # 'ё' + 242: 240, # 'ђ' + 243: 241, # 'ѓ' + 244: 242, # 'є' + 245: 243, # 'ѕ' + 246: 244, # 'і' + 247: 245, # 'ї' + 248: 246, # 'ј' + 249: 247, # 'љ' + 250: 248, # 'њ' + 251: 249, # 'ћ' + 252: 250, # 'ќ' + 253: 251, # '§' + 254: 252, # 'ў' + 255: 255, # 'џ' +} + +ISO_8859_5_RUSSIAN_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-5', + language='Russian', + char_to_order_map=ISO_8859_5_RUSSIAN_CHAR_TO_ORDER, + language_model=RUSSIAN_LANG_MODEL, + typical_positive_ratio=0.976601, + keep_ascii_letters=False, + alphabet='ЁАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюяё') + diff --git a/lib/chardet/langthaimodel.py b/lib/chardet/langthaimodel.py new file mode 100644 index 0000000..d0191f2 --- /dev/null +++ b/lib/chardet/langthaimodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +THAI_LANG_MODEL = { + 5: { # 'ก' + 5: 2, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 3, # 'ฎ' + 57: 2, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 2, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 2, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 3, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 1, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 30: { # 'ข' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 0, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 2, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 2, # 'ี' + 40: 3, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 24: { # 'ค' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 2, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 2, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 3, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 8: { # 'ง' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 1, # 'ฉ' + 34: 2, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 2, # 'ศ' + 46: 1, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 3, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 26: { # 'จ' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 3, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 52: { # 'ฉ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 3, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 1, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 34: { # 'ช' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 1, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 51: { # 'ซ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 3, # 'ึ' + 27: 2, # 'ื' + 32: 1, # 'ุ' + 35: 1, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 1, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 47: { # 'ญ' + 5: 1, # 'ก' + 30: 1, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 3, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 2, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 58: { # 'ฎ' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 1, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 57: { # 'ฏ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 49: { # 'ฐ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 53: { # 'ฑ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 55: { # 'ฒ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 43: { # 'ณ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 3, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 3, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 3, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 20: { # 'ด' + 5: 2, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 2, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 1, # 'ึ' + 27: 2, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 2, # 'ๆ' + 37: 2, # '็' + 6: 1, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 19: { # 'ต' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 2, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 2, # 'ภ' + 9: 1, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 1, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 2, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 44: { # 'ถ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 1, # 'ี' + 40: 3, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 14: { # 'ท' + 5: 1, # 'ก' + 30: 1, # 'ข' + 24: 3, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 3, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 1, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 3, # 'ศ' + 46: 1, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 1, # 'ื' + 32: 3, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 48: { # 'ธ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 2, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 2, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 3: { # 'น' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 2, # 'ถ' + 14: 3, # 'ท' + 48: 3, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 1, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 3, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 3, # 'โ' + 29: 3, # 'ใ' + 33: 3, # 'ไ' + 50: 2, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 17: { # 'บ' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 1, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 2, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 2, # 'ื' + 32: 3, # 'ุ' + 35: 2, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 25: { # 'ป' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 1, # 'ฎ' + 57: 3, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 1, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 1, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 2, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 1, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 39: { # 'ผ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 1, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 0, # 'ุ' + 35: 3, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 1, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 62: { # 'ฝ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 1, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 1, # 'ี' + 40: 2, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 2, # '่' + 7: 1, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 31: { # 'พ' + 5: 1, # 'ก' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 1, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 2, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 1, # 'ึ' + 27: 3, # 'ื' + 32: 1, # 'ุ' + 35: 2, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 1, # '็' + 6: 0, # '่' + 7: 1, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 54: { # 'ฟ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 1, # 'ื' + 32: 1, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 45: { # 'ภ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 2, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 9: { # 'ม' + 5: 2, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 3, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 2, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 1, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 2, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 16: { # 'ย' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 2, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 1, # 'ึ' + 27: 2, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 2, # 'ๆ' + 37: 1, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 2: { # 'ร' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 2, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 3, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 3, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 3, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 2, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 2, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 1, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 3, # 'เ' + 28: 3, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 3, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 61: { # 'ฤ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 2, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 15: { # 'ล' + 5: 2, # 'ก' + 30: 3, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 3, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 2, # 'ฯ' + 22: 3, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 2, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 2, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 12: { # 'ว' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 3, # 'ิ' + 13: 2, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 2, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 42: { # 'ศ' + 5: 1, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 2, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 2, # 'ิ' + 13: 0, # 'ี' + 40: 3, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 2, # 'ู' + 11: 0, # 'เ' + 28: 1, # 'แ' + 41: 0, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 46: { # 'ษ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 2, # 'ฎ' + 57: 1, # 'ฏ' + 49: 2, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 0, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 2, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 18: { # 'ส' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 3, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 2, # 'ภ' + 9: 3, # 'ม' + 16: 1, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 3, # 'ำ' + 23: 3, # 'ิ' + 13: 3, # 'ี' + 40: 2, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 3, # 'ู' + 11: 2, # 'เ' + 28: 0, # 'แ' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 1, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 21: { # 'ห' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 1, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 0, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 0, # 'ำ' + 23: 1, # 'ิ' + 13: 1, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 1, # 'ุ' + 35: 1, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 3, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 4: { # 'อ' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 2, # 'ะ' + 10: 3, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 2, # 'ิ' + 13: 3, # 'ี' + 40: 0, # 'ึ' + 27: 3, # 'ื' + 32: 3, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 1, # '็' + 6: 2, # '่' + 7: 2, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 63: { # 'ฯ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 22: { # 'ะ' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 1, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 10: { # 'ั' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 3, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 2, # 'ฐ' + 53: 0, # 'ฑ' + 55: 3, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 1: { # 'า' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 1, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 2, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 1, # 'ฝ' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 3, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 3, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 36: { # 'ำ' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 23: { # 'ิ' + 5: 3, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 3, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 2, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 3, # 'ศ' + 46: 2, # 'ษ' + 18: 2, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 2, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 13: { # 'ี' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 1, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 2, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 40: { # 'ึ' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 3, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 1, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 27: { # 'ื' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 32: { # 'ุ' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 3, # 'ค' + 8: 3, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 1, # 'ฒ' + 43: 3, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 2, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 1, # 'ภ' + 9: 3, # 'ม' + 16: 1, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 1, # 'ว' + 42: 1, # 'ศ' + 46: 2, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 2, # '้' + 38: 1, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 35: { # 'ู' + 5: 3, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 2, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 2, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 2, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 2, # 'น' + 17: 0, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 1, # 'แ' + 41: 1, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 3, # '่' + 7: 3, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 11: { # 'เ' + 5: 3, # 'ก' + 30: 3, # 'ข' + 24: 3, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 3, # 'ฉ' + 34: 3, # 'ช' + 51: 2, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 1, # 'ณ' + 20: 3, # 'ด' + 19: 3, # 'ต' + 44: 1, # 'ถ' + 14: 3, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 3, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 3, # 'พ' + 54: 1, # 'ฟ' + 45: 3, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 3, # 'ว' + 42: 2, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 28: { # 'แ' + 5: 3, # 'ก' + 30: 2, # 'ข' + 24: 2, # 'ค' + 8: 1, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 3, # 'ต' + 44: 2, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 2, # 'ป' + 39: 3, # 'ผ' + 62: 0, # 'ฝ' + 31: 2, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 41: { # 'โ' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 1, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 1, # 'ภ' + 9: 1, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 3, # 'ล' + 12: 0, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 0, # 'ห' + 4: 2, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 29: { # 'ใ' + 5: 2, # 'ก' + 30: 0, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 3, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 3, # 'ส' + 21: 3, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 33: { # 'ไ' + 5: 1, # 'ก' + 30: 2, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 3, # 'ด' + 19: 1, # 'ต' + 44: 0, # 'ถ' + 14: 3, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 1, # 'บ' + 25: 3, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 2, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 0, # 'ย' + 2: 3, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 2, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 50: { # 'ๆ' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 37: { # '็' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 2, # 'ง' + 26: 3, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 1, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 0, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 3, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 1, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 2, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 0, # 'ห' + 4: 1, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 1, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 6: { # '่' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 1, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 1, # 'ธ' + 3: 3, # 'น' + 17: 1, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 1, # 'ฝ' + 31: 1, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 3, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 2, # 'ล' + 12: 3, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 1, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 1, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 3, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 1, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 7: { # '้' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 2, # 'ค' + 8: 3, # 'ง' + 26: 2, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 1, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 1, # 'ด' + 19: 2, # 'ต' + 44: 1, # 'ถ' + 14: 2, # 'ท' + 48: 0, # 'ธ' + 3: 3, # 'น' + 17: 2, # 'บ' + 25: 2, # 'ป' + 39: 2, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 3, # 'ม' + 16: 2, # 'ย' + 2: 2, # 'ร' + 61: 0, # 'ฤ' + 15: 1, # 'ล' + 12: 3, # 'ว' + 42: 1, # 'ศ' + 46: 0, # 'ษ' + 18: 2, # 'ส' + 21: 2, # 'ห' + 4: 3, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 3, # 'า' + 36: 2, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 2, # 'ใ' + 33: 2, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 38: { # '์' + 5: 2, # 'ก' + 30: 1, # 'ข' + 24: 1, # 'ค' + 8: 0, # 'ง' + 26: 1, # 'จ' + 52: 0, # 'ฉ' + 34: 1, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 2, # 'ด' + 19: 1, # 'ต' + 44: 1, # 'ถ' + 14: 1, # 'ท' + 48: 0, # 'ธ' + 3: 1, # 'น' + 17: 1, # 'บ' + 25: 1, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 1, # 'พ' + 54: 1, # 'ฟ' + 45: 0, # 'ภ' + 9: 2, # 'ม' + 16: 0, # 'ย' + 2: 1, # 'ร' + 61: 1, # 'ฤ' + 15: 1, # 'ล' + 12: 1, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 1, # 'ส' + 21: 1, # 'ห' + 4: 2, # 'อ' + 63: 1, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 2, # 'เ' + 28: 2, # 'แ' + 41: 1, # 'โ' + 29: 1, # 'ใ' + 33: 1, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 0, # '๑' + 59: 0, # '๒' + 60: 0, # '๕' + }, + 56: { # '๑' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 2, # '๑' + 59: 1, # '๒' + 60: 1, # '๕' + }, + 59: { # '๒' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 1, # '๑' + 59: 1, # '๒' + 60: 3, # '๕' + }, + 60: { # '๕' + 5: 0, # 'ก' + 30: 0, # 'ข' + 24: 0, # 'ค' + 8: 0, # 'ง' + 26: 0, # 'จ' + 52: 0, # 'ฉ' + 34: 0, # 'ช' + 51: 0, # 'ซ' + 47: 0, # 'ญ' + 58: 0, # 'ฎ' + 57: 0, # 'ฏ' + 49: 0, # 'ฐ' + 53: 0, # 'ฑ' + 55: 0, # 'ฒ' + 43: 0, # 'ณ' + 20: 0, # 'ด' + 19: 0, # 'ต' + 44: 0, # 'ถ' + 14: 0, # 'ท' + 48: 0, # 'ธ' + 3: 0, # 'น' + 17: 0, # 'บ' + 25: 0, # 'ป' + 39: 0, # 'ผ' + 62: 0, # 'ฝ' + 31: 0, # 'พ' + 54: 0, # 'ฟ' + 45: 0, # 'ภ' + 9: 0, # 'ม' + 16: 0, # 'ย' + 2: 0, # 'ร' + 61: 0, # 'ฤ' + 15: 0, # 'ล' + 12: 0, # 'ว' + 42: 0, # 'ศ' + 46: 0, # 'ษ' + 18: 0, # 'ส' + 21: 0, # 'ห' + 4: 0, # 'อ' + 63: 0, # 'ฯ' + 22: 0, # 'ะ' + 10: 0, # 'ั' + 1: 0, # 'า' + 36: 0, # 'ำ' + 23: 0, # 'ิ' + 13: 0, # 'ี' + 40: 0, # 'ึ' + 27: 0, # 'ื' + 32: 0, # 'ุ' + 35: 0, # 'ู' + 11: 0, # 'เ' + 28: 0, # 'แ' + 41: 0, # 'โ' + 29: 0, # 'ใ' + 33: 0, # 'ไ' + 50: 0, # 'ๆ' + 37: 0, # '็' + 6: 0, # '่' + 7: 0, # '้' + 38: 0, # '์' + 56: 2, # '๑' + 59: 1, # '๒' + 60: 0, # '๕' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +TIS_620_THAI_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 254, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 254, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 253, # ' ' + 33: 253, # '!' + 34: 253, # '"' + 35: 253, # '#' + 36: 253, # '$' + 37: 253, # '%' + 38: 253, # '&' + 39: 253, # "'" + 40: 253, # '(' + 41: 253, # ')' + 42: 253, # '*' + 43: 253, # '+' + 44: 253, # ',' + 45: 253, # '-' + 46: 253, # '.' + 47: 253, # '/' + 48: 252, # '0' + 49: 252, # '1' + 50: 252, # '2' + 51: 252, # '3' + 52: 252, # '4' + 53: 252, # '5' + 54: 252, # '6' + 55: 252, # '7' + 56: 252, # '8' + 57: 252, # '9' + 58: 253, # ':' + 59: 253, # ';' + 60: 253, # '<' + 61: 253, # '=' + 62: 253, # '>' + 63: 253, # '?' + 64: 253, # '@' + 65: 182, # 'A' + 66: 106, # 'B' + 67: 107, # 'C' + 68: 100, # 'D' + 69: 183, # 'E' + 70: 184, # 'F' + 71: 185, # 'G' + 72: 101, # 'H' + 73: 94, # 'I' + 74: 186, # 'J' + 75: 187, # 'K' + 76: 108, # 'L' + 77: 109, # 'M' + 78: 110, # 'N' + 79: 111, # 'O' + 80: 188, # 'P' + 81: 189, # 'Q' + 82: 190, # 'R' + 83: 89, # 'S' + 84: 95, # 'T' + 85: 112, # 'U' + 86: 113, # 'V' + 87: 191, # 'W' + 88: 192, # 'X' + 89: 193, # 'Y' + 90: 194, # 'Z' + 91: 253, # '[' + 92: 253, # '\\' + 93: 253, # ']' + 94: 253, # '^' + 95: 253, # '_' + 96: 253, # '`' + 97: 64, # 'a' + 98: 72, # 'b' + 99: 73, # 'c' + 100: 114, # 'd' + 101: 74, # 'e' + 102: 115, # 'f' + 103: 116, # 'g' + 104: 102, # 'h' + 105: 81, # 'i' + 106: 201, # 'j' + 107: 117, # 'k' + 108: 90, # 'l' + 109: 103, # 'm' + 110: 78, # 'n' + 111: 82, # 'o' + 112: 96, # 'p' + 113: 202, # 'q' + 114: 91, # 'r' + 115: 79, # 's' + 116: 84, # 't' + 117: 104, # 'u' + 118: 105, # 'v' + 119: 97, # 'w' + 120: 98, # 'x' + 121: 92, # 'y' + 122: 203, # 'z' + 123: 253, # '{' + 124: 253, # '|' + 125: 253, # '}' + 126: 253, # '~' + 127: 253, # '\x7f' + 128: 209, # '\x80' + 129: 210, # '\x81' + 130: 211, # '\x82' + 131: 212, # '\x83' + 132: 213, # '\x84' + 133: 88, # '\x85' + 134: 214, # '\x86' + 135: 215, # '\x87' + 136: 216, # '\x88' + 137: 217, # '\x89' + 138: 218, # '\x8a' + 139: 219, # '\x8b' + 140: 220, # '\x8c' + 141: 118, # '\x8d' + 142: 221, # '\x8e' + 143: 222, # '\x8f' + 144: 223, # '\x90' + 145: 224, # '\x91' + 146: 99, # '\x92' + 147: 85, # '\x93' + 148: 83, # '\x94' + 149: 225, # '\x95' + 150: 226, # '\x96' + 151: 227, # '\x97' + 152: 228, # '\x98' + 153: 229, # '\x99' + 154: 230, # '\x9a' + 155: 231, # '\x9b' + 156: 232, # '\x9c' + 157: 233, # '\x9d' + 158: 234, # '\x9e' + 159: 235, # '\x9f' + 160: 236, # None + 161: 5, # 'ก' + 162: 30, # 'ข' + 163: 237, # 'ฃ' + 164: 24, # 'ค' + 165: 238, # 'ฅ' + 166: 75, # 'ฆ' + 167: 8, # 'ง' + 168: 26, # 'จ' + 169: 52, # 'ฉ' + 170: 34, # 'ช' + 171: 51, # 'ซ' + 172: 119, # 'ฌ' + 173: 47, # 'ญ' + 174: 58, # 'ฎ' + 175: 57, # 'ฏ' + 176: 49, # 'ฐ' + 177: 53, # 'ฑ' + 178: 55, # 'ฒ' + 179: 43, # 'ณ' + 180: 20, # 'ด' + 181: 19, # 'ต' + 182: 44, # 'ถ' + 183: 14, # 'ท' + 184: 48, # 'ธ' + 185: 3, # 'น' + 186: 17, # 'บ' + 187: 25, # 'ป' + 188: 39, # 'ผ' + 189: 62, # 'ฝ' + 190: 31, # 'พ' + 191: 54, # 'ฟ' + 192: 45, # 'ภ' + 193: 9, # 'ม' + 194: 16, # 'ย' + 195: 2, # 'ร' + 196: 61, # 'ฤ' + 197: 15, # 'ล' + 198: 239, # 'ฦ' + 199: 12, # 'ว' + 200: 42, # 'ศ' + 201: 46, # 'ษ' + 202: 18, # 'ส' + 203: 21, # 'ห' + 204: 76, # 'ฬ' + 205: 4, # 'อ' + 206: 66, # 'ฮ' + 207: 63, # 'ฯ' + 208: 22, # 'ะ' + 209: 10, # 'ั' + 210: 1, # 'า' + 211: 36, # 'ำ' + 212: 23, # 'ิ' + 213: 13, # 'ี' + 214: 40, # 'ึ' + 215: 27, # 'ื' + 216: 32, # 'ุ' + 217: 35, # 'ู' + 218: 86, # 'ฺ' + 219: 240, # None + 220: 241, # None + 221: 242, # None + 222: 243, # None + 223: 244, # '฿' + 224: 11, # 'เ' + 225: 28, # 'แ' + 226: 41, # 'โ' + 227: 29, # 'ใ' + 228: 33, # 'ไ' + 229: 245, # 'ๅ' + 230: 50, # 'ๆ' + 231: 37, # '็' + 232: 6, # '่' + 233: 7, # '้' + 234: 67, # '๊' + 235: 77, # '๋' + 236: 38, # '์' + 237: 93, # 'ํ' + 238: 246, # '๎' + 239: 247, # '๏' + 240: 68, # '๐' + 241: 56, # '๑' + 242: 59, # '๒' + 243: 65, # '๓' + 244: 69, # '๔' + 245: 60, # '๕' + 246: 70, # '๖' + 247: 80, # '๗' + 248: 71, # '๘' + 249: 87, # '๙' + 250: 248, # '๚' + 251: 249, # '๛' + 252: 250, # None + 253: 251, # None + 254: 252, # None + 255: 253, # None +} + +TIS_620_THAI_MODEL = SingleByteCharSetModel(charset_name='TIS-620', + language='Thai', + char_to_order_map=TIS_620_THAI_CHAR_TO_ORDER, + language_model=THAI_LANG_MODEL, + typical_positive_ratio=0.926386, + keep_ascii_letters=False, + alphabet='กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛') + diff --git a/lib/chardet/langturkishmodel.py b/lib/chardet/langturkishmodel.py new file mode 100644 index 0000000..8ba9322 --- /dev/null +++ b/lib/chardet/langturkishmodel.py @@ -0,0 +1,4383 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from chardet.sbcharsetprober import SingleByteCharSetModel + + +# 3: Positive +# 2: Likely +# 1: Unlikely +# 0: Negative + +TURKISH_LANG_MODEL = { + 23: { # 'A' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 37: { # 'B' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 47: { # 'C' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 39: { # 'D' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 0, # 'ş' + }, + 29: { # 'E' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 52: { # 'F' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 1, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 2, # 'ş' + }, + 36: { # 'G' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 2, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 1, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 45: { # 'H' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 2, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 2, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 53: { # 'I' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 60: { # 'J' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 16: { # 'K' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 1, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 49: { # 'L' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 2, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 20: { # 'M' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 0, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 46: { # 'N' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 42: { # 'O' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 2, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 48: { # 'P' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 44: { # 'R' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, + 35: { # 'S' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 1, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 2, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 31: { # 'T' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 2, # 't' + 14: 2, # 'u' + 32: 1, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 51: { # 'U' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 1, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 38: { # 'V' + 23: 1, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 2, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 1, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 62: { # 'W' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 43: { # 'Y' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 0, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 1, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 1, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 56: { # 'Z' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 1: { # 'a' + 23: 3, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 1, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 21: { # 'b' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 3, # 'g' + 25: 1, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 2, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 28: { # 'c' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 2, # 'T' + 51: 2, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 3, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 1, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 1, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 2, # 'ş' + }, + 12: { # 'd' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 2: { # 'e' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 2, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 18: { # 'f' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 1, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 1, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 27: { # 'g' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 25: { # 'h' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 3: { # 'i' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 1, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 3, # 'g' + 25: 1, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 1, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 1, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 24: { # 'j' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 2, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 10: { # 'k' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 2, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 3, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 5: { # 'l' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 1, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 2, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 13: { # 'm' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 2, # 'u' + 32: 2, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 4: { # 'n' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 3, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 15: { # 'o' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 2, # 'L' + 20: 0, # 'M' + 46: 2, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ğ' + 41: 2, # 'İ' + 6: 3, # 'ı' + 40: 2, # 'Ş' + 19: 2, # 'ş' + }, + 26: { # 'p' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 1, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 7: { # 'r' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 1, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 1, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 3, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 8: { # 's' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 2, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 9: { # 't' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 2, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 2, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 14: { # 'u' + 23: 3, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 2, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 3, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 2, # 'Z' + 1: 2, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 2, # 'e' + 18: 2, # 'f' + 27: 3, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 2, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 32: { # 'v' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 1, # 'k' + 5: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 57: { # 'w' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 1, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 1, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 2, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 58: { # 'x' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 2, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 11: { # 'y' + 23: 1, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 2, # 'r' + 8: 1, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 3, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 22: { # 'z' + 23: 2, # 'A' + 37: 2, # 'B' + 47: 1, # 'C' + 39: 2, # 'D' + 29: 3, # 'E' + 52: 1, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 2, # 'N' + 42: 2, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 3, # 'T' + 51: 2, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 1, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 2, # 'e' + 18: 3, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 3, # 'y' + 22: 2, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 3, # 'ı' + 40: 1, # 'Ş' + 19: 2, # 'ş' + }, + 63: { # '·' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 54: { # 'Ç' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 1, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 0, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 3, # 'i' + 24: 0, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 2, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 2, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 2, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 50: { # 'Ö' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 2, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 2, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 1, # 'N' + 42: 2, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 1, # 'f' + 27: 1, # 'g' + 25: 1, # 'h' + 3: 2, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 2, # 'p' + 7: 3, # 'r' + 8: 1, # 's' + 9: 2, # 't' + 14: 0, # 'u' + 32: 1, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 2, # 'ü' + 30: 1, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 55: { # 'Ü' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 1, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 1, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 1, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 1, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 1, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 0, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 59: { # 'â' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 0, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 2, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 2, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 0, # 'ş' + }, + 33: { # 'ç' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 3, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 0, # 'Z' + 1: 0, # 'a' + 21: 3, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 2, # 'f' + 27: 1, # 'g' + 25: 3, # 'h' + 3: 3, # 'i' + 24: 0, # 'j' + 10: 3, # 'k' + 5: 0, # 'l' + 13: 0, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 3, # 't' + 14: 0, # 'u' + 32: 2, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 1, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 61: { # 'î' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 0, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 0, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 2, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 1, # 'j' + 10: 0, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 1, # 'n' + 15: 0, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 1, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 1, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 1, # 'î' + 34: 0, # 'ö' + 17: 0, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 1, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 34: { # 'ö' + 23: 0, # 'A' + 37: 1, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 1, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 1, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 2, # 'h' + 3: 1, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 2, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 0, # 'r' + 8: 3, # 's' + 9: 1, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 1, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 2, # 'ğ' + 41: 1, # 'İ' + 6: 1, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 17: { # 'ü' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 0, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 1, # 'J' + 16: 1, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 0, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 0, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 0, # 'c' + 12: 1, # 'd' + 2: 3, # 'e' + 18: 1, # 'f' + 27: 2, # 'g' + 25: 0, # 'h' + 3: 1, # 'i' + 24: 1, # 'j' + 10: 2, # 'k' + 5: 3, # 'l' + 13: 2, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 2, # 'p' + 7: 2, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 3, # 'u' + 32: 1, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 2, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 30: { # 'ğ' + 23: 0, # 'A' + 37: 2, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 1, # 'M' + 46: 2, # 'N' + 42: 2, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 0, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 2, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 0, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 2, # 'e' + 18: 0, # 'f' + 27: 0, # 'g' + 25: 0, # 'h' + 3: 0, # 'i' + 24: 3, # 'j' + 10: 1, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 1, # 'o' + 26: 0, # 'p' + 7: 1, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 2, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 2, # 'İ' + 6: 2, # 'ı' + 40: 2, # 'Ş' + 19: 1, # 'ş' + }, + 41: { # 'İ' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 2, # 'G' + 45: 2, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 0, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 0, # 'Z' + 1: 1, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 2, # 'd' + 2: 1, # 'e' + 18: 0, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 2, # 'i' + 24: 2, # 'j' + 10: 2, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 1, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 2, # 't' + 14: 0, # 'u' + 32: 0, # 'v' + 57: 1, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 1, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 1, # 'ö' + 17: 1, # 'ü' + 30: 2, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 1, # 'ş' + }, + 6: { # 'ı' + 23: 2, # 'A' + 37: 0, # 'B' + 47: 0, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 2, # 'J' + 16: 3, # 'K' + 49: 0, # 'L' + 20: 3, # 'M' + 46: 1, # 'N' + 42: 0, # 'O' + 48: 0, # 'P' + 44: 0, # 'R' + 35: 0, # 'S' + 31: 2, # 'T' + 51: 0, # 'U' + 38: 0, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 3, # 'a' + 21: 2, # 'b' + 28: 1, # 'c' + 12: 3, # 'd' + 2: 3, # 'e' + 18: 3, # 'f' + 27: 3, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 3, # 'j' + 10: 3, # 'k' + 5: 3, # 'l' + 13: 3, # 'm' + 4: 3, # 'n' + 15: 0, # 'o' + 26: 3, # 'p' + 7: 3, # 'r' + 8: 3, # 's' + 9: 3, # 't' + 14: 3, # 'u' + 32: 3, # 'v' + 57: 1, # 'w' + 58: 1, # 'x' + 11: 3, # 'y' + 22: 0, # 'z' + 63: 1, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 2, # 'ç' + 61: 0, # 'î' + 34: 0, # 'ö' + 17: 3, # 'ü' + 30: 0, # 'ğ' + 41: 0, # 'İ' + 6: 3, # 'ı' + 40: 0, # 'Ş' + 19: 0, # 'ş' + }, + 40: { # 'Ş' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 1, # 'D' + 29: 1, # 'E' + 52: 0, # 'F' + 36: 1, # 'G' + 45: 2, # 'H' + 53: 1, # 'I' + 60: 0, # 'J' + 16: 0, # 'K' + 49: 0, # 'L' + 20: 2, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 2, # 'P' + 44: 2, # 'R' + 35: 1, # 'S' + 31: 1, # 'T' + 51: 0, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 2, # 'Y' + 56: 1, # 'Z' + 1: 0, # 'a' + 21: 2, # 'b' + 28: 0, # 'c' + 12: 2, # 'd' + 2: 0, # 'e' + 18: 3, # 'f' + 27: 0, # 'g' + 25: 2, # 'h' + 3: 3, # 'i' + 24: 2, # 'j' + 10: 1, # 'k' + 5: 0, # 'l' + 13: 1, # 'm' + 4: 3, # 'n' + 15: 2, # 'o' + 26: 0, # 'p' + 7: 3, # 'r' + 8: 2, # 's' + 9: 2, # 't' + 14: 1, # 'u' + 32: 3, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 2, # 'y' + 22: 0, # 'z' + 63: 0, # '·' + 54: 0, # 'Ç' + 50: 0, # 'Ö' + 55: 1, # 'Ü' + 59: 0, # 'â' + 33: 0, # 'ç' + 61: 0, # 'î' + 34: 2, # 'ö' + 17: 1, # 'ü' + 30: 2, # 'ğ' + 41: 0, # 'İ' + 6: 2, # 'ı' + 40: 1, # 'Ş' + 19: 2, # 'ş' + }, + 19: { # 'ş' + 23: 0, # 'A' + 37: 0, # 'B' + 47: 1, # 'C' + 39: 0, # 'D' + 29: 0, # 'E' + 52: 2, # 'F' + 36: 1, # 'G' + 45: 0, # 'H' + 53: 0, # 'I' + 60: 0, # 'J' + 16: 3, # 'K' + 49: 2, # 'L' + 20: 0, # 'M' + 46: 1, # 'N' + 42: 1, # 'O' + 48: 1, # 'P' + 44: 1, # 'R' + 35: 1, # 'S' + 31: 0, # 'T' + 51: 1, # 'U' + 38: 1, # 'V' + 62: 0, # 'W' + 43: 1, # 'Y' + 56: 0, # 'Z' + 1: 3, # 'a' + 21: 1, # 'b' + 28: 2, # 'c' + 12: 0, # 'd' + 2: 3, # 'e' + 18: 0, # 'f' + 27: 2, # 'g' + 25: 1, # 'h' + 3: 1, # 'i' + 24: 0, # 'j' + 10: 2, # 'k' + 5: 2, # 'l' + 13: 3, # 'm' + 4: 0, # 'n' + 15: 0, # 'o' + 26: 1, # 'p' + 7: 3, # 'r' + 8: 0, # 's' + 9: 0, # 't' + 14: 3, # 'u' + 32: 0, # 'v' + 57: 0, # 'w' + 58: 0, # 'x' + 11: 0, # 'y' + 22: 2, # 'z' + 63: 0, # '·' + 54: 1, # 'Ç' + 50: 2, # 'Ö' + 55: 0, # 'Ü' + 59: 0, # 'â' + 33: 1, # 'ç' + 61: 1, # 'î' + 34: 2, # 'ö' + 17: 0, # 'ü' + 30: 1, # 'ğ' + 41: 1, # 'İ' + 6: 1, # 'ı' + 40: 1, # 'Ş' + 19: 1, # 'ş' + }, +} + +# 255: Undefined characters that did not exist in training text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 +# 251: Control characters + +# Character Mapping Table(s): +ISO_8859_9_TURKISH_CHAR_TO_ORDER = { + 0: 255, # '\x00' + 1: 255, # '\x01' + 2: 255, # '\x02' + 3: 255, # '\x03' + 4: 255, # '\x04' + 5: 255, # '\x05' + 6: 255, # '\x06' + 7: 255, # '\x07' + 8: 255, # '\x08' + 9: 255, # '\t' + 10: 255, # '\n' + 11: 255, # '\x0b' + 12: 255, # '\x0c' + 13: 255, # '\r' + 14: 255, # '\x0e' + 15: 255, # '\x0f' + 16: 255, # '\x10' + 17: 255, # '\x11' + 18: 255, # '\x12' + 19: 255, # '\x13' + 20: 255, # '\x14' + 21: 255, # '\x15' + 22: 255, # '\x16' + 23: 255, # '\x17' + 24: 255, # '\x18' + 25: 255, # '\x19' + 26: 255, # '\x1a' + 27: 255, # '\x1b' + 28: 255, # '\x1c' + 29: 255, # '\x1d' + 30: 255, # '\x1e' + 31: 255, # '\x1f' + 32: 255, # ' ' + 33: 255, # '!' + 34: 255, # '"' + 35: 255, # '#' + 36: 255, # '$' + 37: 255, # '%' + 38: 255, # '&' + 39: 255, # "'" + 40: 255, # '(' + 41: 255, # ')' + 42: 255, # '*' + 43: 255, # '+' + 44: 255, # ',' + 45: 255, # '-' + 46: 255, # '.' + 47: 255, # '/' + 48: 255, # '0' + 49: 255, # '1' + 50: 255, # '2' + 51: 255, # '3' + 52: 255, # '4' + 53: 255, # '5' + 54: 255, # '6' + 55: 255, # '7' + 56: 255, # '8' + 57: 255, # '9' + 58: 255, # ':' + 59: 255, # ';' + 60: 255, # '<' + 61: 255, # '=' + 62: 255, # '>' + 63: 255, # '?' + 64: 255, # '@' + 65: 23, # 'A' + 66: 37, # 'B' + 67: 47, # 'C' + 68: 39, # 'D' + 69: 29, # 'E' + 70: 52, # 'F' + 71: 36, # 'G' + 72: 45, # 'H' + 73: 53, # 'I' + 74: 60, # 'J' + 75: 16, # 'K' + 76: 49, # 'L' + 77: 20, # 'M' + 78: 46, # 'N' + 79: 42, # 'O' + 80: 48, # 'P' + 81: 69, # 'Q' + 82: 44, # 'R' + 83: 35, # 'S' + 84: 31, # 'T' + 85: 51, # 'U' + 86: 38, # 'V' + 87: 62, # 'W' + 88: 65, # 'X' + 89: 43, # 'Y' + 90: 56, # 'Z' + 91: 255, # '[' + 92: 255, # '\\' + 93: 255, # ']' + 94: 255, # '^' + 95: 255, # '_' + 96: 255, # '`' + 97: 1, # 'a' + 98: 21, # 'b' + 99: 28, # 'c' + 100: 12, # 'd' + 101: 2, # 'e' + 102: 18, # 'f' + 103: 27, # 'g' + 104: 25, # 'h' + 105: 3, # 'i' + 106: 24, # 'j' + 107: 10, # 'k' + 108: 5, # 'l' + 109: 13, # 'm' + 110: 4, # 'n' + 111: 15, # 'o' + 112: 26, # 'p' + 113: 64, # 'q' + 114: 7, # 'r' + 115: 8, # 's' + 116: 9, # 't' + 117: 14, # 'u' + 118: 32, # 'v' + 119: 57, # 'w' + 120: 58, # 'x' + 121: 11, # 'y' + 122: 22, # 'z' + 123: 255, # '{' + 124: 255, # '|' + 125: 255, # '}' + 126: 255, # '~' + 127: 255, # '\x7f' + 128: 180, # '\x80' + 129: 179, # '\x81' + 130: 178, # '\x82' + 131: 177, # '\x83' + 132: 176, # '\x84' + 133: 175, # '\x85' + 134: 174, # '\x86' + 135: 173, # '\x87' + 136: 172, # '\x88' + 137: 171, # '\x89' + 138: 170, # '\x8a' + 139: 169, # '\x8b' + 140: 168, # '\x8c' + 141: 167, # '\x8d' + 142: 166, # '\x8e' + 143: 165, # '\x8f' + 144: 164, # '\x90' + 145: 163, # '\x91' + 146: 162, # '\x92' + 147: 161, # '\x93' + 148: 160, # '\x94' + 149: 159, # '\x95' + 150: 101, # '\x96' + 151: 158, # '\x97' + 152: 157, # '\x98' + 153: 156, # '\x99' + 154: 155, # '\x9a' + 155: 154, # '\x9b' + 156: 153, # '\x9c' + 157: 152, # '\x9d' + 158: 151, # '\x9e' + 159: 106, # '\x9f' + 160: 150, # '\xa0' + 161: 149, # '¡' + 162: 148, # '¢' + 163: 147, # '£' + 164: 146, # '¤' + 165: 145, # '¥' + 166: 144, # '¦' + 167: 100, # '§' + 168: 143, # '¨' + 169: 142, # '©' + 170: 141, # 'ª' + 171: 140, # '«' + 172: 139, # '¬' + 173: 138, # '\xad' + 174: 137, # '®' + 175: 136, # '¯' + 176: 94, # '°' + 177: 80, # '±' + 178: 93, # '²' + 179: 135, # '³' + 180: 105, # '´' + 181: 134, # 'µ' + 182: 133, # '¶' + 183: 63, # '·' + 184: 132, # '¸' + 185: 131, # '¹' + 186: 130, # 'º' + 187: 129, # '»' + 188: 128, # '¼' + 189: 127, # '½' + 190: 126, # '¾' + 191: 125, # '¿' + 192: 124, # 'À' + 193: 104, # 'Á' + 194: 73, # 'Â' + 195: 99, # 'Ã' + 196: 79, # 'Ä' + 197: 85, # 'Å' + 198: 123, # 'Æ' + 199: 54, # 'Ç' + 200: 122, # 'È' + 201: 98, # 'É' + 202: 92, # 'Ê' + 203: 121, # 'Ë' + 204: 120, # 'Ì' + 205: 91, # 'Í' + 206: 103, # 'Î' + 207: 119, # 'Ï' + 208: 68, # 'Ğ' + 209: 118, # 'Ñ' + 210: 117, # 'Ò' + 211: 97, # 'Ó' + 212: 116, # 'Ô' + 213: 115, # 'Õ' + 214: 50, # 'Ö' + 215: 90, # '×' + 216: 114, # 'Ø' + 217: 113, # 'Ù' + 218: 112, # 'Ú' + 219: 111, # 'Û' + 220: 55, # 'Ü' + 221: 41, # 'İ' + 222: 40, # 'Ş' + 223: 86, # 'ß' + 224: 89, # 'à' + 225: 70, # 'á' + 226: 59, # 'â' + 227: 78, # 'ã' + 228: 71, # 'ä' + 229: 82, # 'å' + 230: 88, # 'æ' + 231: 33, # 'ç' + 232: 77, # 'è' + 233: 66, # 'é' + 234: 84, # 'ê' + 235: 83, # 'ë' + 236: 110, # 'ì' + 237: 75, # 'í' + 238: 61, # 'î' + 239: 96, # 'ï' + 240: 30, # 'ğ' + 241: 67, # 'ñ' + 242: 109, # 'ò' + 243: 74, # 'ó' + 244: 87, # 'ô' + 245: 102, # 'õ' + 246: 34, # 'ö' + 247: 95, # '÷' + 248: 81, # 'ø' + 249: 108, # 'ù' + 250: 76, # 'ú' + 251: 72, # 'û' + 252: 17, # 'ü' + 253: 6, # 'ı' + 254: 19, # 'ş' + 255: 107, # 'ÿ' +} + +ISO_8859_9_TURKISH_MODEL = SingleByteCharSetModel(charset_name='ISO-8859-9', + language='Turkish', + char_to_order_map=ISO_8859_9_TURKISH_CHAR_TO_ORDER, + language_model=TURKISH_LANG_MODEL, + typical_positive_ratio=0.97029, + keep_ascii_letters=True, + alphabet='ABCDEFGHIJKLMNOPRSTUVYZabcdefghijklmnoprstuvyzÂÇÎÖÛÜâçîöûüĞğİıŞş') + diff --git a/lib/chardet/latin1prober.py b/lib/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/lib/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/lib/chardet/mbcharsetprober.py b/lib/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/lib/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/lib/chardet/mbcsgroupprober.py b/lib/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/lib/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/lib/chardet/mbcssm.py b/lib/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/lib/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/lib/chardet/metadata/__init__.py b/lib/chardet/metadata/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/chardet/metadata/__pycache__/__init__.cpython-312.pyc b/lib/chardet/metadata/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65828694920033c3d0a89b073c04abbff4d09d6e GIT binary patch literal 189 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 self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model.typical_positive_ratio) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/lib/chardet/sbcsgroupprober.py b/lib/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..bdeef4e --- /dev/null +++ b/lib/chardet/sbcsgroupprober.py @@ -0,0 +1,83 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .hebrewprober import HebrewProber +from .langbulgarianmodel import (ISO_8859_5_BULGARIAN_MODEL, + WINDOWS_1251_BULGARIAN_MODEL) +from .langgreekmodel import ISO_8859_7_GREEK_MODEL, WINDOWS_1253_GREEK_MODEL +from .langhebrewmodel import WINDOWS_1255_HEBREW_MODEL +# from .langhungarianmodel import (ISO_8859_2_HUNGARIAN_MODEL, +# WINDOWS_1250_HUNGARIAN_MODEL) +from .langrussianmodel import (IBM855_RUSSIAN_MODEL, IBM866_RUSSIAN_MODEL, + ISO_8859_5_RUSSIAN_MODEL, KOI8_R_RUSSIAN_MODEL, + MACCYRILLIC_RUSSIAN_MODEL, + WINDOWS_1251_RUSSIAN_MODEL) +from .langthaimodel import TIS_620_THAI_MODEL +from .langturkishmodel import ISO_8859_9_TURKISH_MODEL +from .sbcharsetprober import SingleByteCharSetProber + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, + False, hebrew_prober) + # TODO: See if using ISO-8859-8 Hebrew model works better here, since + # it's actually the visual one + visual_hebrew_prober = SingleByteCharSetProber(WINDOWS_1255_HEBREW_MODEL, + True, hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, + visual_hebrew_prober) + # TODO: ORDER MATTERS HERE. I changed the order vs what was in master + # and several tests failed that did not before. Some thought + # should be put into the ordering, and we should consider making + # order not matter here, because that is very counter-intuitive. + self.probers = [ + SingleByteCharSetProber(WINDOWS_1251_RUSSIAN_MODEL), + SingleByteCharSetProber(KOI8_R_RUSSIAN_MODEL), + SingleByteCharSetProber(ISO_8859_5_RUSSIAN_MODEL), + SingleByteCharSetProber(MACCYRILLIC_RUSSIAN_MODEL), + SingleByteCharSetProber(IBM866_RUSSIAN_MODEL), + SingleByteCharSetProber(IBM855_RUSSIAN_MODEL), + SingleByteCharSetProber(ISO_8859_7_GREEK_MODEL), + SingleByteCharSetProber(WINDOWS_1253_GREEK_MODEL), + SingleByteCharSetProber(ISO_8859_5_BULGARIAN_MODEL), + SingleByteCharSetProber(WINDOWS_1251_BULGARIAN_MODEL), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(ISO_8859_2_HUNGARIAN_MODEL), + # SingleByteCharSetProber(WINDOWS_1250_HUNGARIAN_MODEL), + SingleByteCharSetProber(TIS_620_THAI_MODEL), + SingleByteCharSetProber(ISO_8859_9_TURKISH_MODEL), + hebrew_prober, + logical_hebrew_prober, + visual_hebrew_prober, + ] + self.reset() diff --git a/lib/chardet/sjisprober.py b/lib/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/lib/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/lib/chardet/universaldetector.py b/lib/chardet/universaldetector.py new file mode 100644 index 0000000..055a8ac --- /dev/null +++ b/lib/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() <= logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + group_prober.charset_name, + group_prober.language, + group_prober.get_confidence()) + return self.result diff --git a/lib/chardet/utf8prober.py b/lib/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/lib/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/lib/chardet/version.py b/lib/chardet/version.py new file mode 100644 index 0000000..70369b9 --- /dev/null +++ b/lib/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "4.0.0" +VERSION = __version__.split('.') diff --git a/lib/flox/__init__.py b/lib/flox/__init__.py new file mode 100644 index 0000000..9e857ad --- /dev/null +++ b/lib/flox/__init__.py @@ -0,0 +1,337 @@ +import sys +import traceback +import os +import json +import time +import webbrowser +import urllib.parse +from datetime import date +import logging +import logging.handlers +from pathlib import Path +from typing import Union +from functools import wraps, cached_property +from tempfile import gettempdir + +from .launcher import Launcher +from .browser import Browser +from .settings import Settings + +PLUGIN_MANIFEST = 'plugin.json' +FLOW_LAUNCHER_DIR_NAME = "FlowLauncher" +SCOOP_FLOW_LAUNCHER_DIR_NAME = "flow-launcher" +WOX_DIR_NAME = "Wox" +FLOW_API = 'Flow.Launcher' +WOX_API = 'Wox' +APP_DIR = None +USER_DIR = None +LOCALAPPDATA = Path(os.getenv('LOCALAPPDATA')) +APPDATA = Path(os.getenv('APPDATA')) +FILE_PATH = os.path.dirname(os.path.abspath(__file__)) +CURRENT_WORKING_DIR = Path().cwd() +LAUNCHER_NOT_FOUND_MSG = f"Unable to locate Launcher directory\nCurrent working directory: {CURRENT_WORKING_DIR}" + + +launcher_dir = None +path = CURRENT_WORKING_DIR +if SCOOP_FLOW_LAUNCHER_DIR_NAME.lower() in str(path).lower(): + launcher_name = SCOOP_FLOW_LAUNCHER_DIR_NAME + API = FLOW_API +elif FLOW_LAUNCHER_DIR_NAME.lower() in str(path).lower(): + launcher_name = FLOW_LAUNCHER_DIR_NAME + API = FLOW_API +elif WOX_DIR_NAME.lower() in str(path).lower(): + launcher_name = WOX_DIR_NAME + API = WOX_API +else: + raise FileNotFoundError(LAUNCHER_NOT_FOUND_MSG) + +while True: + if len(path.parts) == 1: + raise FileNotFoundError(LAUNCHER_NOT_FOUND_MSG) + if path.joinpath('Settings').exists(): + USER_DIR = path + if USER_DIR.name == 'UserData': + APP_DIR = USER_DIR.parent + elif str(CURRENT_WORKING_DIR).startswith(str(APPDATA)): + APP_DIR = LOCALAPPDATA.joinpath(launcher_name) + else: + raise FileNotFoundError(LAUNCHER_NOT_FOUND_MSG) + break + + path = path.parent + +APP_ICONS = APP_DIR.joinpath("Images") +ICON_APP = APP_DIR.joinpath('app.png') +ICON_APP_ERROR = APP_DIR.joinpath(APP_ICONS, 'app_error.png') +ICON_BROWSER = APP_DIR.joinpath(APP_ICONS, 'browser.png') +ICON_CALCULATOR = APP_DIR.joinpath(APP_ICONS, 'calculator.png') +ICON_CANCEL = APP_DIR.joinpath(APP_ICONS, 'cancel.png') +ICON_CLOSE = APP_DIR.joinpath(APP_ICONS, 'close.png') +ICON_CMD = APP_DIR.joinpath(APP_ICONS, 'cmd.png') +ICON_COLOR = APP_DIR.joinpath('color.png') +ICON_CONTROL_PANEL = APP_DIR.joinpath('ControlPanel.png') +ICON_COPY = APP_DIR.joinpath('copy.png') +ICON_DELETE_FILE_FOLDER = APP_DIR.joinpath('deletefilefolder.png') +ICON_DISABLE = APP_DIR.joinpath('disable.png') +ICON_DOWN = APP_DIR.joinpath('down.png') +ICON_EXE = APP_DIR.joinpath('exe.png') +ICON_FILE = APP_DIR.joinpath('file.png') +ICON_FIND = APP_DIR.joinpath('find.png') +ICON_FOLDER = APP_DIR.joinpath('folder.png') +ICON_HISTORY = APP_DIR.joinpath('history.png') +ICON_IMAGE = APP_DIR.joinpath('image.png') +ICON_LOCK = APP_DIR.joinpath('lock.png') +ICON_LOGOFF = APP_DIR.joinpath('logoff.png') +ICON_OK = APP_DIR.joinpath('ok.png') +ICON_OPEN = APP_DIR.joinpath('open.png') +ICON_PICTURES = APP_DIR.joinpath('pictures.png') +ICON_PLUGIN = APP_DIR.joinpath('plugin.png') +ICON_PROGRAM = APP_DIR.joinpath('program.png') +ICON_RECYCLEBIN = APP_DIR.joinpath('recyclebin.png') +ICON_RESTART = APP_DIR.joinpath('restart.png') +ICON_SEARCH = APP_DIR.joinpath('search.png') +ICON_SETTINGS = APP_DIR.joinpath('settings.png') +ICON_SHELL = APP_DIR.joinpath('shell.png') +ICON_SHUTDOWN = APP_DIR.joinpath('shutdown.png') +ICON_SLEEP = APP_DIR.joinpath('sleep.png') +ICON_UP = APP_DIR.joinpath('up.png') +ICON_UPDATE = APP_DIR.joinpath('update.png') +ICON_URL = APP_DIR.joinpath('url.png') +ICON_USER = APP_DIR.joinpath('user.png') +ICON_WARNING = APP_DIR.joinpath('warning.png') +ICON_WEB_SEARCH = APP_DIR.joinpath('web_search.png') +ICON_WORK = APP_DIR.joinpath('work.png') + + +class Flox(Launcher): + + def __init_subclass__(cls, api=API, app_dir=APP_DIR, user_dir=USER_DIR): + cls._debug = False + cls.appdir = APP_DIR + cls.user_dir = USER_DIR + cls.api = api + cls._start = time.time() + cls._results = [] + cls._settings = None + cls.font_family = '/Resources/#Segoe Fluent Icons' + cls.issue_item_title = 'Report Issue' + cls.issue_item_subtitle = 'Report this issue to the developer' + + @cached_property + def browser(self): + return Browser(self.app_settings) + + def exception(self, exception): + self.exception_item(exception) + self.issue_item(exception) + + def _query(self, query): + self.args = query.lower() + + self.query(query) + + def _context_menu(self, data): + self.context_menu(data) + + def exception_item(self, exception): + self.add_item( + title=exception.__class__.__name__, + subtitle=str(exception), + icon=ICON_APP_ERROR, + method=self.change_query, + dont_hide=True + ) + + def issue_item(self, e): + trace = ''.join(traceback.format_exception(type(e), value=e, tb=e.__traceback__)).replace('\n', '%0A') + self.add_item( + title=self.issue_item_title, + subtitle=self.issue_item_subtitle, + icon=ICON_BROWSER, + method=self.create_github_issue, + parameters=[e.__class__.__name__, trace], + ) + + def create_github_issue(self, title, trace, log=None): + url = self.manifest['Website'] + if 'github' in url.lower(): + issue_body = f"Please+type+any+relevant+information+here%0A%0A%0A%0A%0A%0A%3Cdetails open%3E%3Csummary%3ETrace+Log%3C%2Fsummary%3E%0A%3Cp%3E%0A%0A%60%60%60%0A{trace}%0A%60%60%60%0A%3C%2Fp%3E%0A%3C%2Fdetails%3E" + url = f"{url}/issues/new?title={title}&body={issue_body}" + webbrowser.open(url) + + def add_item(self, title:str, subtitle:str='', icon:str=None, method:Union[str, callable]=None, parameters:list=None, context:list=None, glyph:str=None, score:int=0, **kwargs): + icon = icon or self.icon + if not Path(icon).is_absolute(): + icon = Path(self.plugindir, icon) + item = { + "Title": str(title), + "SubTitle": str(subtitle), + "IcoPath": str(icon), + "ContextData": context, + "Score": score, + "JsonRPCAction": {} + } + auto_complete_text = kwargs.pop("auto_complete_text", None) + + item["AutoCompleteText"] = auto_complete_text or f'{self.user_keyword} {title}'.replace('* ', '') + if method: + item['JsonRPCAction']['method'] = getattr(method, "__name__", method) + item['JsonRPCAction']['parameters'] = parameters or [] + item['JsonRPCAction']['dontHideAfterAction'] = kwargs.pop("dont_hide", False) + if glyph: + item['Glyph'] = {} + item['Glyph']['Glyph'] = glyph + font_family = kwargs.pop("font_family", self.font_family) + if font_family.startswith("#"): + font_family = str(Path(self.plugindir).joinpath(font_family)) + item['Glyph']['FontFamily'] = font_family + for kw in kwargs: + item[kw] = kwargs[kw] + self._results.append(item) + return self._results[-1] + + @cached_property + def plugindir(self): + potential_paths = [ + os.path.abspath(os.getcwd()), + os.path.dirname(os.path.abspath(os.path.dirname(__file__))) + ] + + for path in potential_paths: + + while True: + if os.path.exists(os.path.join(path, PLUGIN_MANIFEST)): + return path + elif os.path.ismount(path): + return os.getcwd() + + path = os.path.dirname(path) + + @cached_property + def manifest(self): + with open(os.path.join(self.plugindir, PLUGIN_MANIFEST), 'r', encoding='utf-8') as f: + return json.load(f) + + @cached_property + def id(self): + return self.manifest['ID'] + + @cached_property + def icon(self): + return self.manifest['IcoPath'] + + @cached_property + def action_keyword(self): + return self.manifest['ActionKeyword'] + + @cached_property + def version(self): + return self.manifest['Version'] + + @cached_property + def appdata(self): + # Userdata should be up two directories from plugin root + return os.path.dirname(os.path.dirname(self.plugindir)) + + @property + def app_settings(self): + with open(os.path.join(self.appdata, 'Settings', 'Settings.json'), 'r', encoding='utf-8') as f: + return json.load(f) + + @property + def query_search_precision(self): + return self.app_settings.get('QuerySearchPrecision', 'Regular') + + @cached_property + def user_keywords(self): + return self.app_settings['PluginSettings']['Plugins'].get(self.id, {}).get('UserKeywords', [self.action_keyword]) + + @cached_property + def user_keyword(self): + return self.user_keywords[0] + + @cached_property + def appicon(self, icon): + return os.path.join(self.appdir, 'images', icon + '.png') + + @property + def applog(self): + today = date.today().strftime('%Y-%m-%d') + file = f"{today}.txt" + return os.path.join(self.appdata, 'Logs', self.appversion, file) + + + @cached_property + def appversion(self): + return os.path.basename(self.appdir).replace('app-', '') + + @cached_property + def logfile(self): + file = "plugin.log" + return os.path.join(self.plugindir, file) + + @cached_property + def logger(self): + logger = logging.getLogger('') + formatter = logging.Formatter( + '%(asctime)s %(levelname)s (%(filename)s): %(message)s', + datefmt='%H:%M:%S') + logfile = logging.handlers.RotatingFileHandler( + self.logfile, + maxBytes=1024 * 2024, + backupCount=1) + logfile.setFormatter(formatter) + logger.addHandler(logfile) + logger.setLevel(logging.WARNING) + return logger + + def logger_level(self, level): + if level == "info": + self.logger.setLevel(logging.INFO) + elif level == "debug": + self.logger.setLevel(logging.DEBUG) + elif level == "warning": + self.logger.setLevel(logging.WARNING) + elif level == "error": + self.logger.setLevel(logging.ERROR) + elif level == "critical": + self.logger.setLevel(logging.CRITICAL) + + @cached_property + def api(self): + launcher = os.path.basename(os.path.dirname(self.appdir)) + if launcher == 'FlowLauncher': + return FLOW_API + else: + return WOX_API + + @cached_property + def name(self): + return self.manifest['Name'] + + @cached_property + def author(self): + return self.manifest['Author'] + + @cached_property + def settings_path(self): + dirname = self.name + setting_file = "Settings.json" + return os.path.join(self.appdata, 'Settings', 'Plugins', dirname, setting_file) + + @cached_property + def settings(self): + if not os.path.exists(os.path.dirname(self.settings_path)): + os.mkdir(os.path.dirname(self.settings_path)) + return Settings(self.settings_path) + + def browser_open(self, url): + self.browser.open(url) + + @cached_property + def python_dir(self): + return self.app_settings["PluginSettings"]["PythonDirectory"] + + def log(self): + return self.logger \ No newline at end of file diff --git a/lib/flox/__pycache__/__init__.cpython-312.pyc b/lib/flox/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4434f2d808a1a51f7f6e040b434673d78b20c882 GIT binary patch literal 20175 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 X)q#`|{Iz~eqbgZG`ZpB5iRAkK%3VRK literal 0 HcmV?d00001 diff --git a/lib/flox/__pycache__/browser.cpython-312.pyc b/lib/flox/__pycache__/browser.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee731a20ec104db4342fc8bf21191fdec45a10bb GIT binary patch literal 4291 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 I7_>eA4+HPkqyPW_ literal 0 HcmV?d00001 diff --git a/lib/flox/__pycache__/clipboard.cpython-312.pyc b/lib/flox/__pycache__/clipboard.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..013d609116012ce83a7ed8a12c596b5441d94729 GIT binary patch literal 3941 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 literal 0 HcmV?d00001 diff --git a/lib/flox/__pycache__/string_matcher.cpython-312.pyc b/lib/flox/__pycache__/string_matcher.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b17c54690d588b59434ccae8672c4c7e527b336c GIT binary patch literal 7470 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 literal 0 HcmV?d00001 diff --git a/lib/flox/__pycache__/utils.cpython-312.pyc b/lib/flox/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cff9091be9690213d01bb09717e7bf4c3678e2b GIT binary patch literal 6937 zcmcgQZEPDycC*}Fa`_=q5=n^?C5wuz*mPsbj-A++9phBVPAuDUE>cjK=T@edRnTwG) z7vwnXn_{LoALLn|j|p)xD6+l~Gsi7K3+sz9DQ*o~S>GJ91#K|T9J2@Q&{|@SxFhH& z!Rmr_Feb(7w>Vl|%XR}7 z=sEz4yI%rNnB+Re19km%G1x3SS-;`B5NwefualrxZi2d1_Q|g6T(GTXCWkX+H_Q-Z z56t#`C$t%$?cWJ)0ceNpWh=MB%Dd!t{9^kO_=8Bc`bN|?tjlnVCox7h~O4RV9KVY)-I zrYy;F6THk_m*)5kKS~0o*;bn$%3vrwrTAqfoTMRGlZ}N-0%Rmn)m%vMRjB@szX9r| zmEjA-5FjkU!y*DO9TqXfILBo;Tx=xFXq756w4LzV{LBO-g&Kn91TSO$ra;m#BLo;lo3ZptvJ(;_D1ZE!4P<*UpOtMMlKNaqmPV)+xHaP2Y>I~F5<$Ob{k}2|84*4{>|0|0V2;iMc%OwM+^od{itDSj>KNBj1NnZ2Ry_WOI(*vG=Hh92AQB8Gw zL>&)ZQIoN>rchKF-K<=TsG6!v%ngJl6)VqB(29I2ovci>NPho3l&$lF{g>WW6{=o37lLXal^TNSm(C@_q1dG{aI}|Fk<@+-)>E|o zFTeV-5;=H`UW!GoTuRMoQ^~}oiCFSlUs{XA)ZWw#91%QjN};m>wwc}&F(jm(>@B;# z%1{XvJ*YYazV6$3@*k}ox$x4lmDc^);SEat#Le9RJzmmwQhAa^G+Ie$}@!{DZaOaDF(vJUR8{@YIH< zHMegm{NVLf&xrz&8hbwD3MPxEXT!hyr`DfX?{Q_hPU%0=LgQ^y|4eWZPh!r?rr_Z@`2?;>xQ@OBkKp&rG5YA z-CwW(;ucV8?R{1Udw9k+g4G|M?jqj66T-3ee0MI~zOcM|=(Ffo?(eU=TC!&gB0{#* zLEz@+0yosle{S{+Hkdy5VgKjEG1O0f-Y`%<)Fpng%LGGT_&Mx%@!0PbhmKgj=$RaFzJ(qOjoy!@%!ViiCW;9G#b7WJ;3+zD z+Kv@EZWwq4`}?qZ2`UwL2*gVAKrhG~35AeI5LG=4)jWAB5nFv$UL0K7vufQ}Ae`8K zH?-k&-I`gL$u-{0WQAuuj6FlZW30AR)P-Bkz5G9jM=aq|Y=_4d8u_x>dZ@> zcZFrCb5+{EVXZ^S-|R%O`*H(-dds?CUEH1HR;4zSyAS2=L%I95R7|lRdRhiv;UB&t z4xF^qm=CHOGoLr1Q*AzmBs1iBIpj`eGz+n*n9APcP~$OFQS=(R1mQN$Qg{<%kj`T$ zL)9uNJjHZ~ReuT{71LhekFEaZi;IWv9J_t&{o`w{J$d-I?U^53x7W`PGq+Hq&E*sQ zJ5U_|dx$EMImW`PtCFocYHy|8#ck#D)Bc3(KQpU!EA-a6+8C`B%%*u64VU@s+vj z8s-W>n5oNOK&OVe92^U`1!c|zNk3w3D+ZfrBfy{IJUBAL&2Vt(YGY1xESU~ZRi%1t z5ETn0QL;r1aqjWONW)@W0Dv{Nr`J(sf-34%iCJ#|!dXN@bmmZ-nis>lV=Ik4^TX?w z#xmR1rKUB>o0q&_No@t5NWMSTxiVW&T;IhOxY}{E-K9{WrD?*C!3=XNhuo*VD3wM^T>J3Ir$4pa~(aa@8$|+))TnTG^q%#p|Uxq2fe# z3V5=RAwMENt_qzOiOkOl?+QE9FT$p|^5sknx#9RsYD3BC1m1&~R{AGsGVTZ7`9lfW zuZBRJ5e*d=0-%kd55PsHpY=d;40Erl(LldH5(gKL1HEM^O!AkY&{e|lkTQeBigXdb zg3In}_-td$zyUuS*fxWaKda14C#meO-OfakhLv&IIMLoK@N5KIJB`Es@^Epd$~#KJ zADO`O74MA2z3BC|L{5*)x+|AagGRqUAnAN6nJRj5^a{Ei&Q2ALMu0L!m7o~abgObL ztfaI^GQr#!|s3CIfZ5D$kS3rSZA!o?u+zoz``s-oq=ke6uhLl{Z8<9 zaM^$0LC=ck=={iU?X5ZaqpKfW{V={R)x%9kJh~w{*CbzF^5q7X+^f=yPt63}2BaX% zg6G?(B5}Ckf>J_58(MBZ@WAyzTyA@HO**nH9VsO&fc*!!uZTytR7{9|+B_hUhmv*R zHU43vci<@h@Tds=n)kM{x&1RUH%!@!Wr+N_2LcBu@J@!65$>1FQsv(Ba3sMCBm<5w z!|xPEYRnbhQs&(|M{UR@OH^e6V=d&9Rhgy%d*166yr7k5Xm!R}j4)R*aLk6HWfM2> zs|3wsYo;`MIG0YGGvFl$9&SpHucx=TzHj~;${0NcL;`l*2Jg7zql0gpIzOP>;H`yf z>U0Dm*7pIdi)tzs(TefA83x!RP0?mv!%x&|-K?gs#3LHy-WAJW5fRM;pzuf%579rv z59>ra78}QisA5jQ%*8Mm3DcuU80_pafZl*T`8+>2k? zyMF6vEQl~#kVu0o3(pgtTeAzZ@amwfIA5B7W8KoQZ1JwUTkf2>eI^%ve`M+9y!*wh zwVcCuyv-|RP->SW1-R@dU!(Cv*(VFYd&8#{C@RYzV!4S&oJhv_^T=?+(-9rzo ztB!t{XIzd097`nW_uzN|zb@hXI=ai!6Bzg*c<-UiDLINCy$ZgxGp~f#9c>B`kb}t4 z1UTkoOr@yd#S7~T*u!idxStGPRW!W`_!>@AyeIWeq#>tKREpuWC3YJa!cR=rShhnk1z-xo1 zT+CGuKyOPr5l_nLm~xWF;1kVT{ZFV0JjZd5NarKc_K0*nBHl;D_cgJ9O{|ZI=W9~; zh#dTy)c?-r%kEjT`SLbj?u`{&&%6crF4nIL^#zfyH_h8XDY({o^BVEyi8t4@O4@(d z)qSt+KHRW(ah}D&O>7F^<3z4~@z5rL=1IN4`JOmToO4s+xrWC!vhOgWn>ld41#Ff^ zH?eu#K=vH`IQEzboImF(V6)V{iOpjN2^_lbz&Y)?LpY~>308up(BR@AW!)suJl^Mm P9l%6rmcmc5VQl#y^}>(2 literal 0 HcmV?d00001 diff --git a/lib/flox/browser.py b/lib/flox/browser.py new file mode 100644 index 0000000..478a361 --- /dev/null +++ b/lib/flox/browser.py @@ -0,0 +1,75 @@ +import logging +from subprocess import Popen, PIPE, CREATE_NO_WINDOW +import webbrowser +from winreg import OpenKey, QueryValueEx, HKEY_CURRENT_USER as HKCU, HKEY_LOCAL_MACHINE as HKLM + +log = logging.getLogger(__name__) + +DEFAULT_BROWSER_KEYWORD = "*" +MICROSOFT_EDGE = 'msedge' +CHROME = 'chrome' +FIREFOX = 'firefox' +NEW_WINDOW_ARG = "--new-window" + + +CHROME_PATH = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe" +FIREFOX_PATH = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\firefox.exe" +MSEDGE_PATH = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe" +DEFAULT_BROWSER_PATH = r"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" + +DEFAULT_BROWSERS = { + CHROME: CHROME_PATH, + FIREFOX: FIREFOX_PATH, + MICROSOFT_EDGE: MSEDGE_PATH, + DEFAULT_BROWSER_KEYWORD: DEFAULT_BROWSER_PATH +} + +def get_reg(path, base_path=HKLM, name=""): + try: + with OpenKey(base_path, path) as key: + return QueryValueEx(key, name)[0] + except FileNotFoundError: + log.exception(f'Can\'t find browser "{path}"') + +class Browser(object): + + def __init__(self, settings): + self.Name = None + self.Path = None + self.PrivateArg = None + self.EnablePrivate = False + self.OpenInTab = True + self.Editable = False + self.CustomBrowserIndex = settings.get('CustomBrowserIndex', 0) + self.CustomBrowserList = settings.get('CustomBrowserList', []) + try: + self.current_browser = self.CustomBrowserList[self.CustomBrowserIndex] + except IndexError: + self.current_browser = {} + for item in self.current_browser: + setattr(self, item, self.current_browser[item]) + + def open(self, url): + try: + cmd = [self.get_exe(), url] + if self.current_browser.get('EnablePrivate', False): + cmd.append(self.current_browser['PrivateArg']) + if not self.OpenInTab: + cmd.append(NEW_WINDOW_ARG) + log.debug(f'Opening {url} with {cmd}') + Popen(cmd, creationflags=CREATE_NO_WINDOW) + # All else fails, open in default browser and log error + except Exception as e: + log.exception(f'Can\'t open {url} with {self.Name}') + webbrowser.open(url) + + def get_exe(self): + key = self.Path or DEFAULT_BROWSER_KEYWORD + if key == DEFAULT_BROWSER_KEYWORD: + browser = get_reg(DEFAULT_BROWSER_PATH, HKCU, 'Progid') + key = browser.split('-')[0].replace('url', '').replace('HTML', '').lower() + if key in DEFAULT_BROWSERS: + _path = DEFAULT_BROWSERS.get(key) + return get_reg(_path) + else: + return key \ No newline at end of file diff --git a/lib/flox/clipboard.py b/lib/flox/clipboard.py new file mode 100644 index 0000000..a30f55d --- /dev/null +++ b/lib/flox/clipboard.py @@ -0,0 +1,82 @@ +import ctypes + +from ctypes.wintypes import BOOL, HWND, HANDLE, HGLOBAL, UINT, LPVOID +from ctypes import c_size_t as SIZE_T + +# Credit for code goes to Mark Ransom at https://stackoverflow.com/a/25678113 + +OpenClipboard = ctypes.windll.user32.OpenClipboard +OpenClipboard.argtypes = HWND, +OpenClipboard.restype = BOOL +EmptyClipboard = ctypes.windll.user32.EmptyClipboard +EmptyClipboard.restype = BOOL +GetClipboardData = ctypes.windll.user32.GetClipboardData +GetClipboardData.argtypes = UINT, +GetClipboardData.restype = HANDLE +SetClipboardData = ctypes.windll.user32.SetClipboardData +SetClipboardData.argtypes = UINT, HANDLE +SetClipboardData.restype = HANDLE +CloseClipboard = ctypes.windll.user32.CloseClipboard +CloseClipboard.restype = BOOL +CF_UNICODETEXT = 13 + +GlobalAlloc = ctypes.windll.kernel32.GlobalAlloc +GlobalAlloc.argtypes = UINT, SIZE_T +GlobalAlloc.restype = HGLOBAL +GlobalLock = ctypes.windll.kernel32.GlobalLock +GlobalLock.argtypes = HGLOBAL, +GlobalLock.restype = LPVOID +GlobalUnlock = ctypes.windll.kernel32.GlobalUnlock +GlobalUnlock.argtypes = HGLOBAL, +GlobalSize = ctypes.windll.kernel32.GlobalSize +GlobalSize.argtypes = HGLOBAL, +GlobalSize.restype = SIZE_T + +GMEM_MOVEABLE = 0x0002 +GMEM_ZEROINIT = 0x0040 + +unicode_type = type(u'') + +class Clipboard(object): + + def get(self): + return get() + + def put(self, text): + return put(text) + +def get(): + """ + Get the contents of the clipboard. + """ + text = None + OpenClipboard(None) + handle = GetClipboardData(CF_UNICODETEXT) + pcontents = GlobalLock(handle) + size = GlobalSize(handle) + if pcontents and size: + raw_data = ctypes.create_string_buffer(size) + ctypes.memmove(raw_data, pcontents, size) + text = raw_data.raw.decode('utf-16le').rstrip(u'\0') + GlobalUnlock(handle) + CloseClipboard() + return text + +def put(s): + """ + Put the given string onto the clipboard. + """ + if not isinstance(s, unicode_type): + s = s.decode('mbcs') + data = s.encode('utf-16le') + OpenClipboard(None) + EmptyClipboard() + handle = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, len(data) + 2) + pcontents = GlobalLock(handle) + ctypes.memmove(pcontents, data, len(data)) + GlobalUnlock(handle) + SetClipboardData(CF_UNICODETEXT, handle) + CloseClipboard() + +def copy(s): + put(s) \ No newline at end of file diff --git a/lib/flox/launcher.py b/lib/flox/launcher.py new file mode 100644 index 0000000..3098f85 --- /dev/null +++ b/lib/flox/launcher.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +import json +import sys +from time import time + +""" +Slightly modified wox.py credit: https://github.com/Wox-launcher/Wox +""" + +class Launcher(object): + """ + Launcher python plugin base + """ + + def __del__(self, debug=None): + self.run(debug) + + def run(self, debug=None): + if debug: + self._debug = debug + self.rpc_request = {'method': 'query', 'parameters': ['']} + if len(sys.argv) > 1: + self.rpc_request = json.loads(sys.argv[1]) + if 'settings' in self.rpc_request.keys(): + self._settings = self.rpc_request['settings'] + self.logger.debug('Loaded settings from RPC request') + if not self._debug: + self._debug = self.settings.get('debug', False) + if self._debug: + self.logger_level("debug") + self.logger.debug(f'Request:\n{json.dumps(self.rpc_request, indent=4)}') + self.logger.debug(f"Params: {self.rpc_request.get('parameters')}") + # proxy is not working now + # self.proxy = rpc_request.get("proxy",{}) + request_method_name = self.rpc_request.get("method") + #transform query and context calls to internal flox methods + if request_method_name == 'query' or request_method_name == 'context_menu': + request_method_name = f"_{request_method_name}" + + request_parameters = self.rpc_request.get("parameters") + + request_method = getattr(self, request_method_name) + try: + results = request_method(*request_parameters) or self._results + except Exception as e: + self.logger.exception(e) + results = self.exception(e) or self._results + line_break = '#' * 10 + ms = int((time() - self._start) * 1000) + self.logger.debug(f'{line_break} Total time: {ms}ms {line_break}') + if request_method_name == "_query" or request_method_name == "_context_menu": + results = {"result": results} + if self._settings != self.rpc_request.get('Settings') and self._settings is not None: + results['SettingsChange'] = self.settings + + print(json.dumps(results)) + + def query(self,query): + """ + sub class need to override this method + """ + return [] + + def context_menu(self, data): + """ + optional context menu entries for a result + """ + return [] + + def exception(self, exception): + """ + exception handler + """ + return [] + + def debug(self,msg): + """ + alert msg + """ + print("DEBUG:{}".format(msg)) + sys.exit() + + def change_query(self, query, requery=False): + """ + change query + """ + print(json.dumps({"method": f"{self.api}.ChangeQuery","parameters":[query,requery]})) + + def shell_run(self, cmd): + """ + run shell commands + """ + print(json.dumps({"method": f"{self.api}.ShellRun","parameters":[cmd]})) + + def close_app(self): + """ + close launcher + """ + print(json.dumps({"method": f"{self.api}.CloseApp","parameters":[]})) + + def hide_app(self): + """ + hide launcher + """ + print(json.dumps({"method": f"{self.api}.HideApp","parameters":[]})) + + def show_app(self): + """ + show launcher + """ + print(json.dumps({"method": f"{self.api}.ShowApp","parameters":[]})) + + def show_msg(self, title, sub_title, ico_path=""): + """ + show messagebox + """ + print(json.dumps({"method": f"{self.api}.ShowMsg","parameters":[title,sub_title,ico_path]})) + + def open_setting_dialog(self): + """ + open setting dialog + """ + self.logger.debug(json.dumps({"method": f"{self.api}.OpenSettingDialog","parameters":[]})) + print(json.dumps({"method": f"{self.api}.OpenSettingDialog","parameters":[]})) + + def start_loadingbar(self): + """ + start loading animation in wox + """ + print(json.dumps({"method": f"{self.api}.StartLoadingBar","parameters":[]})) + + def stop_loadingbar(self): + """ + stop loading animation in wox + """ + print(json.dumps({"method": f"{self.api}.StopLoadingBar","parameters":[]})) + + def reload_plugins(self): + """ + reload all launcher plugins + """ + print(json.dumps({"method": f"{self.api}.ReloadPlugins","parameters":[]})) diff --git a/lib/flox/settings.py b/lib/flox/settings.py new file mode 100644 index 0000000..8bebf46 --- /dev/null +++ b/lib/flox/settings.py @@ -0,0 +1,53 @@ +from pathlib import Path +import json + +class Settings(dict): + + def __init__(self, filepath): + super(Settings, self).__init__() + self._filepath = filepath + self._save = True + if Path(self._filepath).exists(): + self._load() + else: + data = {} + self.update(data) + self.save() + + + def _load(self): + data = {} + with open(self._filepath, 'r') as f: + try: + data.update(json.load(f)) + except json.decoder.JSONDecodeError: + pass + + self._save = False + self.update(data) + self._save = True + + def save(self): + if self._save: + data = {} + data.update(self) + with open(self._filepath, 'w') as f: + json.dump(data, f, sort_keys=True, indent=4) + return + + def __setitem__(self, key, value): + super(Settings, self).__setitem__(key, value) + self.save() + + def __delitem__(self, key): + super(Settings, self).__delitem__(key) + self.save() + + def update(self, *args, **kwargs): + super(Settings, self).update(*args, **kwargs) + self.save() + + def setdefault(self, key, value=None): + ret = super(Settings, self).setdefault(key, value) + self.save() + return ret diff --git a/lib/flox/string_matcher.py b/lib/flox/string_matcher.py new file mode 100644 index 0000000..84cfb7b --- /dev/null +++ b/lib/flox/string_matcher.py @@ -0,0 +1,219 @@ +from dataclasses import dataclass, field +from typing import List + +SPACE_CHAR: str = ' ' +QUERY_SEARCH_PRECISION = { + 'Regular': 50, + 'Low': 20, + 'None': 0 +} +DEFAULT_QUERY_SEARCH_PRECISION = QUERY_SEARCH_PRECISION['Regular'] + +""" +This is a python copy of Flow Launcher's string matcher. +I take no credit for the algorithm, I just translated it to python. +""" + + +@dataclass +class MatchData: + """Match data""" + matched: bool + score_cutoff: int + index_list: List[int] = field(default_factory=list) + score: int = 0 + + +def string_matcher(query: str, text: str, ignore_case: bool = True, query_search_precision: int = DEFAULT_QUERY_SEARCH_PRECISION) -> MatchData: + """Compare query to text""" + if not text or not query: + return MatchData(False, query_search_precision) + + query = query.strip() + + current_acronym_query_index = 0 + acronym_match_data: List[int] = [] + acronyms_total_count: int = 0 + acronyms_matched: int = 0 + + full_text_lower: str = text.lower() if ignore_case else text + query_lower: str = query.lower() if ignore_case else query + + query_substrings: List[str] = query_lower.split(' ') + current_query_substring_index: int = 0 + current_query_substring = query_substrings[current_query_substring_index] + current_query_substring_char_index = 0 + + first_match_index = -1 + first_match_index_in_word = -1 + last_match_index = 0 + all_query_substrings_matched: bool = False + match_found_in_previous_loop: bool = False + all_substrings_contained_in_text: bool = True + + index_list: List[int] = [] + space_indices: List[int] = [] + for text_index in range(len(full_text_lower)): + if current_acronym_query_index >= len(query_lower) and acronyms_matched == len(query_lower): + + if is_acronym_count(full_text_lower, text_index): + acronyms_total_count += 1 + continue + + if current_acronym_query_index >= len(query_lower) or current_acronym_query_index >= len(query_lower) and all_query_substrings_matched: + break + + if full_text_lower[text_index] == SPACE_CHAR and current_query_substring_char_index == 0: + space_indices.append(text_index) + + if is_acronym(text, text_index): + if full_text_lower[text_index] == query_lower[current_acronym_query_index]: + acronym_match_data.append(text_index) + acronyms_matched += 1 + current_acronym_query_index += 1 + + if is_acronym_count(text, text_index): + acronyms_total_count += 1 + + if all_query_substrings_matched or full_text_lower[text_index] != current_query_substring[current_query_substring_char_index]: + match_found_in_previous_loop = False + continue + + if first_match_index < 0: + first_match_index = text_index + + if current_query_substring_char_index == 0: + match_found_in_previous_loop = True + first_match_index_in_word = text_index + elif not match_found_in_previous_loop: + start_index_to_verify = text_index - current_query_substring_char_index + + if all_previous_chars_matched(start_index_to_verify, current_query_substring_char_index, full_text_lower, current_query_substring): + match_found_in_previous_loop = True + first_match_index_in_word = start_index_to_verify if current_query_substring_index == 0 else first_match_index + + index_list = get_updated_index_list( + start_index_to_verify, current_query_substring_char_index, first_match_index_in_word, index_list) + + last_match_index = text_index + 1 + index_list.append(text_index) + + current_query_substring_char_index += 1 + + if current_query_substring_char_index == len(current_query_substring): + all_substrings_contained_in_text = match_found_in_previous_loop and all_substrings_contained_in_text + + current_query_substring_index += 1 + + all_query_substrings_matched = all_query_substrings_matched_func( + current_query_substring_index, len(query_substrings)) + + if all_query_substrings_matched: + continue + + current_query_substring = query_substrings[current_query_substring_index] + current_query_substring_char_index = 0 + + if acronyms_matched > 0 and acronyms_matched == len(query): + acronyms_score: int = acronyms_matched * 100 / acronyms_total_count + + if acronyms_score >= query_search_precision: + return MatchData(True, query_search_precision, acronym_match_data, acronyms_score) + + if all_query_substrings_matched: + + nearest_space_index = calculate_closest_space_index( + space_indices, first_match_index) + + score = calculate_search_score(query, text, first_match_index - nearest_space_index - 1, + space_indices, last_match_index - first_match_index, all_substrings_contained_in_text) + + return MatchData(True, query_search_precision, index_list, score) + + return MatchData(False, query_search_precision) + + +def calculate_search_score(query: str, text: str, first_index: int, space_indices: List[int], match_length: int, all_substrings_contained_in_text: bool): + score = 100 * (len(query) + 1) / ((1 + first_index) + (match_length + 1)) + + if first_index == 0 and all_substrings_contained_in_text: + score -= len(space_indices) + + if (len(text) - len(query)) < 5: + score += 20 + elif (len(text) - len(query)) < 10: + score += 10 + + if all_substrings_contained_in_text: + count: int = len(query.replace(' ', '')) + threshold: int = 4 + if count <= threshold: + score += count * 10 + else: + score += threshold * 10 + (count - threshold) * 5 + + return score + + +def get_updated_index_list(start_index_to_verify: int, current_query_substring_char_index: int, first_matched_index_in_word: int, index_list: List[int]): + updated_list: List[int] = [] + + for idx, item in enumerate(index_list): + if item >= first_matched_index_in_word: + index_list.pop(idx) + + updated_list.extend(index_list) + + for i in range(current_query_substring_char_index): + updated_list.append(start_index_to_verify + i) + + return updated_list + + +def all_query_substrings_matched_func(current_query_substring_index: int, query_substrings_length: int) -> bool: + return current_query_substring_index >= query_substrings_length + + +def all_previous_chars_matched(start_index_to_verify: int, current_query_substring_char_index: int, full_text_lower: str, current_query_substring: str) -> bool: + all_match = True + for i in range(current_query_substring_char_index): + if full_text_lower[start_index_to_verify + i] != current_query_substring[i]: + all_match = False + + return all_match + + +def is_acronym(text: str, text_index: int) -> bool: + if is_acronym_char(text, text_index) or is_acronym_number(text, text_index): + return True + return False + + +def is_acronym_count(text: str, text_index: int) -> bool: + if is_acronym_char(text, text_index): + return True + if is_acronym_number(text, text_index): + return text_index == 0 or text[text_index - 1] == SPACE_CHAR + + return False + + +def is_acronym_char(text: str, text_index: int) -> bool: + return text[text_index].isupper() or text_index == 0 or text[text_index - 1] == SPACE_CHAR + + +def is_acronym_number(text: str, text_index: int) -> bool: + return text[text_index].isdigit() + + +def calculate_closest_space_index(space_indices: List[int], first_match_index: int) -> int: + + closest_space_index = -1 + + for i in space_indices: + if i < first_match_index: + closest_space_index = i + else: + break + + return closest_space_index diff --git a/lib/flox/utils.py b/lib/flox/utils.py new file mode 100644 index 0000000..b71069c --- /dev/null +++ b/lib/flox/utils.py @@ -0,0 +1,137 @@ +from tempfile import gettempdir +from urllib import request +from urllib.error import URLError +from pathlib import Path +from functools import wraps +import json +import os +from time import time +import socket +from concurrent.futures import ThreadPoolExecutor +import logging + +logging = logging.getLogger(__name__) + +URL_SCHEMA = [ + 'http://', + 'https://', +] +socket.setdefaulttimeout(15) + +def cache(file_name:str, max_age=30, dir=gettempdir()): + """ + Cache decorator + """ + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + cache_file = Path(dir, file_name) + if not Path(cache_file).is_absolute(): + cache_file = Path(gettempdir(), cache_file) + if cache_file.exists() and file_age(cache_file) < max_age and cache_file.stat().st_size != 0: + with open(cache_file, 'r', encoding='utf-8') as f: + try: + cache = json.load(f) + except json.JSONDecodeError: + logging.warning('Unable to read cache file: %s', cache_file) + f.close() + os.remove(cache_file) + else: + return cache + data = func(*args, **kwargs) + if data is None: + return None + if len(data) != 0: + try: + write_json(data, cache_file) + except FileNotFoundError: + logging.warning('Unable to write cache file: %s', cache_file) + return data + return wrapper + return decorator + +def read_json(path:str): + """ + Read json file + """ + with open(path, 'r', encoding='utf-8') as f: + data = json.load(f) + +def write_json(data, path): + if not Path(path).parent.exists(): + Path(path).parent.mkdir(parents=True) + with open(path, 'w') as f: + json.dump(data, f) + +def file_age(path): + age = time() - path.stat().st_mtime + return age + +def get_cache(path, max_age=0): + if Path(path).exists() and file_age(path) < max_age and path.stat().st_size != 0: + return read_json(path) + return None + +def refresh_cache(file_name:str, dir:str=gettempdir()): + """ + Touch cache file + """ + cache_file = Path(dir, file_name) + if cache_file.exists(): + cache_file.touch() + +def cache_path(file_name:str, dir:str=gettempdir()): + """ + Return path to cache file + """ + return Path(dir, file_name) + +def remove_cache(file_name:str, dir:str=gettempdir()): + """ + Remove cache file + """ + cache_file = Path(dir, file_name) + if cache_file.exists(): + cache_file.unlink() + +def download_file(url:str, path, **kwargs): + """ + Download file from url and save it to dir + + Args: + url (str): image url. + dir (str): directory to save image. + file_name (str): file name to save image. + + Keyword Args: + force_download (bool): Force download image even if it exists. + """ + force_download = kwargs.pop('force_download', False) + if not force_download and path.exists(): + return + try: + request.urlretrieve(url, path) + except URLError as e: + logging.exception(f'Unable to download: {url}') + return Path(path) + +def get_icon(url:str, path, file_name:str=None, **kwargs): + for schema in URL_SCHEMA: + if url.startswith(schema): + break + else: + return url + executor = kwargs.pop('executor', False) + if file_name is None: + file_name = url.split('/')[-1] + if not Path(path).is_absolute(): + path = Path(gettempdir(), path) + if not path.exists(): + path.mkdir(parents=True) + full_path = Path(path, file_name) + if not full_path.exists(): + if executor is False: + download_file(url, full_path) + else: + executor.submit(download_file, url, full_path) + return full_path \ No newline at end of file diff --git a/lib/flox/version b/lib/flox/version new file mode 100644 index 0000000..68d0e0a --- /dev/null +++ b/lib/flox/version @@ -0,0 +1 @@ +0.19.6 diff --git a/lib/idna-2.10.dist-info/INSTALLER b/lib/idna-2.10.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/idna-2.10.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/idna-2.10.dist-info/LICENSE.rst b/lib/idna-2.10.dist-info/LICENSE.rst new file mode 100644 index 0000000..63664b8 --- /dev/null +++ b/lib/idna-2.10.dist-info/LICENSE.rst @@ -0,0 +1,34 @@ +License +------- + +License: bsd-3-clause + +Copyright (c) 2013-2020, Kim Davies. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +#. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +#. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided with + the distribution. + +#. Neither the name of the copyright holder nor the names of the + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +#. THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + DAMAGE. diff --git a/lib/idna-2.10.dist-info/METADATA b/lib/idna-2.10.dist-info/METADATA new file mode 100644 index 0000000..f73c0ff --- /dev/null +++ b/lib/idna-2.10.dist-info/METADATA @@ -0,0 +1,243 @@ +Metadata-Version: 2.1 +Name: idna +Version: 2.10 +Summary: Internationalized Domain Names in Applications (IDNA) +Home-page: https://github.com/kjd/idna +Author: Kim Davies +Author-email: kim@cynosure.com.au +License: BSD-like +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* + +Internationalized Domain Names in Applications (IDNA) +===================================================== + +Support for the Internationalised Domain Names in Applications +(IDNA) protocol as specified in `RFC 5891 `_. +This is the latest version of the protocol and is sometimes referred to as +“IDNA 2008”. + +This library also provides support for Unicode Technical Standard 46, +`Unicode IDNA Compatibility Processing `_. + +This acts as a suitable replacement for the “encodings.idna” module that +comes with the Python standard library, but only supports the +old, deprecated IDNA specification (`RFC 3490 `_). + +Basic functions are simply executed: + +.. code-block:: pycon + + # Python 3 + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + + # Python 2 + >>> import idna + >>> idna.encode(u'ドメイン.テスト') + 'xn--eckwd4c7c.xn--zckzah' + >>> print idna.decode('xn--eckwd4c7c.xn--zckzah') + ドメイン.テスト + +Packages +-------- + +The latest tagged release version is published in the PyPI repository: + +.. image:: https://badge.fury.io/py/idna.svg + :target: http://badge.fury.io/py/idna + + +Installation +------------ + +To install this library, you can use pip: + +.. code-block:: bash + + $ pip install idna + +Alternatively, you can install the package using the bundled setup script: + +.. code-block:: bash + + $ python setup.py install + +This library works with Python 2.7 and Python 3.4 or later. + + +Usage +----- + +For typical usage, the ``encode`` and ``decode`` functions will take a domain +name argument and perform a conversion to A-labels or U-labels respectively. + +.. code-block:: pycon + + # Python 3 + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + +You may use the codec encoding and decoding methods using the +``idna.codec`` module: + +.. code-block:: pycon + + # Python 2 + >>> import idna.codec + >>> print u'домена.испытание'.encode('idna') + xn--80ahd1agd.xn--80akhbyknj4f + >>> print 'xn--80ahd1agd.xn--80akhbyknj4f'.decode('idna') + домена.испытание + +Conversions can be applied at a per-label basis using the ``ulabel`` or ``alabel`` +functions if necessary: + +.. code-block:: pycon + + # Python 2 + >>> idna.alabel(u'测试') + 'xn--0zwm56d' + +Compatibility Mapping (UTS #46) ++++++++++++++++++++++++++++++++ + +As described in `RFC 5895 `_, the IDNA +specification no longer normalizes input from different potential ways a user +may input a domain name. This functionality, known as a “mapping”, is now +considered by the specification to be a local user-interface issue distinct +from IDNA conversion functionality. + +This library provides one such mapping, that was developed by the Unicode +Consortium. Known as `Unicode IDNA Compatibility Processing `_, +it provides for both a regular mapping for typical applications, as well as +a transitional mapping to help migrate from older IDNA 2003 applications. + +For example, “Königsgäßchen” is not a permissible label as *LATIN CAPITAL +LETTER K* is not allowed (nor are capital letters in general). UTS 46 will +convert this into lower case prior to applying the IDNA conversion. + +.. code-block:: pycon + + # Python 3 + >>> import idna + >>> idna.encode(u'Königsgäßchen') + ... + idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed + >>> idna.encode('Königsgäßchen', uts46=True) + b'xn--knigsgchen-b4a3dun' + >>> print(idna.decode('xn--knigsgchen-b4a3dun')) + königsgäßchen + +Transitional processing provides conversions to help transition from the older +2003 standard to the current standard. For example, in the original IDNA +specification, the *LATIN SMALL LETTER SHARP S* (ß) was converted into two +*LATIN SMALL LETTER S* (ss), whereas in the current IDNA specification this +conversion is not performed. + +.. code-block:: pycon + + # Python 2 + >>> idna.encode(u'Königsgäßchen', uts46=True, transitional=True) + 'xn--knigsgsschen-lcb0w' + +Implementors should use transitional processing with caution, only in rare +cases where conversion from legacy labels to current labels must be performed +(i.e. IDNA implementations that pre-date 2008). For typical applications +that just need to convert labels, transitional processing is unlikely to be +beneficial and could produce unexpected incompatible results. + +``encodings.idna`` Compatibility +++++++++++++++++++++++++++++++++ + +Function calls from the Python built-in ``encodings.idna`` module are +mapped to their IDNA 2008 equivalents using the ``idna.compat`` module. +Simply substitute the ``import`` clause in your code to refer to the +new module name. + +Exceptions +---------- + +All errors raised during the conversion following the specification should +raise an exception derived from the ``idna.IDNAError`` base class. + +More specific exceptions that may be generated as ``idna.IDNABidiError`` +when the error reflects an illegal combination of left-to-right and right-to-left +characters in a label; ``idna.InvalidCodepoint`` when a specific codepoint is +an illegal character in an IDN label (i.e. INVALID); and ``idna.InvalidCodepointContext`` +when the codepoint is illegal based on its positional context (i.e. it is CONTEXTO +or CONTEXTJ but the contextual requirements are not satisfied.) + +Building and Diagnostics +------------------------ + +The IDNA and UTS 46 functionality relies upon pre-calculated lookup tables for +performance. These tables are derived from computing against eligibility criteria +in the respective standards. These tables are computed using the command-line +script ``tools/idna-data``. + +This tool will fetch relevant tables from the Unicode Consortium and perform the +required calculations to identify eligibility. It has three main modes: + +* ``idna-data make-libdata``. Generates ``idnadata.py`` and ``uts46data.py``, + the pre-calculated lookup tables using for IDNA and UTS 46 conversions. Implementors + who wish to track this library against a different Unicode version may use this tool + to manually generate a different version of the ``idnadata.py`` and ``uts46data.py`` + files. + +* ``idna-data make-table``. Generate a table of the IDNA disposition + (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix B.1 of RFC + 5892 and the pre-computed tables published by `IANA `_. + +* ``idna-data U+0061``. Prints debugging output on the various properties + associated with an individual Unicode codepoint (in this case, U+0061), that are + used to assess the IDNA and UTS 46 status of a codepoint. This is helpful in debugging + or analysis. + +The tool accepts a number of arguments, described using ``idna-data -h``. Most notably, +the ``--version`` argument allows the specification of the version of Unicode to use +in computing the table data. For example, ``idna-data --version 9.0.0 make-libdata`` +will generate library data against Unicode 9.0.0. + +Note that this script requires Python 3, but all generated library data will work +in Python 2.7. + + +Testing +------- + +The library has a test suite based on each rule of the IDNA specification, as +well as tests that are provided as part of the Unicode Technical Standard 46, +`Unicode IDNA Compatibility Processing `_. + +The tests are run automatically on each commit at Travis CI: + +.. image:: https://travis-ci.org/kjd/idna.svg?branch=master + :target: https://travis-ci.org/kjd/idna + + diff --git a/lib/idna-2.10.dist-info/RECORD b/lib/idna-2.10.dist-info/RECORD new file mode 100644 index 0000000..2f73649 --- /dev/null +++ b/lib/idna-2.10.dist-info/RECORD @@ -0,0 +1,22 @@ +idna-2.10.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +idna-2.10.dist-info/LICENSE.rst,sha256=QSAUQg0kc9ugYRfD1Nng7sqm3eDKMM2VH07CvjlCbzI,1565 +idna-2.10.dist-info/METADATA,sha256=ZWCaQDBjdmSvx5EU7Cv6ORC-9NUQ6nXh1eXx38ySe40,9104 +idna-2.10.dist-info/RECORD,, +idna-2.10.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 +idna-2.10.dist-info/top_level.txt,sha256=jSag9sEDqvSPftxOQy-ABfGV_RSy7oFh4zZJpODV8k0,5 +idna/__init__.py,sha256=9Nt7xpyet3DmOrPUGooDdAwmHZZu1qUAy2EaJ93kGiQ,58 +idna/__pycache__/__init__.cpython-312.pyc,, +idna/__pycache__/codec.cpython-312.pyc,, +idna/__pycache__/compat.cpython-312.pyc,, +idna/__pycache__/core.cpython-312.pyc,, +idna/__pycache__/idnadata.cpython-312.pyc,, +idna/__pycache__/intranges.cpython-312.pyc,, +idna/__pycache__/package_data.cpython-312.pyc,, +idna/__pycache__/uts46data.cpython-312.pyc,, +idna/codec.py,sha256=lvYb7yu7PhAqFaAIAdWcwgaWI2UmgseUua-1c0AsG0A,3299 +idna/compat.py,sha256=R-h29D-6mrnJzbXxymrWUW7iZUvy-26TQwZ0ij57i4U,232 +idna/core.py,sha256=jCoaLb3bA2tS_DDx9PpGuNTEZZN2jAzB369aP-IHYRE,11951 +idna/idnadata.py,sha256=gmzFwZWjdms3kKZ_M_vwz7-LP_SCgYfSeE03B21Qpsk,42350 +idna/intranges.py,sha256=TY1lpxZIQWEP6tNqjZkFA5hgoMWOj1OBmnUG8ihT87E,1749 +idna/package_data.py,sha256=bxBjpLnE06_1jSYKEy5svOMu1zM3OMztXVUb1tPlcp0,22 +idna/uts46data.py,sha256=lMdw2zdjkH1JUWXPPEfFUSYT3Fyj60bBmfLvvy5m7ko,202084 diff --git a/lib/idna-2.10.dist-info/WHEEL b/lib/idna-2.10.dist-info/WHEEL new file mode 100644 index 0000000..8b701e9 --- /dev/null +++ b/lib/idna-2.10.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.33.6) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/lib/idna-2.10.dist-info/top_level.txt b/lib/idna-2.10.dist-info/top_level.txt new file mode 100644 index 0000000..c40472e --- /dev/null +++ b/lib/idna-2.10.dist-info/top_level.txt @@ -0,0 +1 @@ +idna diff --git a/lib/idna/__init__.py b/lib/idna/__init__.py new file mode 100644 index 0000000..847bf93 --- /dev/null +++ b/lib/idna/__init__.py @@ -0,0 +1,2 @@ +from .package_data import __version__ +from .core import * diff --git a/lib/idna/__pycache__/__init__.cpython-312.pyc b/lib/idna/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3a3e9700cef620f3a2871252c4493b8f95a60eac GIT binary patch literal 252 zcmX@j%ge<81gtFWX;wh`F^B^LOi;#WDIjAyLkdF*V-7)v{G!yA z44*;f{|a!niU}q?xviKRNPJ*s RWMsU{pn8`I0R!-lK|af7z30(Q+^DrCqd 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 literal 0 HcmV?d00001 diff --git a/lib/idna/__pycache__/idnadata.cpython-312.pyc b/lib/idna/__pycache__/idnadata.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d59d9e7ac7363ebf7b5cd1490d481a96b31a52e8 GIT binary patch literal 36325 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%0D?6E8%5LTc?Q!ZiVE0;10l*^cf%H_-=W+ii| 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 GjrVN?+}6&0Tr-o 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 PcYRigbnhZ|VDbL|;m`V= literal 0 HcmV?d00001 diff --git a/lib/idna/codec.py b/lib/idna/codec.py new file mode 100644 index 0000000..98c65ea --- /dev/null +++ b/lib/idna/codec.py @@ -0,0 +1,118 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re + +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +class Codec(codecs.Codec): + + def encode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return "", 0 + + return encode(data), len(data) + + def decode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return u"", 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return ("", 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(data, unicode): + labels = _unicode_dots_re.split(data) + else: + # Must be ASCII string + data = str(data) + unicode(data, "ascii") + labels = data.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/lib/idna/compat.py b/lib/idna/compat.py new file mode 100644 index 0000000..4d47f33 --- /dev/null +++ b/lib/idna/compat.py @@ -0,0 +1,12 @@ +from .core import * +from .codec import * + +def ToASCII(label): + return encode(label) + +def ToUnicode(label): + return decode(label) + +def nameprep(s): + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") + diff --git a/lib/idna/core.py b/lib/idna/core.py new file mode 100644 index 0000000..41ec5c7 --- /dev/null +++ b/lib/idna/core.py @@ -0,0 +1,400 @@ +from . import idnadata +import bisect +import unicodedata +import re +import sys +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +if sys.version_info[0] >= 3: + unicode = str + unichr = chr + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp): + v = unicodedata.combining(unichr(cp)) + if v == 0: + if not unicodedata.name(unichr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + +def _is_script(cp, script): + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s): + return s.encode('punycode') + +def _unot(s): + return 'U+{0:04X}'.format(s) + + +def valid_label_length(label): + + if len(label) > 63: + return False + return True + + +def valid_string_length(label, trailing_dot): + + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label, check_ltr=False): + + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label): + + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label): + + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label): + + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label, pos): + + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label, pos, exception=False): + + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == u'\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + +def check_label(label): + + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + except ValueError: + raise IDNAError('Unknown codepoint adjacent to joiner {0} at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label): + + try: + label = label.encode('ascii') + ulabel(label) + if not valid_label_length(label): + raise IDNAError('Label too long') + return label + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = unicode(label) + check_label(label) + label = _punycode(label) + label = _alabel_prefix + label + + if not valid_label_length(label): + raise IDNAError('Label too long') + + return label + + +def ulabel(label): + + if not isinstance(label, (bytes, bytearray)): + try: + label = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + + label = label.lower() + if label.startswith(_alabel_prefix): + label = label[len(_alabel_prefix):] + if not label: + raise IDNAError('Malformed A-label, no Punycode eligible content found') + if label.decode('ascii')[-1] == '-': + raise IDNAError('A-label must not end with a hyphen') + else: + check_label(label) + return label.decode('ascii') + + label = label.decode('punycode') + check_label(label) + return label + + +def uts46_remap(domain, std3_rules=True, transitional=False): + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = u"" + try: + for pos, char in enumerate(domain): + code_point = ord(char) + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement = uts46row[2] if len(uts46row) == 3 else None + if (status == "V" or + (status == "D" and not transitional) or + (status == "3" and not std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == "M" or + (status == "3" and not std3_rules) or + (status == "D" and transitional)): + output += replacement + elif status != "I": + raise IndexError() + return unicodedata.normalize("NFC", output) + except IndexError: + raise InvalidCodepoint( + "Codepoint {0} not allowed at position {1} in {2}".format( + _unot(code_point), pos + 1, repr(domain))) + + +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s, strict=False, uts46=False, std3_rules=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split(u'.') + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(u'') + return u'.'.join(result) diff --git a/lib/idna/idnadata.py b/lib/idna/idnadata.py new file mode 100644 index 0000000..a284e4c --- /dev/null +++ b/lib/idna/idnadata.py @@ -0,0 +1,2050 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "13.0.0" +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x37f00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0xab650000ab66, + 0x101400001018f, + 0x101a0000101a1, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004dc0, + 0x4e0000009ffd, + 0xf9000000fa6e, + 0xfa700000fada, + 0x16ff000016ff2, + 0x200000002a6de, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + 0x300000003134b, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5ef000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b11f, + 0x1b1500001b153, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1b0000001b001, + 0x1b1640001b168, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x605: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x70f: 84, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 82, + 0x857: 82, + 0x858: 82, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 0x8a0: 68, + 0x8a1: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x8ad: 85, + 0x8ae: 82, + 0x8af: 68, + 0x8b0: 68, + 0x8b1: 82, + 0x8b2: 82, + 0x8b3: 68, + 0x8b4: 68, + 0x8b6: 68, + 0x8b7: 68, + 0x8b8: 68, + 0x8b9: 82, + 0x8ba: 68, + 0x8bb: 68, + 0x8bc: 68, + 0x8bd: 68, + 0x8be: 68, + 0x8bf: 68, + 0x8c0: 68, + 0x8c1: 68, + 0x8c2: 68, + 0x8c3: 68, + 0x8c4: 68, + 0x8c5: 68, + 0x8c6: 68, + 0x8c7: 68, + 0x8e2: 85, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1878: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x202f: 85, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, + 0x10ac0: 68, + 0x10ac1: 68, + 0x10ac2: 68, + 0x10ac3: 68, + 0x10ac4: 68, + 0x10ac5: 82, + 0x10ac6: 85, + 0x10ac7: 82, + 0x10ac8: 85, + 0x10ac9: 82, + 0x10aca: 82, + 0x10acb: 85, + 0x10acc: 85, + 0x10acd: 76, + 0x10ace: 82, + 0x10acf: 82, + 0x10ad0: 82, + 0x10ad1: 82, + 0x10ad2: 82, + 0x10ad3: 68, + 0x10ad4: 68, + 0x10ad5: 68, + 0x10ad6: 68, + 0x10ad7: 76, + 0x10ad8: 68, + 0x10ad9: 68, + 0x10ada: 68, + 0x10adb: 68, + 0x10adc: 68, + 0x10add: 82, + 0x10ade: 68, + 0x10adf: 68, + 0x10ae0: 68, + 0x10ae1: 82, + 0x10ae2: 85, + 0x10ae3: 85, + 0x10ae4: 82, + 0x10aeb: 68, + 0x10aec: 68, + 0x10aed: 68, + 0x10aee: 68, + 0x10aef: 82, + 0x10b80: 68, + 0x10b81: 82, + 0x10b82: 68, + 0x10b83: 82, + 0x10b84: 82, + 0x10b85: 82, + 0x10b86: 68, + 0x10b87: 68, + 0x10b88: 68, + 0x10b89: 82, + 0x10b8a: 68, + 0x10b8b: 68, + 0x10b8c: 82, + 0x10b8d: 68, + 0x10b8e: 82, + 0x10b8f: 82, + 0x10b90: 68, + 0x10b91: 82, + 0x10ba9: 82, + 0x10baa: 82, + 0x10bab: 82, + 0x10bac: 82, + 0x10bad: 68, + 0x10bae: 68, + 0x10baf: 85, + 0x10d00: 76, + 0x10d01: 68, + 0x10d02: 68, + 0x10d03: 68, + 0x10d04: 68, + 0x10d05: 68, + 0x10d06: 68, + 0x10d07: 68, + 0x10d08: 68, + 0x10d09: 68, + 0x10d0a: 68, + 0x10d0b: 68, + 0x10d0c: 68, + 0x10d0d: 68, + 0x10d0e: 68, + 0x10d0f: 68, + 0x10d10: 68, + 0x10d11: 68, + 0x10d12: 68, + 0x10d13: 68, + 0x10d14: 68, + 0x10d15: 68, + 0x10d16: 68, + 0x10d17: 68, + 0x10d18: 68, + 0x10d19: 68, + 0x10d1a: 68, + 0x10d1b: 68, + 0x10d1c: 68, + 0x10d1d: 68, + 0x10d1e: 68, + 0x10d1f: 68, + 0x10d20: 68, + 0x10d21: 68, + 0x10d22: 82, + 0x10d23: 68, + 0x10f30: 68, + 0x10f31: 68, + 0x10f32: 68, + 0x10f33: 82, + 0x10f34: 68, + 0x10f35: 68, + 0x10f36: 68, + 0x10f37: 68, + 0x10f38: 68, + 0x10f39: 68, + 0x10f3a: 68, + 0x10f3b: 68, + 0x10f3c: 68, + 0x10f3d: 68, + 0x10f3e: 68, + 0x10f3f: 68, + 0x10f40: 68, + 0x10f41: 68, + 0x10f42: 68, + 0x10f43: 68, + 0x10f44: 68, + 0x10f45: 85, + 0x10f51: 68, + 0x10f52: 68, + 0x10f53: 68, + 0x10f54: 82, + 0x10fb0: 68, + 0x10fb1: 85, + 0x10fb2: 68, + 0x10fb3: 68, + 0x10fb4: 82, + 0x10fb5: 82, + 0x10fb6: 82, + 0x10fb7: 85, + 0x10fb8: 68, + 0x10fb9: 82, + 0x10fba: 82, + 0x10fbb: 68, + 0x10fbc: 68, + 0x10fbd: 82, + 0x10fbe: 68, + 0x10fbf: 68, + 0x10fc0: 85, + 0x10fc1: 68, + 0x10fc2: 82, + 0x10fc3: 82, + 0x10fc4: 68, + 0x10fc5: 85, + 0x10fc6: 85, + 0x10fc7: 85, + 0x10fc8: 85, + 0x10fc9: 82, + 0x10fca: 68, + 0x10fcb: 76, + 0x110bd: 85, + 0x110cd: 85, + 0x1e900: 68, + 0x1e901: 68, + 0x1e902: 68, + 0x1e903: 68, + 0x1e904: 68, + 0x1e905: 68, + 0x1e906: 68, + 0x1e907: 68, + 0x1e908: 68, + 0x1e909: 68, + 0x1e90a: 68, + 0x1e90b: 68, + 0x1e90c: 68, + 0x1e90d: 68, + 0x1e90e: 68, + 0x1e90f: 68, + 0x1e910: 68, + 0x1e911: 68, + 0x1e912: 68, + 0x1e913: 68, + 0x1e914: 68, + 0x1e915: 68, + 0x1e916: 68, + 0x1e917: 68, + 0x1e918: 68, + 0x1e919: 68, + 0x1e91a: 68, + 0x1e91b: 68, + 0x1e91c: 68, + 0x1e91d: 68, + 0x1e91e: 68, + 0x1e91f: 68, + 0x1e920: 68, + 0x1e921: 68, + 0x1e922: 68, + 0x1e923: 68, + 0x1e924: 68, + 0x1e925: 68, + 0x1e926: 68, + 0x1e927: 68, + 0x1e928: 68, + 0x1e929: 68, + 0x1e92a: 68, + 0x1e92b: 68, + 0x1e92c: 68, + 0x1e92d: 68, + 0x1e92e: 68, + 0x1e92f: 68, + 0x1e930: 68, + 0x1e931: 68, + 0x1e932: 68, + 0x1e933: 68, + 0x1e934: 68, + 0x1e935: 68, + 0x1e936: 68, + 0x1e937: 68, + 0x1e938: 68, + 0x1e939: 68, + 0x1e93a: 68, + 0x1e93b: 68, + 0x1e93c: 68, + 0x1e93d: 68, + 0x1e93e: 68, + 0x1e93f: 68, + 0x1e940: 68, + 0x1e941: 68, + 0x1e942: 68, + 0x1e943: 68, + 0x1e94b: 84, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052a, + 0x52b0000052c, + 0x52d0000052e, + 0x52f00000530, + 0x5590000055a, + 0x56000000587, + 0x58800000589, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5ef000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x7fd000007fe, + 0x8000000082e, + 0x8400000085c, + 0x8600000086b, + 0x8a0000008b5, + 0x8b6000008c8, + 0x8d3000008e2, + 0x8e300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0x9fc000009fd, + 0x9fe000009ff, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xaf900000b00, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5500000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0000000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c3a, + 0xc3d00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5b, + 0xc6000000c64, + 0xc6600000c70, + 0xc8000000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcde00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf3, + 0xd0000000d0d, + 0xd0e00000d11, + 0xd1200000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5400000d58, + 0xd5f00000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8100000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xde600000df0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8600000e8b, + 0xe8c00000ea4, + 0xea500000ea6, + 0xea700000eb3, + 0xeb400000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ece, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f6, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x16f1000016f9, + 0x17000000170d, + 0x170e00001715, + 0x172000001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001879, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191f, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1ab000001abe, + 0x1abf00001ac1, + 0x1b0000001b4c, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cfb, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001dfa, + 0x1dfb00001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c5f, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x310500003130, + 0x31a0000031c0, + 0x31f000003200, + 0x340000004dc0, + 0x4e0000009ffd, + 0xa0000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa6990000a69a, + 0xa69b0000a69c, + 0xa69e0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a790, + 0xa7910000a792, + 0xa7930000a796, + 0xa7970000a798, + 0xa7990000a79a, + 0xa79b0000a79c, + 0xa79d0000a79e, + 0xa79f0000a7a0, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7af0000a7b0, + 0xa7b50000a7b6, + 0xa7b70000a7b8, + 0xa7b90000a7ba, + 0xa7bb0000a7bc, + 0xa7bd0000a7be, + 0xa7bf0000a7c0, + 0xa7c30000a7c4, + 0xa7c80000a7c9, + 0xa7ca0000a7cb, + 0xa7f60000a7f8, + 0xa7fa0000a828, + 0xa82c0000a82d, + 0xa8400000a874, + 0xa8800000a8c6, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa8fd0000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xa9e00000a9ff, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xab300000ab5b, + 0xab600000ab6a, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe30, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x102e0000102e1, + 0x1030000010320, + 0x1032d00010341, + 0x103420001034a, + 0x103500001037b, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x104d8000104fc, + 0x1050000010528, + 0x1053000010564, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1086000010877, + 0x108800001089f, + 0x108e0000108f3, + 0x108f4000108f6, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a36, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10a8000010a9d, + 0x10ac000010ac8, + 0x10ac900010ae7, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10b8000010b92, + 0x10c0000010c49, + 0x10cc000010cf3, + 0x10d0000010d28, + 0x10d3000010d3a, + 0x10e8000010eaa, + 0x10eab00010ead, + 0x10eb000010eb2, + 0x10f0000010f1d, + 0x10f2700010f28, + 0x10f3000010f51, + 0x10fb000010fc5, + 0x10fe000010ff7, + 0x1100000011047, + 0x1106600011070, + 0x1107f000110bb, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111c9000111cd, + 0x111ce000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e0001123f, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133b00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x1145e00011462, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b9, + 0x116c0000116ca, + 0x117000001171b, + 0x1171d0001172c, + 0x117300001173a, + 0x118000001183b, + 0x118c0000118ea, + 0x118ff00011907, + 0x119090001190a, + 0x1190c00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193b00011944, + 0x119500001195a, + 0x119a0000119a8, + 0x119aa000119d8, + 0x119da000119e2, + 0x119e3000119e5, + 0x11a0000011a3f, + 0x11a4700011a48, + 0x11a5000011a9a, + 0x11a9d00011a9e, + 0x11ac000011af9, + 0x11c0000011c09, + 0x11c0a00011c37, + 0x11c3800011c41, + 0x11c5000011c5a, + 0x11c7200011c90, + 0x11c9200011ca8, + 0x11ca900011cb7, + 0x11d0000011d07, + 0x11d0800011d0a, + 0x11d0b00011d37, + 0x11d3a00011d3b, + 0x11d3c00011d3e, + 0x11d3f00011d48, + 0x11d5000011d5a, + 0x11d6000011d66, + 0x11d6700011d69, + 0x11d6a00011d8f, + 0x11d9000011d92, + 0x11d9300011d99, + 0x11da000011daa, + 0x11ee000011ef7, + 0x11fb000011fb1, + 0x120000001239a, + 0x1248000012544, + 0x130000001342f, + 0x1440000014647, + 0x1680000016a39, + 0x16a4000016a5f, + 0x16a6000016a6a, + 0x16ad000016aee, + 0x16af000016af5, + 0x16b0000016b37, + 0x16b4000016b44, + 0x16b5000016b5a, + 0x16b6300016b78, + 0x16b7d00016b90, + 0x16e6000016e80, + 0x16f0000016f4b, + 0x16f4f00016f88, + 0x16f8f00016fa0, + 0x16fe000016fe2, + 0x16fe300016fe5, + 0x16ff000016ff2, + 0x17000000187f8, + 0x1880000018cd6, + 0x18d0000018d09, + 0x1b0000001b11f, + 0x1b1500001b153, + 0x1b1640001b168, + 0x1b1700001b2fc, + 0x1bc000001bc6b, + 0x1bc700001bc7d, + 0x1bc800001bc89, + 0x1bc900001bc9a, + 0x1bc9d0001bc9f, + 0x1da000001da37, + 0x1da3b0001da6d, + 0x1da750001da76, + 0x1da840001da85, + 0x1da9b0001daa0, + 0x1daa10001dab0, + 0x1e0000001e007, + 0x1e0080001e019, + 0x1e01b0001e022, + 0x1e0230001e025, + 0x1e0260001e02b, + 0x1e1000001e12d, + 0x1e1300001e13e, + 0x1e1400001e14a, + 0x1e14e0001e14f, + 0x1e2c00001e2fa, + 0x1e8000001e8c5, + 0x1e8d00001e8d7, + 0x1e9220001e94c, + 0x1e9500001e95a, + 0x1fbf00001fbfa, + 0x200000002a6de, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x300000003134b, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/lib/idna/intranges.py b/lib/idna/intranges.py new file mode 100644 index 0000000..fa8a735 --- /dev/null +++ b/lib/idna/intranges.py @@ -0,0 +1,53 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + +def intranges_from_list(list_): + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start, end): + return (start << 32) | end + +def _decode_range(r): + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_, ranges): + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/lib/idna/package_data.py b/lib/idna/package_data.py new file mode 100644 index 0000000..ce1c521 --- /dev/null +++ b/lib/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '2.10' + diff --git a/lib/idna/uts46data.py b/lib/idna/uts46data.py new file mode 100644 index 0000000..3766dd4 --- /dev/null +++ b/lib/idna/uts46data.py @@ -0,0 +1,8357 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "13.0.0" +def _seg_0(): + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', u'a'), + (0x42, 'M', u'b'), + (0x43, 'M', u'c'), + (0x44, 'M', u'd'), + (0x45, 'M', u'e'), + (0x46, 'M', u'f'), + (0x47, 'M', u'g'), + (0x48, 'M', u'h'), + (0x49, 'M', u'i'), + (0x4A, 'M', u'j'), + (0x4B, 'M', u'k'), + (0x4C, 'M', u'l'), + (0x4D, 'M', u'm'), + (0x4E, 'M', u'n'), + (0x4F, 'M', u'o'), + (0x50, 'M', u'p'), + (0x51, 'M', u'q'), + (0x52, 'M', u'r'), + (0x53, 'M', u's'), + (0x54, 'M', u't'), + (0x55, 'M', u'u'), + (0x56, 'M', u'v'), + (0x57, 'M', u'w'), + (0x58, 'M', u'x'), + (0x59, 'M', u'y'), + (0x5A, 'M', u'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1(): + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', u' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', u' ̈'), + (0xA9, 'V'), + (0xAA, 'M', u'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', u' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', u'2'), + (0xB3, 'M', u'3'), + (0xB4, '3', u' ́'), + (0xB5, 'M', u'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', u' ̧'), + (0xB9, 'M', u'1'), + (0xBA, 'M', u'o'), + (0xBB, 'V'), + (0xBC, 'M', u'1⁄4'), + (0xBD, 'M', u'1⁄2'), + (0xBE, 'M', u'3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', u'à'), + (0xC1, 'M', u'á'), + (0xC2, 'M', u'â'), + (0xC3, 'M', u'ã'), + (0xC4, 'M', u'ä'), + (0xC5, 'M', u'å'), + (0xC6, 'M', u'æ'), + (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ + (0xC8, 'M', u'è'), + (0xC9, 'M', u'é'), + (0xCA, 'M', u'ê'), + (0xCB, 'M', u'ë'), + (0xCC, 'M', u'ì'), + (0xCD, 'M', u'í'), + (0xCE, 'M', u'î'), + (0xCF, 'M', u'ï'), + (0xD0, 'M', u'ð'), + (0xD1, 'M', u'ñ'), + (0xD2, 'M', u'ò'), + (0xD3, 'M', u'ó'), + (0xD4, 'M', u'ô'), + (0xD5, 'M', u'õ'), + (0xD6, 'M', u'ö'), + (0xD7, 'V'), + (0xD8, 'M', u'ø'), + (0xD9, 'M', u'ù'), + (0xDA, 'M', u'ú'), + (0xDB, 'M', u'û'), + (0xDC, 'M', u'ü'), + (0xDD, 'M', u'ý'), + (0xDE, 'M', u'þ'), + (0xDF, 'D', u'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', u'ā'), + (0x101, 'V'), + (0x102, 'M', u'ă'), + (0x103, 'V'), + (0x104, 'M', u'ą'), + (0x105, 'V'), + (0x106, 'M', u'ć'), + (0x107, 'V'), + (0x108, 'M', u'ĉ'), + (0x109, 'V'), + (0x10A, 'M', u'ċ'), + (0x10B, 'V'), + (0x10C, 'M', u'č'), + (0x10D, 'V'), + (0x10E, 'M', u'ď'), + (0x10F, 'V'), + (0x110, 'M', u'đ'), + (0x111, 'V'), + (0x112, 'M', u'ē'), + (0x113, 'V'), + (0x114, 'M', u'ĕ'), + (0x115, 'V'), + (0x116, 'M', u'ė'), + (0x117, 'V'), + (0x118, 'M', u'ę'), + (0x119, 'V'), + (0x11A, 'M', u'ě'), + (0x11B, 'V'), + (0x11C, 'M', u'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', u'ğ'), + (0x11F, 'V'), + (0x120, 'M', u'ġ'), + (0x121, 'V'), + (0x122, 'M', u'ģ'), + (0x123, 'V'), + (0x124, 'M', u'ĥ'), + (0x125, 'V'), + (0x126, 'M', u'ħ'), + (0x127, 'V'), + (0x128, 'M', u'ĩ'), + (0x129, 'V'), + (0x12A, 'M', u'ī'), + (0x12B, 'V'), + ] + +def _seg_3(): + return [ + (0x12C, 'M', u'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', u'į'), + (0x12F, 'V'), + (0x130, 'M', u'i̇'), + (0x131, 'V'), + (0x132, 'M', u'ij'), + (0x134, 'M', u'ĵ'), + (0x135, 'V'), + (0x136, 'M', u'ķ'), + (0x137, 'V'), + (0x139, 'M', u'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', u'ļ'), + (0x13C, 'V'), + (0x13D, 'M', u'ľ'), + (0x13E, 'V'), + (0x13F, 'M', u'l·'), + (0x141, 'M', u'ł'), + (0x142, 'V'), + (0x143, 'M', u'ń'), + (0x144, 'V'), + (0x145, 'M', u'ņ'), + (0x146, 'V'), + (0x147, 'M', u'ň'), + (0x148, 'V'), + (0x149, 'M', u'ʼn'), + (0x14A, 'M', u'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', u'ō'), + (0x14D, 'V'), + (0x14E, 'M', u'ŏ'), + (0x14F, 'V'), + (0x150, 'M', u'ő'), + (0x151, 'V'), + (0x152, 'M', u'œ'), + (0x153, 'V'), + (0x154, 'M', u'ŕ'), + (0x155, 'V'), + (0x156, 'M', u'ŗ'), + (0x157, 'V'), + (0x158, 'M', u'ř'), + (0x159, 'V'), + (0x15A, 'M', u'ś'), + (0x15B, 'V'), + (0x15C, 'M', u'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', u'ş'), + (0x15F, 'V'), + (0x160, 'M', u'š'), + (0x161, 'V'), + (0x162, 'M', u'ţ'), + (0x163, 'V'), + (0x164, 'M', u'ť'), + (0x165, 'V'), + (0x166, 'M', u'ŧ'), + (0x167, 'V'), + (0x168, 'M', u'ũ'), + (0x169, 'V'), + (0x16A, 'M', u'ū'), + (0x16B, 'V'), + (0x16C, 'M', u'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', u'ů'), + (0x16F, 'V'), + (0x170, 'M', u'ű'), + (0x171, 'V'), + (0x172, 'M', u'ų'), + (0x173, 'V'), + (0x174, 'M', u'ŵ'), + (0x175, 'V'), + (0x176, 'M', u'ŷ'), + (0x177, 'V'), + (0x178, 'M', u'ÿ'), + (0x179, 'M', u'ź'), + (0x17A, 'V'), + (0x17B, 'M', u'ż'), + (0x17C, 'V'), + (0x17D, 'M', u'ž'), + (0x17E, 'V'), + (0x17F, 'M', u's'), + (0x180, 'V'), + (0x181, 'M', u'ɓ'), + (0x182, 'M', u'ƃ'), + (0x183, 'V'), + (0x184, 'M', u'ƅ'), + (0x185, 'V'), + (0x186, 'M', u'ɔ'), + (0x187, 'M', u'ƈ'), + (0x188, 'V'), + (0x189, 'M', u'ɖ'), + (0x18A, 'M', u'ɗ'), + (0x18B, 'M', u'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', u'ǝ'), + (0x18F, 'M', u'ə'), + (0x190, 'M', u'ɛ'), + (0x191, 'M', u'ƒ'), + (0x192, 'V'), + (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ + (0x194, 'M', u'ɣ'), + (0x195, 'V'), + (0x196, 'M', u'ɩ'), + (0x197, 'M', u'ɨ'), + (0x198, 'M', u'ƙ'), + (0x199, 'V'), + (0x19C, 'M', u'ɯ'), + (0x19D, 'M', u'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', u'ɵ'), + (0x1A0, 'M', u'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', u'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', u'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', u'ʀ'), + (0x1A7, 'M', u'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', u'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', u'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', u'ʈ'), + (0x1AF, 'M', u'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', u'ʊ'), + (0x1B2, 'M', u'ʋ'), + (0x1B3, 'M', u'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', u'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', u'ʒ'), + (0x1B8, 'M', u'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', u'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', u'dž'), + (0x1C7, 'M', u'lj'), + (0x1CA, 'M', u'nj'), + (0x1CD, 'M', u'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', u'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', u'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', u'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', u'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', u'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', u'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', u'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', u'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', u'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', u'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', u'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', u'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', u'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', u'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', u'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', u'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', u'dz'), + (0x1F4, 'M', u'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', u'ƕ'), + (0x1F7, 'M', u'ƿ'), + (0x1F8, 'M', u'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', u'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', u'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', u'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', u'ȁ'), + (0x201, 'V'), + (0x202, 'M', u'ȃ'), + (0x203, 'V'), + (0x204, 'M', u'ȅ'), + (0x205, 'V'), + (0x206, 'M', u'ȇ'), + (0x207, 'V'), + (0x208, 'M', u'ȉ'), + (0x209, 'V'), + (0x20A, 'M', u'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ + (0x20D, 'V'), + (0x20E, 'M', u'ȏ'), + (0x20F, 'V'), + (0x210, 'M', u'ȑ'), + (0x211, 'V'), + (0x212, 'M', u'ȓ'), + (0x213, 'V'), + (0x214, 'M', u'ȕ'), + (0x215, 'V'), + (0x216, 'M', u'ȗ'), + (0x217, 'V'), + (0x218, 'M', u'ș'), + (0x219, 'V'), + (0x21A, 'M', u'ț'), + (0x21B, 'V'), + (0x21C, 'M', u'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', u'ȟ'), + (0x21F, 'V'), + (0x220, 'M', u'ƞ'), + (0x221, 'V'), + (0x222, 'M', u'ȣ'), + (0x223, 'V'), + (0x224, 'M', u'ȥ'), + (0x225, 'V'), + (0x226, 'M', u'ȧ'), + (0x227, 'V'), + (0x228, 'M', u'ȩ'), + (0x229, 'V'), + (0x22A, 'M', u'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', u'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', u'ȯ'), + (0x22F, 'V'), + (0x230, 'M', u'ȱ'), + (0x231, 'V'), + (0x232, 'M', u'ȳ'), + (0x233, 'V'), + (0x23A, 'M', u'ⱥ'), + (0x23B, 'M', u'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', u'ƚ'), + (0x23E, 'M', u'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', u'ɂ'), + (0x242, 'V'), + (0x243, 'M', u'ƀ'), + (0x244, 'M', u'ʉ'), + (0x245, 'M', u'ʌ'), + (0x246, 'M', u'ɇ'), + (0x247, 'V'), + (0x248, 'M', u'ɉ'), + (0x249, 'V'), + (0x24A, 'M', u'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', u'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', u'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', u'h'), + (0x2B1, 'M', u'ɦ'), + (0x2B2, 'M', u'j'), + (0x2B3, 'M', u'r'), + (0x2B4, 'M', u'ɹ'), + (0x2B5, 'M', u'ɻ'), + (0x2B6, 'M', u'ʁ'), + (0x2B7, 'M', u'w'), + (0x2B8, 'M', u'y'), + (0x2B9, 'V'), + (0x2D8, '3', u' ̆'), + (0x2D9, '3', u' ̇'), + (0x2DA, '3', u' ̊'), + (0x2DB, '3', u' ̨'), + (0x2DC, '3', u' ̃'), + (0x2DD, '3', u' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', u'ɣ'), + (0x2E1, 'M', u'l'), + (0x2E2, 'M', u's'), + (0x2E3, 'M', u'x'), + (0x2E4, 'M', u'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', u'̀'), + (0x341, 'M', u'́'), + (0x342, 'V'), + (0x343, 'M', u'̓'), + (0x344, 'M', u'̈́'), + (0x345, 'M', u'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', u'ͱ'), + (0x371, 'V'), + (0x372, 'M', u'ͳ'), + (0x373, 'V'), + (0x374, 'M', u'ʹ'), + (0x375, 'V'), + (0x376, 'M', u'ͷ'), + (0x377, 'V'), + ] + +def _seg_6(): + return [ + (0x378, 'X'), + (0x37A, '3', u' ι'), + (0x37B, 'V'), + (0x37E, '3', u';'), + (0x37F, 'M', u'ϳ'), + (0x380, 'X'), + (0x384, '3', u' ́'), + (0x385, '3', u' ̈́'), + (0x386, 'M', u'ά'), + (0x387, 'M', u'·'), + (0x388, 'M', u'έ'), + (0x389, 'M', u'ή'), + (0x38A, 'M', u'ί'), + (0x38B, 'X'), + (0x38C, 'M', u'ό'), + (0x38D, 'X'), + (0x38E, 'M', u'ύ'), + (0x38F, 'M', u'ώ'), + (0x390, 'V'), + (0x391, 'M', u'α'), + (0x392, 'M', u'β'), + (0x393, 'M', u'γ'), + (0x394, 'M', u'δ'), + (0x395, 'M', u'ε'), + (0x396, 'M', u'ζ'), + (0x397, 'M', u'η'), + (0x398, 'M', u'θ'), + (0x399, 'M', u'ι'), + (0x39A, 'M', u'κ'), + (0x39B, 'M', u'λ'), + (0x39C, 'M', u'μ'), + (0x39D, 'M', u'ν'), + (0x39E, 'M', u'ξ'), + (0x39F, 'M', u'ο'), + (0x3A0, 'M', u'π'), + (0x3A1, 'M', u'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', u'σ'), + (0x3A4, 'M', u'τ'), + (0x3A5, 'M', u'υ'), + (0x3A6, 'M', u'φ'), + (0x3A7, 'M', u'χ'), + (0x3A8, 'M', u'ψ'), + (0x3A9, 'M', u'ω'), + (0x3AA, 'M', u'ϊ'), + (0x3AB, 'M', u'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', u'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', u'ϗ'), + (0x3D0, 'M', u'β'), + (0x3D1, 'M', u'θ'), + (0x3D2, 'M', u'υ'), + (0x3D3, 'M', u'ύ'), + (0x3D4, 'M', u'ϋ'), + (0x3D5, 'M', u'φ'), + (0x3D6, 'M', u'π'), + (0x3D7, 'V'), + (0x3D8, 'M', u'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', u'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', u'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', u'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', u'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', u'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', u'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', u'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', u'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', u'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', u'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', u'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', u'κ'), + (0x3F1, 'M', u'ρ'), + (0x3F2, 'M', u'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', u'θ'), + (0x3F5, 'M', u'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', u'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', u'σ'), + (0x3FA, 'M', u'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', u'ͻ'), + (0x3FE, 'M', u'ͼ'), + (0x3FF, 'M', u'ͽ'), + (0x400, 'M', u'ѐ'), + (0x401, 'M', u'ё'), + (0x402, 'M', u'ђ'), + ] + +def _seg_7(): + return [ + (0x403, 'M', u'ѓ'), + (0x404, 'M', u'є'), + (0x405, 'M', u'ѕ'), + (0x406, 'M', u'і'), + (0x407, 'M', u'ї'), + (0x408, 'M', u'ј'), + (0x409, 'M', u'љ'), + (0x40A, 'M', u'њ'), + (0x40B, 'M', u'ћ'), + (0x40C, 'M', u'ќ'), + (0x40D, 'M', u'ѝ'), + (0x40E, 'M', u'ў'), + (0x40F, 'M', u'џ'), + (0x410, 'M', u'а'), + (0x411, 'M', u'б'), + (0x412, 'M', u'в'), + (0x413, 'M', u'г'), + (0x414, 'M', u'д'), + (0x415, 'M', u'е'), + (0x416, 'M', u'ж'), + (0x417, 'M', u'з'), + (0x418, 'M', u'и'), + (0x419, 'M', u'й'), + (0x41A, 'M', u'к'), + (0x41B, 'M', u'л'), + (0x41C, 'M', u'м'), + (0x41D, 'M', u'н'), + (0x41E, 'M', u'о'), + (0x41F, 'M', u'п'), + (0x420, 'M', u'р'), + (0x421, 'M', u'с'), + (0x422, 'M', u'т'), + (0x423, 'M', u'у'), + (0x424, 'M', u'ф'), + (0x425, 'M', u'х'), + (0x426, 'M', u'ц'), + (0x427, 'M', u'ч'), + (0x428, 'M', u'ш'), + (0x429, 'M', u'щ'), + (0x42A, 'M', u'ъ'), + (0x42B, 'M', u'ы'), + (0x42C, 'M', u'ь'), + (0x42D, 'M', u'э'), + (0x42E, 'M', u'ю'), + (0x42F, 'M', u'я'), + (0x430, 'V'), + (0x460, 'M', u'ѡ'), + (0x461, 'V'), + (0x462, 'M', u'ѣ'), + (0x463, 'V'), + (0x464, 'M', u'ѥ'), + (0x465, 'V'), + (0x466, 'M', u'ѧ'), + (0x467, 'V'), + (0x468, 'M', u'ѩ'), + (0x469, 'V'), + (0x46A, 'M', u'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', u'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', u'ѯ'), + (0x46F, 'V'), + (0x470, 'M', u'ѱ'), + (0x471, 'V'), + (0x472, 'M', u'ѳ'), + (0x473, 'V'), + (0x474, 'M', u'ѵ'), + (0x475, 'V'), + (0x476, 'M', u'ѷ'), + (0x477, 'V'), + (0x478, 'M', u'ѹ'), + (0x479, 'V'), + (0x47A, 'M', u'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', u'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', u'ѿ'), + (0x47F, 'V'), + (0x480, 'M', u'ҁ'), + (0x481, 'V'), + (0x48A, 'M', u'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', u'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', u'ҏ'), + (0x48F, 'V'), + (0x490, 'M', u'ґ'), + (0x491, 'V'), + (0x492, 'M', u'ғ'), + (0x493, 'V'), + (0x494, 'M', u'ҕ'), + (0x495, 'V'), + (0x496, 'M', u'җ'), + (0x497, 'V'), + (0x498, 'M', u'ҙ'), + (0x499, 'V'), + (0x49A, 'M', u'қ'), + (0x49B, 'V'), + (0x49C, 'M', u'ҝ'), + (0x49D, 'V'), + ] + +def _seg_8(): + return [ + (0x49E, 'M', u'ҟ'), + (0x49F, 'V'), + (0x4A0, 'M', u'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', u'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', u'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', u'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', u'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', u'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', u'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', u'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', u'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', u'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', u'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', u'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', u'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', u'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', u'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', u'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', u'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', u'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', u'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', u'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', u'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', u'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', u'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', u'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', u'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', u'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', u'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', u'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', u'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', u'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', u'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', u'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', u'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', u'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', u'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', u'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', u'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', u'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', u'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', u'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', u'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', u'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', u'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', u'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', u'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', u'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', u'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', u'ԁ'), + (0x501, 'V'), + (0x502, 'M', u'ԃ'), + ] + +def _seg_9(): + return [ + (0x503, 'V'), + (0x504, 'M', u'ԅ'), + (0x505, 'V'), + (0x506, 'M', u'ԇ'), + (0x507, 'V'), + (0x508, 'M', u'ԉ'), + (0x509, 'V'), + (0x50A, 'M', u'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', u'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', u'ԏ'), + (0x50F, 'V'), + (0x510, 'M', u'ԑ'), + (0x511, 'V'), + (0x512, 'M', u'ԓ'), + (0x513, 'V'), + (0x514, 'M', u'ԕ'), + (0x515, 'V'), + (0x516, 'M', u'ԗ'), + (0x517, 'V'), + (0x518, 'M', u'ԙ'), + (0x519, 'V'), + (0x51A, 'M', u'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', u'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', u'ԟ'), + (0x51F, 'V'), + (0x520, 'M', u'ԡ'), + (0x521, 'V'), + (0x522, 'M', u'ԣ'), + (0x523, 'V'), + (0x524, 'M', u'ԥ'), + (0x525, 'V'), + (0x526, 'M', u'ԧ'), + (0x527, 'V'), + (0x528, 'M', u'ԩ'), + (0x529, 'V'), + (0x52A, 'M', u'ԫ'), + (0x52B, 'V'), + (0x52C, 'M', u'ԭ'), + (0x52D, 'V'), + (0x52E, 'M', u'ԯ'), + (0x52F, 'V'), + (0x530, 'X'), + (0x531, 'M', u'ա'), + (0x532, 'M', u'բ'), + (0x533, 'M', u'գ'), + (0x534, 'M', u'դ'), + (0x535, 'M', u'ե'), + (0x536, 'M', u'զ'), + (0x537, 'M', u'է'), + (0x538, 'M', u'ը'), + (0x539, 'M', u'թ'), + (0x53A, 'M', u'ժ'), + (0x53B, 'M', u'ի'), + (0x53C, 'M', u'լ'), + (0x53D, 'M', u'խ'), + (0x53E, 'M', u'ծ'), + (0x53F, 'M', u'կ'), + (0x540, 'M', u'հ'), + (0x541, 'M', u'ձ'), + (0x542, 'M', u'ղ'), + (0x543, 'M', u'ճ'), + (0x544, 'M', u'մ'), + (0x545, 'M', u'յ'), + (0x546, 'M', u'ն'), + (0x547, 'M', u'շ'), + (0x548, 'M', u'ո'), + (0x549, 'M', u'չ'), + (0x54A, 'M', u'պ'), + (0x54B, 'M', u'ջ'), + (0x54C, 'M', u'ռ'), + (0x54D, 'M', u'ս'), + (0x54E, 'M', u'վ'), + (0x54F, 'M', u'տ'), + (0x550, 'M', u'ր'), + (0x551, 'M', u'ց'), + (0x552, 'M', u'ւ'), + (0x553, 'M', u'փ'), + (0x554, 'M', u'ք'), + (0x555, 'M', u'օ'), + (0x556, 'M', u'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x587, 'M', u'եւ'), + (0x588, 'V'), + (0x58B, 'X'), + (0x58D, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5EF, 'V'), + (0x5F5, 'X'), + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), + ] + +def _seg_10(): + return [ + (0x675, 'M', u'اٴ'), + (0x676, 'M', u'وٴ'), + (0x677, 'M', u'ۇٴ'), + (0x678, 'M', u'يٴ'), + (0x679, 'V'), + (0x6DD, 'X'), + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x7FD, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x860, 'V'), + (0x86B, 'X'), + (0x8A0, 'V'), + (0x8B5, 'X'), + (0x8B6, 'V'), + (0x8C8, 'X'), + (0x8D3, 'V'), + (0x8E2, 'X'), + (0x8E3, 'V'), + (0x958, 'M', u'क़'), + (0x959, 'M', u'ख़'), + (0x95A, 'M', u'ग़'), + (0x95B, 'M', u'ज़'), + (0x95C, 'M', u'ड़'), + (0x95D, 'M', u'ढ़'), + (0x95E, 'M', u'फ़'), + (0x95F, 'M', u'य़'), + (0x960, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', u'ড়'), + (0x9DD, 'M', u'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', u'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FF, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', u'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', u'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + (0xA59, 'M', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), + ] + +def _seg_11(): + return [ + (0xA5C, 'V'), + (0xA5D, 'X'), + (0xA5E, 'M', u'ਫ਼'), + (0xA5F, 'X'), + (0xA66, 'V'), + (0xA77, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xAF9, 'V'), + (0xB00, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB55, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', u'ଡ଼'), + (0xB5D, 'M', u'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC00, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + ] + +def _seg_12(): + return [ + (0xC29, 'X'), + (0xC2A, 'V'), + (0xC3A, 'X'), + (0xC3D, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5B, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC77, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDE, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF3, 'X'), + (0xD00, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD50, 'X'), + (0xD54, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD80, 'X'), + (0xD81, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDE6, 'V'), + (0xDF0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', u'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + (0xE86, 'V'), + (0xE8B, 'X'), + (0xE8C, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEB3, 'M', u'ໍາ'), + (0xEB4, 'V'), + ] + +def _seg_13(): + return [ + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECE, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', u'ຫນ'), + (0xEDD, 'M', u'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', u'་'), + (0xF0D, 'V'), + (0xF43, 'M', u'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', u'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', u'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', u'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', u'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', u'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', u'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', u'ཱུ'), + (0xF76, 'M', u'ྲྀ'), + (0xF77, 'M', u'ྲཱྀ'), + (0xF78, 'M', u'ླྀ'), + (0xF79, 'M', u'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', u'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', u'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', u'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', u'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', u'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', u'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', u'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', u'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', u'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', u'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + (0x1258, 'V'), + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + ] + +def _seg_14(): + return [ + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F6, 'X'), + (0x13F8, 'M', u'Ᏸ'), + (0x13F9, 'M', u'Ᏹ'), + (0x13FA, 'M', u'Ᏺ'), + (0x13FB, 'M', u'Ᏻ'), + (0x13FC, 'M', u'Ᏼ'), + (0x13FD, 'M', u'Ᏽ'), + (0x13FE, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F9, 'X'), + (0x1700, 'V'), + (0x170D, 'X'), + (0x170E, 'V'), + (0x1715, 'X'), + (0x1720, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1879, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191F, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1AB0, 'V'), + (0x1AC1, 'X'), + (0x1B00, 'V'), + (0x1B4C, 'X'), + (0x1B50, 'V'), + (0x1B7D, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + ] + +def _seg_15(): + return [ + (0x1C80, 'M', u'в'), + (0x1C81, 'M', u'д'), + (0x1C82, 'M', u'о'), + (0x1C83, 'M', u'с'), + (0x1C84, 'M', u'т'), + (0x1C86, 'M', u'ъ'), + (0x1C87, 'M', u'ѣ'), + (0x1C88, 'M', u'ꙋ'), + (0x1C89, 'X'), + (0x1C90, 'M', u'ა'), + (0x1C91, 'M', u'ბ'), + (0x1C92, 'M', u'გ'), + (0x1C93, 'M', u'დ'), + (0x1C94, 'M', u'ე'), + (0x1C95, 'M', u'ვ'), + (0x1C96, 'M', u'ზ'), + (0x1C97, 'M', u'თ'), + (0x1C98, 'M', u'ი'), + (0x1C99, 'M', u'კ'), + (0x1C9A, 'M', u'ლ'), + (0x1C9B, 'M', u'მ'), + (0x1C9C, 'M', u'ნ'), + (0x1C9D, 'M', u'ო'), + (0x1C9E, 'M', u'პ'), + (0x1C9F, 'M', u'ჟ'), + (0x1CA0, 'M', u'რ'), + (0x1CA1, 'M', u'ს'), + (0x1CA2, 'M', u'ტ'), + (0x1CA3, 'M', u'უ'), + (0x1CA4, 'M', u'ფ'), + (0x1CA5, 'M', u'ქ'), + (0x1CA6, 'M', u'ღ'), + (0x1CA7, 'M', u'ყ'), + (0x1CA8, 'M', u'შ'), + (0x1CA9, 'M', u'ჩ'), + (0x1CAA, 'M', u'ც'), + (0x1CAB, 'M', u'ძ'), + (0x1CAC, 'M', u'წ'), + (0x1CAD, 'M', u'ჭ'), + (0x1CAE, 'M', u'ხ'), + (0x1CAF, 'M', u'ჯ'), + (0x1CB0, 'M', u'ჰ'), + (0x1CB1, 'M', u'ჱ'), + (0x1CB2, 'M', u'ჲ'), + (0x1CB3, 'M', u'ჳ'), + (0x1CB4, 'M', u'ჴ'), + (0x1CB5, 'M', u'ჵ'), + (0x1CB6, 'M', u'ჶ'), + (0x1CB7, 'M', u'ჷ'), + (0x1CB8, 'M', u'ჸ'), + (0x1CB9, 'M', u'ჹ'), + (0x1CBA, 'M', u'ჺ'), + (0x1CBB, 'X'), + (0x1CBD, 'M', u'ჽ'), + (0x1CBE, 'M', u'ჾ'), + (0x1CBF, 'M', u'ჿ'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CFB, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', u'a'), + (0x1D2D, 'M', u'æ'), + (0x1D2E, 'M', u'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', u'd'), + (0x1D31, 'M', u'e'), + (0x1D32, 'M', u'ǝ'), + (0x1D33, 'M', u'g'), + (0x1D34, 'M', u'h'), + (0x1D35, 'M', u'i'), + (0x1D36, 'M', u'j'), + (0x1D37, 'M', u'k'), + (0x1D38, 'M', u'l'), + (0x1D39, 'M', u'm'), + (0x1D3A, 'M', u'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', u'o'), + (0x1D3D, 'M', u'ȣ'), + (0x1D3E, 'M', u'p'), + (0x1D3F, 'M', u'r'), + (0x1D40, 'M', u't'), + (0x1D41, 'M', u'u'), + (0x1D42, 'M', u'w'), + (0x1D43, 'M', u'a'), + (0x1D44, 'M', u'ɐ'), + (0x1D45, 'M', u'ɑ'), + (0x1D46, 'M', u'ᴂ'), + (0x1D47, 'M', u'b'), + (0x1D48, 'M', u'd'), + (0x1D49, 'M', u'e'), + (0x1D4A, 'M', u'ə'), + (0x1D4B, 'M', u'ɛ'), + (0x1D4C, 'M', u'ɜ'), + (0x1D4D, 'M', u'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', u'k'), + (0x1D50, 'M', u'm'), + (0x1D51, 'M', u'ŋ'), + (0x1D52, 'M', u'o'), + ] + +def _seg_16(): + return [ + (0x1D53, 'M', u'ɔ'), + (0x1D54, 'M', u'ᴖ'), + (0x1D55, 'M', u'ᴗ'), + (0x1D56, 'M', u'p'), + (0x1D57, 'M', u't'), + (0x1D58, 'M', u'u'), + (0x1D59, 'M', u'ᴝ'), + (0x1D5A, 'M', u'ɯ'), + (0x1D5B, 'M', u'v'), + (0x1D5C, 'M', u'ᴥ'), + (0x1D5D, 'M', u'β'), + (0x1D5E, 'M', u'γ'), + (0x1D5F, 'M', u'δ'), + (0x1D60, 'M', u'φ'), + (0x1D61, 'M', u'χ'), + (0x1D62, 'M', u'i'), + (0x1D63, 'M', u'r'), + (0x1D64, 'M', u'u'), + (0x1D65, 'M', u'v'), + (0x1D66, 'M', u'β'), + (0x1D67, 'M', u'γ'), + (0x1D68, 'M', u'ρ'), + (0x1D69, 'M', u'φ'), + (0x1D6A, 'M', u'χ'), + (0x1D6B, 'V'), + (0x1D78, 'M', u'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', u'ɒ'), + (0x1D9C, 'M', u'c'), + (0x1D9D, 'M', u'ɕ'), + (0x1D9E, 'M', u'ð'), + (0x1D9F, 'M', u'ɜ'), + (0x1DA0, 'M', u'f'), + (0x1DA1, 'M', u'ɟ'), + (0x1DA2, 'M', u'ɡ'), + (0x1DA3, 'M', u'ɥ'), + (0x1DA4, 'M', u'ɨ'), + (0x1DA5, 'M', u'ɩ'), + (0x1DA6, 'M', u'ɪ'), + (0x1DA7, 'M', u'ᵻ'), + (0x1DA8, 'M', u'ʝ'), + (0x1DA9, 'M', u'ɭ'), + (0x1DAA, 'M', u'ᶅ'), + (0x1DAB, 'M', u'ʟ'), + (0x1DAC, 'M', u'ɱ'), + (0x1DAD, 'M', u'ɰ'), + (0x1DAE, 'M', u'ɲ'), + (0x1DAF, 'M', u'ɳ'), + (0x1DB0, 'M', u'ɴ'), + (0x1DB1, 'M', u'ɵ'), + (0x1DB2, 'M', u'ɸ'), + (0x1DB3, 'M', u'ʂ'), + (0x1DB4, 'M', u'ʃ'), + (0x1DB5, 'M', u'ƫ'), + (0x1DB6, 'M', u'ʉ'), + (0x1DB7, 'M', u'ʊ'), + (0x1DB8, 'M', u'ᴜ'), + (0x1DB9, 'M', u'ʋ'), + (0x1DBA, 'M', u'ʌ'), + (0x1DBB, 'M', u'z'), + (0x1DBC, 'M', u'ʐ'), + (0x1DBD, 'M', u'ʑ'), + (0x1DBE, 'M', u'ʒ'), + (0x1DBF, 'M', u'θ'), + (0x1DC0, 'V'), + (0x1DFA, 'X'), + (0x1DFB, 'V'), + (0x1E00, 'M', u'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', u'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', u'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', u'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', u'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', u'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', u'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', u'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', u'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', u'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', u'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', u'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', u'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', u'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', u'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', u'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', u'ḡ'), + ] + +def _seg_17(): + return [ + (0x1E21, 'V'), + (0x1E22, 'M', u'ḣ'), + (0x1E23, 'V'), + (0x1E24, 'M', u'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', u'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', u'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', u'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', u'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', u'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', u'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', u'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', u'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', u'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', u'ḹ'), + (0x1E39, 'V'), + (0x1E3A, 'M', u'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', u'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', u'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', u'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', u'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', u'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', u'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', u'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', u'ṋ'), + (0x1E4B, 'V'), + (0x1E4C, 'M', u'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', u'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', u'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', u'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', u'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', u'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', u'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', u'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', u'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', u'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', u'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', u'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', u'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', u'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', u'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', u'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', u'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', u'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', u'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', u'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', u'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', u'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', u'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', u'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', u'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', u'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', u'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', u'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', u'ẅ'), + ] + +def _seg_18(): + return [ + (0x1E85, 'V'), + (0x1E86, 'M', u'ẇ'), + (0x1E87, 'V'), + (0x1E88, 'M', u'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', u'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', u'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', u'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', u'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', u'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', u'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', u'aʾ'), + (0x1E9B, 'M', u'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', u'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', u'ạ'), + (0x1EA1, 'V'), + (0x1EA2, 'M', u'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', u'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', u'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', u'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', u'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', u'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', u'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', u'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', u'ẳ'), + (0x1EB3, 'V'), + (0x1EB4, 'M', u'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', u'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', u'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', u'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', u'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', u'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', u'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', u'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', u'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', u'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', u'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', u'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', u'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', u'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', u'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', u'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', u'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', u'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', u'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', u'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', u'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', u'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', u'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', u'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', u'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', u'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', u'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', u'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', u'ử'), + (0x1EED, 'V'), + ] + +def _seg_19(): + return [ + (0x1EEE, 'M', u'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', u'ự'), + (0x1EF1, 'V'), + (0x1EF2, 'M', u'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', u'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', u'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', u'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', u'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', u'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', u'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', u'ἀ'), + (0x1F09, 'M', u'ἁ'), + (0x1F0A, 'M', u'ἂ'), + (0x1F0B, 'M', u'ἃ'), + (0x1F0C, 'M', u'ἄ'), + (0x1F0D, 'M', u'ἅ'), + (0x1F0E, 'M', u'ἆ'), + (0x1F0F, 'M', u'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', u'ἐ'), + (0x1F19, 'M', u'ἑ'), + (0x1F1A, 'M', u'ἒ'), + (0x1F1B, 'M', u'ἓ'), + (0x1F1C, 'M', u'ἔ'), + (0x1F1D, 'M', u'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', u'ἠ'), + (0x1F29, 'M', u'ἡ'), + (0x1F2A, 'M', u'ἢ'), + (0x1F2B, 'M', u'ἣ'), + (0x1F2C, 'M', u'ἤ'), + (0x1F2D, 'M', u'ἥ'), + (0x1F2E, 'M', u'ἦ'), + (0x1F2F, 'M', u'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', u'ἰ'), + (0x1F39, 'M', u'ἱ'), + (0x1F3A, 'M', u'ἲ'), + (0x1F3B, 'M', u'ἳ'), + (0x1F3C, 'M', u'ἴ'), + (0x1F3D, 'M', u'ἵ'), + (0x1F3E, 'M', u'ἶ'), + (0x1F3F, 'M', u'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', u'ὀ'), + (0x1F49, 'M', u'ὁ'), + (0x1F4A, 'M', u'ὂ'), + (0x1F4B, 'M', u'ὃ'), + (0x1F4C, 'M', u'ὄ'), + (0x1F4D, 'M', u'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', u'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', u'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', u'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', u'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', u'ὠ'), + (0x1F69, 'M', u'ὡ'), + (0x1F6A, 'M', u'ὢ'), + (0x1F6B, 'M', u'ὣ'), + (0x1F6C, 'M', u'ὤ'), + (0x1F6D, 'M', u'ὥ'), + (0x1F6E, 'M', u'ὦ'), + (0x1F6F, 'M', u'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', u'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', u'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', u'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', u'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', u'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', u'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', u'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', u'ἀι'), + (0x1F81, 'M', u'ἁι'), + (0x1F82, 'M', u'ἂι'), + (0x1F83, 'M', u'ἃι'), + (0x1F84, 'M', u'ἄι'), + ] + +def _seg_20(): + return [ + (0x1F85, 'M', u'ἅι'), + (0x1F86, 'M', u'ἆι'), + (0x1F87, 'M', u'ἇι'), + (0x1F88, 'M', u'ἀι'), + (0x1F89, 'M', u'ἁι'), + (0x1F8A, 'M', u'ἂι'), + (0x1F8B, 'M', u'ἃι'), + (0x1F8C, 'M', u'ἄι'), + (0x1F8D, 'M', u'ἅι'), + (0x1F8E, 'M', u'ἆι'), + (0x1F8F, 'M', u'ἇι'), + (0x1F90, 'M', u'ἠι'), + (0x1F91, 'M', u'ἡι'), + (0x1F92, 'M', u'ἢι'), + (0x1F93, 'M', u'ἣι'), + (0x1F94, 'M', u'ἤι'), + (0x1F95, 'M', u'ἥι'), + (0x1F96, 'M', u'ἦι'), + (0x1F97, 'M', u'ἧι'), + (0x1F98, 'M', u'ἠι'), + (0x1F99, 'M', u'ἡι'), + (0x1F9A, 'M', u'ἢι'), + (0x1F9B, 'M', u'ἣι'), + (0x1F9C, 'M', u'ἤι'), + (0x1F9D, 'M', u'ἥι'), + (0x1F9E, 'M', u'ἦι'), + (0x1F9F, 'M', u'ἧι'), + (0x1FA0, 'M', u'ὠι'), + (0x1FA1, 'M', u'ὡι'), + (0x1FA2, 'M', u'ὢι'), + (0x1FA3, 'M', u'ὣι'), + (0x1FA4, 'M', u'ὤι'), + (0x1FA5, 'M', u'ὥι'), + (0x1FA6, 'M', u'ὦι'), + (0x1FA7, 'M', u'ὧι'), + (0x1FA8, 'M', u'ὠι'), + (0x1FA9, 'M', u'ὡι'), + (0x1FAA, 'M', u'ὢι'), + (0x1FAB, 'M', u'ὣι'), + (0x1FAC, 'M', u'ὤι'), + (0x1FAD, 'M', u'ὥι'), + (0x1FAE, 'M', u'ὦι'), + (0x1FAF, 'M', u'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', u'ὰι'), + (0x1FB3, 'M', u'αι'), + (0x1FB4, 'M', u'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', u'ᾶι'), + (0x1FB8, 'M', u'ᾰ'), + (0x1FB9, 'M', u'ᾱ'), + (0x1FBA, 'M', u'ὰ'), + (0x1FBB, 'M', u'ά'), + (0x1FBC, 'M', u'αι'), + (0x1FBD, '3', u' ̓'), + (0x1FBE, 'M', u'ι'), + (0x1FBF, '3', u' ̓'), + (0x1FC0, '3', u' ͂'), + (0x1FC1, '3', u' ̈͂'), + (0x1FC2, 'M', u'ὴι'), + (0x1FC3, 'M', u'ηι'), + (0x1FC4, 'M', u'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', u'ῆι'), + (0x1FC8, 'M', u'ὲ'), + (0x1FC9, 'M', u'έ'), + (0x1FCA, 'M', u'ὴ'), + (0x1FCB, 'M', u'ή'), + (0x1FCC, 'M', u'ηι'), + (0x1FCD, '3', u' ̓̀'), + (0x1FCE, '3', u' ̓́'), + (0x1FCF, '3', u' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', u'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', u'ῐ'), + (0x1FD9, 'M', u'ῑ'), + (0x1FDA, 'M', u'ὶ'), + (0x1FDB, 'M', u'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', u' ̔̀'), + (0x1FDE, '3', u' ̔́'), + (0x1FDF, '3', u' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', u'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', u'ῠ'), + (0x1FE9, 'M', u'ῡ'), + (0x1FEA, 'M', u'ὺ'), + (0x1FEB, 'M', u'ύ'), + (0x1FEC, 'M', u'ῥ'), + (0x1FED, '3', u' ̈̀'), + (0x1FEE, '3', u' ̈́'), + (0x1FEF, '3', u'`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', u'ὼι'), + (0x1FF3, 'M', u'ωι'), + ] + +def _seg_21(): + return [ + (0x1FF4, 'M', u'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + (0x1FF7, 'M', u'ῶι'), + (0x1FF8, 'M', u'ὸ'), + (0x1FF9, 'M', u'ό'), + (0x1FFA, 'M', u'ὼ'), + (0x1FFB, 'M', u'ώ'), + (0x1FFC, 'M', u'ωι'), + (0x1FFD, '3', u' ́'), + (0x1FFE, '3', u' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', u' '), + (0x200B, 'I'), + (0x200C, 'D', u''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', u'‐'), + (0x2012, 'V'), + (0x2017, '3', u' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + (0x202F, '3', u' '), + (0x2030, 'V'), + (0x2033, 'M', u'′′'), + (0x2034, 'M', u'′′′'), + (0x2035, 'V'), + (0x2036, 'M', u'‵‵'), + (0x2037, 'M', u'‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', u'!!'), + (0x203D, 'V'), + (0x203E, '3', u' ̅'), + (0x203F, 'V'), + (0x2047, '3', u'??'), + (0x2048, '3', u'?!'), + (0x2049, '3', u'!?'), + (0x204A, 'V'), + (0x2057, 'M', u'′′′′'), + (0x2058, 'V'), + (0x205F, '3', u' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', u'0'), + (0x2071, 'M', u'i'), + (0x2072, 'X'), + (0x2074, 'M', u'4'), + (0x2075, 'M', u'5'), + (0x2076, 'M', u'6'), + (0x2077, 'M', u'7'), + (0x2078, 'M', u'8'), + (0x2079, 'M', u'9'), + (0x207A, '3', u'+'), + (0x207B, 'M', u'−'), + (0x207C, '3', u'='), + (0x207D, '3', u'('), + (0x207E, '3', u')'), + (0x207F, 'M', u'n'), + (0x2080, 'M', u'0'), + (0x2081, 'M', u'1'), + (0x2082, 'M', u'2'), + (0x2083, 'M', u'3'), + (0x2084, 'M', u'4'), + (0x2085, 'M', u'5'), + (0x2086, 'M', u'6'), + (0x2087, 'M', u'7'), + (0x2088, 'M', u'8'), + (0x2089, 'M', u'9'), + (0x208A, '3', u'+'), + (0x208B, 'M', u'−'), + (0x208C, '3', u'='), + (0x208D, '3', u'('), + (0x208E, '3', u')'), + (0x208F, 'X'), + (0x2090, 'M', u'a'), + (0x2091, 'M', u'e'), + (0x2092, 'M', u'o'), + (0x2093, 'M', u'x'), + (0x2094, 'M', u'ə'), + (0x2095, 'M', u'h'), + (0x2096, 'M', u'k'), + (0x2097, 'M', u'l'), + (0x2098, 'M', u'm'), + (0x2099, 'M', u'n'), + (0x209A, 'M', u'p'), + (0x209B, 'M', u's'), + (0x209C, 'M', u't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', u'rs'), + (0x20A9, 'V'), + (0x20C0, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', u'a/c'), + (0x2101, '3', u'a/s'), + ] + +def _seg_22(): + return [ + (0x2102, 'M', u'c'), + (0x2103, 'M', u'°c'), + (0x2104, 'V'), + (0x2105, '3', u'c/o'), + (0x2106, '3', u'c/u'), + (0x2107, 'M', u'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', u'°f'), + (0x210A, 'M', u'g'), + (0x210B, 'M', u'h'), + (0x210F, 'M', u'ħ'), + (0x2110, 'M', u'i'), + (0x2112, 'M', u'l'), + (0x2114, 'V'), + (0x2115, 'M', u'n'), + (0x2116, 'M', u'no'), + (0x2117, 'V'), + (0x2119, 'M', u'p'), + (0x211A, 'M', u'q'), + (0x211B, 'M', u'r'), + (0x211E, 'V'), + (0x2120, 'M', u'sm'), + (0x2121, 'M', u'tel'), + (0x2122, 'M', u'tm'), + (0x2123, 'V'), + (0x2124, 'M', u'z'), + (0x2125, 'V'), + (0x2126, 'M', u'ω'), + (0x2127, 'V'), + (0x2128, 'M', u'z'), + (0x2129, 'V'), + (0x212A, 'M', u'k'), + (0x212B, 'M', u'å'), + (0x212C, 'M', u'b'), + (0x212D, 'M', u'c'), + (0x212E, 'V'), + (0x212F, 'M', u'e'), + (0x2131, 'M', u'f'), + (0x2132, 'X'), + (0x2133, 'M', u'm'), + (0x2134, 'M', u'o'), + (0x2135, 'M', u'א'), + (0x2136, 'M', u'ב'), + (0x2137, 'M', u'ג'), + (0x2138, 'M', u'ד'), + (0x2139, 'M', u'i'), + (0x213A, 'V'), + (0x213B, 'M', u'fax'), + (0x213C, 'M', u'π'), + (0x213D, 'M', u'γ'), + (0x213F, 'M', u'π'), + (0x2140, 'M', u'∑'), + (0x2141, 'V'), + (0x2145, 'M', u'd'), + (0x2147, 'M', u'e'), + (0x2148, 'M', u'i'), + (0x2149, 'M', u'j'), + (0x214A, 'V'), + (0x2150, 'M', u'1⁄7'), + (0x2151, 'M', u'1⁄9'), + (0x2152, 'M', u'1⁄10'), + (0x2153, 'M', u'1⁄3'), + (0x2154, 'M', u'2⁄3'), + (0x2155, 'M', u'1⁄5'), + (0x2156, 'M', u'2⁄5'), + (0x2157, 'M', u'3⁄5'), + (0x2158, 'M', u'4⁄5'), + (0x2159, 'M', u'1⁄6'), + (0x215A, 'M', u'5⁄6'), + (0x215B, 'M', u'1⁄8'), + (0x215C, 'M', u'3⁄8'), + (0x215D, 'M', u'5⁄8'), + (0x215E, 'M', u'7⁄8'), + (0x215F, 'M', u'1⁄'), + (0x2160, 'M', u'i'), + (0x2161, 'M', u'ii'), + (0x2162, 'M', u'iii'), + (0x2163, 'M', u'iv'), + (0x2164, 'M', u'v'), + (0x2165, 'M', u'vi'), + (0x2166, 'M', u'vii'), + (0x2167, 'M', u'viii'), + (0x2168, 'M', u'ix'), + (0x2169, 'M', u'x'), + (0x216A, 'M', u'xi'), + (0x216B, 'M', u'xii'), + (0x216C, 'M', u'l'), + (0x216D, 'M', u'c'), + (0x216E, 'M', u'd'), + (0x216F, 'M', u'm'), + (0x2170, 'M', u'i'), + (0x2171, 'M', u'ii'), + (0x2172, 'M', u'iii'), + (0x2173, 'M', u'iv'), + (0x2174, 'M', u'v'), + (0x2175, 'M', u'vi'), + (0x2176, 'M', u'vii'), + (0x2177, 'M', u'viii'), + (0x2178, 'M', u'ix'), + (0x2179, 'M', u'x'), + ] + +def _seg_23(): + return [ + (0x217A, 'M', u'xi'), + (0x217B, 'M', u'xii'), + (0x217C, 'M', u'l'), + (0x217D, 'M', u'c'), + (0x217E, 'M', u'd'), + (0x217F, 'M', u'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', u'0⁄3'), + (0x218A, 'V'), + (0x218C, 'X'), + (0x2190, 'V'), + (0x222C, 'M', u'∫∫'), + (0x222D, 'M', u'∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', u'∮∮'), + (0x2230, 'M', u'∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', u'〈'), + (0x232A, 'M', u'〉'), + (0x232B, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', u'1'), + (0x2461, 'M', u'2'), + (0x2462, 'M', u'3'), + (0x2463, 'M', u'4'), + (0x2464, 'M', u'5'), + (0x2465, 'M', u'6'), + (0x2466, 'M', u'7'), + (0x2467, 'M', u'8'), + (0x2468, 'M', u'9'), + (0x2469, 'M', u'10'), + (0x246A, 'M', u'11'), + (0x246B, 'M', u'12'), + (0x246C, 'M', u'13'), + (0x246D, 'M', u'14'), + (0x246E, 'M', u'15'), + (0x246F, 'M', u'16'), + (0x2470, 'M', u'17'), + (0x2471, 'M', u'18'), + (0x2472, 'M', u'19'), + (0x2473, 'M', u'20'), + (0x2474, '3', u'(1)'), + (0x2475, '3', u'(2)'), + (0x2476, '3', u'(3)'), + (0x2477, '3', u'(4)'), + (0x2478, '3', u'(5)'), + (0x2479, '3', u'(6)'), + (0x247A, '3', u'(7)'), + (0x247B, '3', u'(8)'), + (0x247C, '3', u'(9)'), + (0x247D, '3', u'(10)'), + (0x247E, '3', u'(11)'), + (0x247F, '3', u'(12)'), + (0x2480, '3', u'(13)'), + (0x2481, '3', u'(14)'), + (0x2482, '3', u'(15)'), + (0x2483, '3', u'(16)'), + (0x2484, '3', u'(17)'), + (0x2485, '3', u'(18)'), + (0x2486, '3', u'(19)'), + (0x2487, '3', u'(20)'), + (0x2488, 'X'), + (0x249C, '3', u'(a)'), + (0x249D, '3', u'(b)'), + (0x249E, '3', u'(c)'), + (0x249F, '3', u'(d)'), + (0x24A0, '3', u'(e)'), + (0x24A1, '3', u'(f)'), + (0x24A2, '3', u'(g)'), + (0x24A3, '3', u'(h)'), + (0x24A4, '3', u'(i)'), + (0x24A5, '3', u'(j)'), + (0x24A6, '3', u'(k)'), + (0x24A7, '3', u'(l)'), + (0x24A8, '3', u'(m)'), + (0x24A9, '3', u'(n)'), + (0x24AA, '3', u'(o)'), + (0x24AB, '3', u'(p)'), + (0x24AC, '3', u'(q)'), + (0x24AD, '3', u'(r)'), + (0x24AE, '3', u'(s)'), + (0x24AF, '3', u'(t)'), + (0x24B0, '3', u'(u)'), + (0x24B1, '3', u'(v)'), + (0x24B2, '3', u'(w)'), + (0x24B3, '3', u'(x)'), + (0x24B4, '3', u'(y)'), + (0x24B5, '3', u'(z)'), + (0x24B6, 'M', u'a'), + (0x24B7, 'M', u'b'), + (0x24B8, 'M', u'c'), + (0x24B9, 'M', u'd'), + ] + +def _seg_24(): + return [ + (0x24BA, 'M', u'e'), + (0x24BB, 'M', u'f'), + (0x24BC, 'M', u'g'), + (0x24BD, 'M', u'h'), + (0x24BE, 'M', u'i'), + (0x24BF, 'M', u'j'), + (0x24C0, 'M', u'k'), + (0x24C1, 'M', u'l'), + (0x24C2, 'M', u'm'), + (0x24C3, 'M', u'n'), + (0x24C4, 'M', u'o'), + (0x24C5, 'M', u'p'), + (0x24C6, 'M', u'q'), + (0x24C7, 'M', u'r'), + (0x24C8, 'M', u's'), + (0x24C9, 'M', u't'), + (0x24CA, 'M', u'u'), + (0x24CB, 'M', u'v'), + (0x24CC, 'M', u'w'), + (0x24CD, 'M', u'x'), + (0x24CE, 'M', u'y'), + (0x24CF, 'M', u'z'), + (0x24D0, 'M', u'a'), + (0x24D1, 'M', u'b'), + (0x24D2, 'M', u'c'), + (0x24D3, 'M', u'd'), + (0x24D4, 'M', u'e'), + (0x24D5, 'M', u'f'), + (0x24D6, 'M', u'g'), + (0x24D7, 'M', u'h'), + (0x24D8, 'M', u'i'), + (0x24D9, 'M', u'j'), + (0x24DA, 'M', u'k'), + (0x24DB, 'M', u'l'), + (0x24DC, 'M', u'm'), + (0x24DD, 'M', u'n'), + (0x24DE, 'M', u'o'), + (0x24DF, 'M', u'p'), + (0x24E0, 'M', u'q'), + (0x24E1, 'M', u'r'), + (0x24E2, 'M', u's'), + (0x24E3, 'M', u't'), + (0x24E4, 'M', u'u'), + (0x24E5, 'M', u'v'), + (0x24E6, 'M', u'w'), + (0x24E7, 'M', u'x'), + (0x24E8, 'M', u'y'), + (0x24E9, 'M', u'z'), + (0x24EA, 'M', u'0'), + (0x24EB, 'V'), + (0x2A0C, 'M', u'∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', u'::='), + (0x2A75, '3', u'=='), + (0x2A76, '3', u'==='), + (0x2A77, 'V'), + (0x2ADC, 'M', u'⫝̸'), + (0x2ADD, 'V'), + (0x2B74, 'X'), + (0x2B76, 'V'), + (0x2B96, 'X'), + (0x2B97, 'V'), + (0x2C00, 'M', u'ⰰ'), + (0x2C01, 'M', u'ⰱ'), + (0x2C02, 'M', u'ⰲ'), + (0x2C03, 'M', u'ⰳ'), + (0x2C04, 'M', u'ⰴ'), + (0x2C05, 'M', u'ⰵ'), + (0x2C06, 'M', u'ⰶ'), + (0x2C07, 'M', u'ⰷ'), + (0x2C08, 'M', u'ⰸ'), + (0x2C09, 'M', u'ⰹ'), + (0x2C0A, 'M', u'ⰺ'), + (0x2C0B, 'M', u'ⰻ'), + (0x2C0C, 'M', u'ⰼ'), + (0x2C0D, 'M', u'ⰽ'), + (0x2C0E, 'M', u'ⰾ'), + (0x2C0F, 'M', u'ⰿ'), + (0x2C10, 'M', u'ⱀ'), + (0x2C11, 'M', u'ⱁ'), + (0x2C12, 'M', u'ⱂ'), + (0x2C13, 'M', u'ⱃ'), + (0x2C14, 'M', u'ⱄ'), + (0x2C15, 'M', u'ⱅ'), + (0x2C16, 'M', u'ⱆ'), + (0x2C17, 'M', u'ⱇ'), + (0x2C18, 'M', u'ⱈ'), + (0x2C19, 'M', u'ⱉ'), + (0x2C1A, 'M', u'ⱊ'), + (0x2C1B, 'M', u'ⱋ'), + (0x2C1C, 'M', u'ⱌ'), + (0x2C1D, 'M', u'ⱍ'), + (0x2C1E, 'M', u'ⱎ'), + (0x2C1F, 'M', u'ⱏ'), + (0x2C20, 'M', u'ⱐ'), + (0x2C21, 'M', u'ⱑ'), + (0x2C22, 'M', u'ⱒ'), + (0x2C23, 'M', u'ⱓ'), + (0x2C24, 'M', u'ⱔ'), + (0x2C25, 'M', u'ⱕ'), + ] + +def _seg_25(): + return [ + (0x2C26, 'M', u'ⱖ'), + (0x2C27, 'M', u'ⱗ'), + (0x2C28, 'M', u'ⱘ'), + (0x2C29, 'M', u'ⱙ'), + (0x2C2A, 'M', u'ⱚ'), + (0x2C2B, 'M', u'ⱛ'), + (0x2C2C, 'M', u'ⱜ'), + (0x2C2D, 'M', u'ⱝ'), + (0x2C2E, 'M', u'ⱞ'), + (0x2C2F, 'X'), + (0x2C30, 'V'), + (0x2C5F, 'X'), + (0x2C60, 'M', u'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', u'ɫ'), + (0x2C63, 'M', u'ᵽ'), + (0x2C64, 'M', u'ɽ'), + (0x2C65, 'V'), + (0x2C67, 'M', u'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', u'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', u'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', u'ɑ'), + (0x2C6E, 'M', u'ɱ'), + (0x2C6F, 'M', u'ɐ'), + (0x2C70, 'M', u'ɒ'), + (0x2C71, 'V'), + (0x2C72, 'M', u'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', u'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', u'j'), + (0x2C7D, 'M', u'v'), + (0x2C7E, 'M', u'ȿ'), + (0x2C7F, 'M', u'ɀ'), + (0x2C80, 'M', u'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', u'ⲃ'), + (0x2C83, 'V'), + (0x2C84, 'M', u'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', u'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', u'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', u'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', u'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', u'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', u'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', u'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', u'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', u'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', u'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', u'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', u'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', u'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', u'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', u'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', u'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', u'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', u'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', u'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', u'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', u'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', u'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', u'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', u'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', u'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', u'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', u'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', u'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', u'ⲿ'), + ] + +def _seg_26(): + return [ + (0x2CBF, 'V'), + (0x2CC0, 'M', u'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', u'ⳃ'), + (0x2CC3, 'V'), + (0x2CC4, 'M', u'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', u'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', u'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', u'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', u'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', u'ⳏ'), + (0x2CCF, 'V'), + (0x2CD0, 'M', u'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', u'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', u'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', u'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', u'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', u'ⳛ'), + (0x2CDB, 'V'), + (0x2CDC, 'M', u'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', u'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', u'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', u'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', u'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', u'ⳮ'), + (0x2CEE, 'V'), + (0x2CF2, 'M', u'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', u'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E53, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', u'母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', u'龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', u'一'), + (0x2F01, 'M', u'丨'), + (0x2F02, 'M', u'丶'), + (0x2F03, 'M', u'丿'), + (0x2F04, 'M', u'乙'), + (0x2F05, 'M', u'亅'), + (0x2F06, 'M', u'二'), + (0x2F07, 'M', u'亠'), + (0x2F08, 'M', u'人'), + (0x2F09, 'M', u'儿'), + (0x2F0A, 'M', u'入'), + (0x2F0B, 'M', u'八'), + (0x2F0C, 'M', u'冂'), + (0x2F0D, 'M', u'冖'), + (0x2F0E, 'M', u'冫'), + (0x2F0F, 'M', u'几'), + (0x2F10, 'M', u'凵'), + (0x2F11, 'M', u'刀'), + ] + +def _seg_27(): + return [ + (0x2F12, 'M', u'力'), + (0x2F13, 'M', u'勹'), + (0x2F14, 'M', u'匕'), + (0x2F15, 'M', u'匚'), + (0x2F16, 'M', u'匸'), + (0x2F17, 'M', u'十'), + (0x2F18, 'M', u'卜'), + (0x2F19, 'M', u'卩'), + (0x2F1A, 'M', u'厂'), + (0x2F1B, 'M', u'厶'), + (0x2F1C, 'M', u'又'), + (0x2F1D, 'M', u'口'), + (0x2F1E, 'M', u'囗'), + (0x2F1F, 'M', u'土'), + (0x2F20, 'M', u'士'), + (0x2F21, 'M', u'夂'), + (0x2F22, 'M', u'夊'), + (0x2F23, 'M', u'夕'), + (0x2F24, 'M', u'大'), + (0x2F25, 'M', u'女'), + (0x2F26, 'M', u'子'), + (0x2F27, 'M', u'宀'), + (0x2F28, 'M', u'寸'), + (0x2F29, 'M', u'小'), + (0x2F2A, 'M', u'尢'), + (0x2F2B, 'M', u'尸'), + (0x2F2C, 'M', u'屮'), + (0x2F2D, 'M', u'山'), + (0x2F2E, 'M', u'巛'), + (0x2F2F, 'M', u'工'), + (0x2F30, 'M', u'己'), + (0x2F31, 'M', u'巾'), + (0x2F32, 'M', u'干'), + (0x2F33, 'M', u'幺'), + (0x2F34, 'M', u'广'), + (0x2F35, 'M', u'廴'), + (0x2F36, 'M', u'廾'), + (0x2F37, 'M', u'弋'), + (0x2F38, 'M', u'弓'), + (0x2F39, 'M', u'彐'), + (0x2F3A, 'M', u'彡'), + (0x2F3B, 'M', u'彳'), + (0x2F3C, 'M', u'心'), + (0x2F3D, 'M', u'戈'), + (0x2F3E, 'M', u'戶'), + (0x2F3F, 'M', u'手'), + (0x2F40, 'M', u'支'), + (0x2F41, 'M', u'攴'), + (0x2F42, 'M', u'文'), + (0x2F43, 'M', u'斗'), + (0x2F44, 'M', u'斤'), + (0x2F45, 'M', u'方'), + (0x2F46, 'M', u'无'), + (0x2F47, 'M', u'日'), + (0x2F48, 'M', u'曰'), + (0x2F49, 'M', u'月'), + (0x2F4A, 'M', u'木'), + (0x2F4B, 'M', u'欠'), + (0x2F4C, 'M', u'止'), + (0x2F4D, 'M', u'歹'), + (0x2F4E, 'M', u'殳'), + (0x2F4F, 'M', u'毋'), + (0x2F50, 'M', u'比'), + (0x2F51, 'M', u'毛'), + (0x2F52, 'M', u'氏'), + (0x2F53, 'M', u'气'), + (0x2F54, 'M', u'水'), + (0x2F55, 'M', u'火'), + (0x2F56, 'M', u'爪'), + (0x2F57, 'M', u'父'), + (0x2F58, 'M', u'爻'), + (0x2F59, 'M', u'爿'), + (0x2F5A, 'M', u'片'), + (0x2F5B, 'M', u'牙'), + (0x2F5C, 'M', u'牛'), + (0x2F5D, 'M', u'犬'), + (0x2F5E, 'M', u'玄'), + (0x2F5F, 'M', u'玉'), + (0x2F60, 'M', u'瓜'), + (0x2F61, 'M', u'瓦'), + (0x2F62, 'M', u'甘'), + (0x2F63, 'M', u'生'), + (0x2F64, 'M', u'用'), + (0x2F65, 'M', u'田'), + (0x2F66, 'M', u'疋'), + (0x2F67, 'M', u'疒'), + (0x2F68, 'M', u'癶'), + (0x2F69, 'M', u'白'), + (0x2F6A, 'M', u'皮'), + (0x2F6B, 'M', u'皿'), + (0x2F6C, 'M', u'目'), + (0x2F6D, 'M', u'矛'), + (0x2F6E, 'M', u'矢'), + (0x2F6F, 'M', u'石'), + (0x2F70, 'M', u'示'), + (0x2F71, 'M', u'禸'), + (0x2F72, 'M', u'禾'), + (0x2F73, 'M', u'穴'), + (0x2F74, 'M', u'立'), + (0x2F75, 'M', u'竹'), + ] + +def _seg_28(): + return [ + (0x2F76, 'M', u'米'), + (0x2F77, 'M', u'糸'), + (0x2F78, 'M', u'缶'), + (0x2F79, 'M', u'网'), + (0x2F7A, 'M', u'羊'), + (0x2F7B, 'M', u'羽'), + (0x2F7C, 'M', u'老'), + (0x2F7D, 'M', u'而'), + (0x2F7E, 'M', u'耒'), + (0x2F7F, 'M', u'耳'), + (0x2F80, 'M', u'聿'), + (0x2F81, 'M', u'肉'), + (0x2F82, 'M', u'臣'), + (0x2F83, 'M', u'自'), + (0x2F84, 'M', u'至'), + (0x2F85, 'M', u'臼'), + (0x2F86, 'M', u'舌'), + (0x2F87, 'M', u'舛'), + (0x2F88, 'M', u'舟'), + (0x2F89, 'M', u'艮'), + (0x2F8A, 'M', u'色'), + (0x2F8B, 'M', u'艸'), + (0x2F8C, 'M', u'虍'), + (0x2F8D, 'M', u'虫'), + (0x2F8E, 'M', u'血'), + (0x2F8F, 'M', u'行'), + (0x2F90, 'M', u'衣'), + (0x2F91, 'M', u'襾'), + (0x2F92, 'M', u'見'), + (0x2F93, 'M', u'角'), + (0x2F94, 'M', u'言'), + (0x2F95, 'M', u'谷'), + (0x2F96, 'M', u'豆'), + (0x2F97, 'M', u'豕'), + (0x2F98, 'M', u'豸'), + (0x2F99, 'M', u'貝'), + (0x2F9A, 'M', u'赤'), + (0x2F9B, 'M', u'走'), + (0x2F9C, 'M', u'足'), + (0x2F9D, 'M', u'身'), + (0x2F9E, 'M', u'車'), + (0x2F9F, 'M', u'辛'), + (0x2FA0, 'M', u'辰'), + (0x2FA1, 'M', u'辵'), + (0x2FA2, 'M', u'邑'), + (0x2FA3, 'M', u'酉'), + (0x2FA4, 'M', u'釆'), + (0x2FA5, 'M', u'里'), + (0x2FA6, 'M', u'金'), + (0x2FA7, 'M', u'長'), + (0x2FA8, 'M', u'門'), + (0x2FA9, 'M', u'阜'), + (0x2FAA, 'M', u'隶'), + (0x2FAB, 'M', u'隹'), + (0x2FAC, 'M', u'雨'), + (0x2FAD, 'M', u'靑'), + (0x2FAE, 'M', u'非'), + (0x2FAF, 'M', u'面'), + (0x2FB0, 'M', u'革'), + (0x2FB1, 'M', u'韋'), + (0x2FB2, 'M', u'韭'), + (0x2FB3, 'M', u'音'), + (0x2FB4, 'M', u'頁'), + (0x2FB5, 'M', u'風'), + (0x2FB6, 'M', u'飛'), + (0x2FB7, 'M', u'食'), + (0x2FB8, 'M', u'首'), + (0x2FB9, 'M', u'香'), + (0x2FBA, 'M', u'馬'), + (0x2FBB, 'M', u'骨'), + (0x2FBC, 'M', u'高'), + (0x2FBD, 'M', u'髟'), + (0x2FBE, 'M', u'鬥'), + (0x2FBF, 'M', u'鬯'), + (0x2FC0, 'M', u'鬲'), + (0x2FC1, 'M', u'鬼'), + (0x2FC2, 'M', u'魚'), + (0x2FC3, 'M', u'鳥'), + (0x2FC4, 'M', u'鹵'), + (0x2FC5, 'M', u'鹿'), + (0x2FC6, 'M', u'麥'), + (0x2FC7, 'M', u'麻'), + (0x2FC8, 'M', u'黃'), + (0x2FC9, 'M', u'黍'), + (0x2FCA, 'M', u'黑'), + (0x2FCB, 'M', u'黹'), + (0x2FCC, 'M', u'黽'), + (0x2FCD, 'M', u'鼎'), + (0x2FCE, 'M', u'鼓'), + (0x2FCF, 'M', u'鼠'), + (0x2FD0, 'M', u'鼻'), + (0x2FD1, 'M', u'齊'), + (0x2FD2, 'M', u'齒'), + (0x2FD3, 'M', u'龍'), + (0x2FD4, 'M', u'龜'), + (0x2FD5, 'M', u'龠'), + (0x2FD6, 'X'), + (0x3000, '3', u' '), + (0x3001, 'V'), + (0x3002, 'M', u'.'), + ] + +def _seg_29(): + return [ + (0x3003, 'V'), + (0x3036, 'M', u'〒'), + (0x3037, 'V'), + (0x3038, 'M', u'十'), + (0x3039, 'M', u'卄'), + (0x303A, 'M', u'卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', u' ゙'), + (0x309C, '3', u' ゚'), + (0x309D, 'V'), + (0x309F, 'M', u'より'), + (0x30A0, 'V'), + (0x30FF, 'M', u'コト'), + (0x3100, 'X'), + (0x3105, 'V'), + (0x3130, 'X'), + (0x3131, 'M', u'ᄀ'), + (0x3132, 'M', u'ᄁ'), + (0x3133, 'M', u'ᆪ'), + (0x3134, 'M', u'ᄂ'), + (0x3135, 'M', u'ᆬ'), + (0x3136, 'M', u'ᆭ'), + (0x3137, 'M', u'ᄃ'), + (0x3138, 'M', u'ᄄ'), + (0x3139, 'M', u'ᄅ'), + (0x313A, 'M', u'ᆰ'), + (0x313B, 'M', u'ᆱ'), + (0x313C, 'M', u'ᆲ'), + (0x313D, 'M', u'ᆳ'), + (0x313E, 'M', u'ᆴ'), + (0x313F, 'M', u'ᆵ'), + (0x3140, 'M', u'ᄚ'), + (0x3141, 'M', u'ᄆ'), + (0x3142, 'M', u'ᄇ'), + (0x3143, 'M', u'ᄈ'), + (0x3144, 'M', u'ᄡ'), + (0x3145, 'M', u'ᄉ'), + (0x3146, 'M', u'ᄊ'), + (0x3147, 'M', u'ᄋ'), + (0x3148, 'M', u'ᄌ'), + (0x3149, 'M', u'ᄍ'), + (0x314A, 'M', u'ᄎ'), + (0x314B, 'M', u'ᄏ'), + (0x314C, 'M', u'ᄐ'), + (0x314D, 'M', u'ᄑ'), + (0x314E, 'M', u'ᄒ'), + (0x314F, 'M', u'ᅡ'), + (0x3150, 'M', u'ᅢ'), + (0x3151, 'M', u'ᅣ'), + (0x3152, 'M', u'ᅤ'), + (0x3153, 'M', u'ᅥ'), + (0x3154, 'M', u'ᅦ'), + (0x3155, 'M', u'ᅧ'), + (0x3156, 'M', u'ᅨ'), + (0x3157, 'M', u'ᅩ'), + (0x3158, 'M', u'ᅪ'), + (0x3159, 'M', u'ᅫ'), + (0x315A, 'M', u'ᅬ'), + (0x315B, 'M', u'ᅭ'), + (0x315C, 'M', u'ᅮ'), + (0x315D, 'M', u'ᅯ'), + (0x315E, 'M', u'ᅰ'), + (0x315F, 'M', u'ᅱ'), + (0x3160, 'M', u'ᅲ'), + (0x3161, 'M', u'ᅳ'), + (0x3162, 'M', u'ᅴ'), + (0x3163, 'M', u'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', u'ᄔ'), + (0x3166, 'M', u'ᄕ'), + (0x3167, 'M', u'ᇇ'), + (0x3168, 'M', u'ᇈ'), + (0x3169, 'M', u'ᇌ'), + (0x316A, 'M', u'ᇎ'), + (0x316B, 'M', u'ᇓ'), + (0x316C, 'M', u'ᇗ'), + (0x316D, 'M', u'ᇙ'), + (0x316E, 'M', u'ᄜ'), + (0x316F, 'M', u'ᇝ'), + (0x3170, 'M', u'ᇟ'), + (0x3171, 'M', u'ᄝ'), + (0x3172, 'M', u'ᄞ'), + (0x3173, 'M', u'ᄠ'), + (0x3174, 'M', u'ᄢ'), + (0x3175, 'M', u'ᄣ'), + (0x3176, 'M', u'ᄧ'), + (0x3177, 'M', u'ᄩ'), + (0x3178, 'M', u'ᄫ'), + (0x3179, 'M', u'ᄬ'), + (0x317A, 'M', u'ᄭ'), + (0x317B, 'M', u'ᄮ'), + (0x317C, 'M', u'ᄯ'), + (0x317D, 'M', u'ᄲ'), + (0x317E, 'M', u'ᄶ'), + (0x317F, 'M', u'ᅀ'), + (0x3180, 'M', u'ᅇ'), + ] + +def _seg_30(): + return [ + (0x3181, 'M', u'ᅌ'), + (0x3182, 'M', u'ᇱ'), + (0x3183, 'M', u'ᇲ'), + (0x3184, 'M', u'ᅗ'), + (0x3185, 'M', u'ᅘ'), + (0x3186, 'M', u'ᅙ'), + (0x3187, 'M', u'ᆄ'), + (0x3188, 'M', u'ᆅ'), + (0x3189, 'M', u'ᆈ'), + (0x318A, 'M', u'ᆑ'), + (0x318B, 'M', u'ᆒ'), + (0x318C, 'M', u'ᆔ'), + (0x318D, 'M', u'ᆞ'), + (0x318E, 'M', u'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', u'一'), + (0x3193, 'M', u'二'), + (0x3194, 'M', u'三'), + (0x3195, 'M', u'四'), + (0x3196, 'M', u'上'), + (0x3197, 'M', u'中'), + (0x3198, 'M', u'下'), + (0x3199, 'M', u'甲'), + (0x319A, 'M', u'乙'), + (0x319B, 'M', u'丙'), + (0x319C, 'M', u'丁'), + (0x319D, 'M', u'天'), + (0x319E, 'M', u'地'), + (0x319F, 'M', u'人'), + (0x31A0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', u'(ᄀ)'), + (0x3201, '3', u'(ᄂ)'), + (0x3202, '3', u'(ᄃ)'), + (0x3203, '3', u'(ᄅ)'), + (0x3204, '3', u'(ᄆ)'), + (0x3205, '3', u'(ᄇ)'), + (0x3206, '3', u'(ᄉ)'), + (0x3207, '3', u'(ᄋ)'), + (0x3208, '3', u'(ᄌ)'), + (0x3209, '3', u'(ᄎ)'), + (0x320A, '3', u'(ᄏ)'), + (0x320B, '3', u'(ᄐ)'), + (0x320C, '3', u'(ᄑ)'), + (0x320D, '3', u'(ᄒ)'), + (0x320E, '3', u'(가)'), + (0x320F, '3', u'(나)'), + (0x3210, '3', u'(다)'), + (0x3211, '3', u'(라)'), + (0x3212, '3', u'(마)'), + (0x3213, '3', u'(바)'), + (0x3214, '3', u'(사)'), + (0x3215, '3', u'(아)'), + (0x3216, '3', u'(자)'), + (0x3217, '3', u'(차)'), + (0x3218, '3', u'(카)'), + (0x3219, '3', u'(타)'), + (0x321A, '3', u'(파)'), + (0x321B, '3', u'(하)'), + (0x321C, '3', u'(주)'), + (0x321D, '3', u'(오전)'), + (0x321E, '3', u'(오후)'), + (0x321F, 'X'), + (0x3220, '3', u'(一)'), + (0x3221, '3', u'(二)'), + (0x3222, '3', u'(三)'), + (0x3223, '3', u'(四)'), + (0x3224, '3', u'(五)'), + (0x3225, '3', u'(六)'), + (0x3226, '3', u'(七)'), + (0x3227, '3', u'(八)'), + (0x3228, '3', u'(九)'), + (0x3229, '3', u'(十)'), + (0x322A, '3', u'(月)'), + (0x322B, '3', u'(火)'), + (0x322C, '3', u'(水)'), + (0x322D, '3', u'(木)'), + (0x322E, '3', u'(金)'), + (0x322F, '3', u'(土)'), + (0x3230, '3', u'(日)'), + (0x3231, '3', u'(株)'), + (0x3232, '3', u'(有)'), + (0x3233, '3', u'(社)'), + (0x3234, '3', u'(名)'), + (0x3235, '3', u'(特)'), + (0x3236, '3', u'(財)'), + (0x3237, '3', u'(祝)'), + (0x3238, '3', u'(労)'), + (0x3239, '3', u'(代)'), + (0x323A, '3', u'(呼)'), + (0x323B, '3', u'(学)'), + (0x323C, '3', u'(監)'), + (0x323D, '3', u'(企)'), + (0x323E, '3', u'(資)'), + (0x323F, '3', u'(協)'), + (0x3240, '3', u'(祭)'), + (0x3241, '3', u'(休)'), + (0x3242, '3', u'(自)'), + ] + +def _seg_31(): + return [ + (0x3243, '3', u'(至)'), + (0x3244, 'M', u'問'), + (0x3245, 'M', u'幼'), + (0x3246, 'M', u'文'), + (0x3247, 'M', u'箏'), + (0x3248, 'V'), + (0x3250, 'M', u'pte'), + (0x3251, 'M', u'21'), + (0x3252, 'M', u'22'), + (0x3253, 'M', u'23'), + (0x3254, 'M', u'24'), + (0x3255, 'M', u'25'), + (0x3256, 'M', u'26'), + (0x3257, 'M', u'27'), + (0x3258, 'M', u'28'), + (0x3259, 'M', u'29'), + (0x325A, 'M', u'30'), + (0x325B, 'M', u'31'), + (0x325C, 'M', u'32'), + (0x325D, 'M', u'33'), + (0x325E, 'M', u'34'), + (0x325F, 'M', u'35'), + (0x3260, 'M', u'ᄀ'), + (0x3261, 'M', u'ᄂ'), + (0x3262, 'M', u'ᄃ'), + (0x3263, 'M', u'ᄅ'), + (0x3264, 'M', u'ᄆ'), + (0x3265, 'M', u'ᄇ'), + (0x3266, 'M', u'ᄉ'), + (0x3267, 'M', u'ᄋ'), + (0x3268, 'M', u'ᄌ'), + (0x3269, 'M', u'ᄎ'), + (0x326A, 'M', u'ᄏ'), + (0x326B, 'M', u'ᄐ'), + (0x326C, 'M', u'ᄑ'), + (0x326D, 'M', u'ᄒ'), + (0x326E, 'M', u'가'), + (0x326F, 'M', u'나'), + (0x3270, 'M', u'다'), + (0x3271, 'M', u'라'), + (0x3272, 'M', u'마'), + (0x3273, 'M', u'바'), + (0x3274, 'M', u'사'), + (0x3275, 'M', u'아'), + (0x3276, 'M', u'자'), + (0x3277, 'M', u'차'), + (0x3278, 'M', u'카'), + (0x3279, 'M', u'타'), + (0x327A, 'M', u'파'), + (0x327B, 'M', u'하'), + (0x327C, 'M', u'참고'), + (0x327D, 'M', u'주의'), + (0x327E, 'M', u'우'), + (0x327F, 'V'), + (0x3280, 'M', u'一'), + (0x3281, 'M', u'二'), + (0x3282, 'M', u'三'), + (0x3283, 'M', u'四'), + (0x3284, 'M', u'五'), + (0x3285, 'M', u'六'), + (0x3286, 'M', u'七'), + (0x3287, 'M', u'八'), + (0x3288, 'M', u'九'), + (0x3289, 'M', u'十'), + (0x328A, 'M', u'月'), + (0x328B, 'M', u'火'), + (0x328C, 'M', u'水'), + (0x328D, 'M', u'木'), + (0x328E, 'M', u'金'), + (0x328F, 'M', u'土'), + (0x3290, 'M', u'日'), + (0x3291, 'M', u'株'), + (0x3292, 'M', u'有'), + (0x3293, 'M', u'社'), + (0x3294, 'M', u'名'), + (0x3295, 'M', u'特'), + (0x3296, 'M', u'財'), + (0x3297, 'M', u'祝'), + (0x3298, 'M', u'労'), + (0x3299, 'M', u'秘'), + (0x329A, 'M', u'男'), + (0x329B, 'M', u'女'), + (0x329C, 'M', u'適'), + (0x329D, 'M', u'優'), + (0x329E, 'M', u'印'), + (0x329F, 'M', u'注'), + (0x32A0, 'M', u'項'), + (0x32A1, 'M', u'休'), + (0x32A2, 'M', u'写'), + (0x32A3, 'M', u'正'), + (0x32A4, 'M', u'上'), + (0x32A5, 'M', u'中'), + (0x32A6, 'M', u'下'), + (0x32A7, 'M', u'左'), + (0x32A8, 'M', u'右'), + (0x32A9, 'M', u'医'), + (0x32AA, 'M', u'宗'), + (0x32AB, 'M', u'学'), + (0x32AC, 'M', u'監'), + (0x32AD, 'M', u'企'), + ] + +def _seg_32(): + return [ + (0x32AE, 'M', u'資'), + (0x32AF, 'M', u'協'), + (0x32B0, 'M', u'夜'), + (0x32B1, 'M', u'36'), + (0x32B2, 'M', u'37'), + (0x32B3, 'M', u'38'), + (0x32B4, 'M', u'39'), + (0x32B5, 'M', u'40'), + (0x32B6, 'M', u'41'), + (0x32B7, 'M', u'42'), + (0x32B8, 'M', u'43'), + (0x32B9, 'M', u'44'), + (0x32BA, 'M', u'45'), + (0x32BB, 'M', u'46'), + (0x32BC, 'M', u'47'), + (0x32BD, 'M', u'48'), + (0x32BE, 'M', u'49'), + (0x32BF, 'M', u'50'), + (0x32C0, 'M', u'1月'), + (0x32C1, 'M', u'2月'), + (0x32C2, 'M', u'3月'), + (0x32C3, 'M', u'4月'), + (0x32C4, 'M', u'5月'), + (0x32C5, 'M', u'6月'), + (0x32C6, 'M', u'7月'), + (0x32C7, 'M', u'8月'), + (0x32C8, 'M', u'9月'), + (0x32C9, 'M', u'10月'), + (0x32CA, 'M', u'11月'), + (0x32CB, 'M', u'12月'), + (0x32CC, 'M', u'hg'), + (0x32CD, 'M', u'erg'), + (0x32CE, 'M', u'ev'), + (0x32CF, 'M', u'ltd'), + (0x32D0, 'M', u'ア'), + (0x32D1, 'M', u'イ'), + (0x32D2, 'M', u'ウ'), + (0x32D3, 'M', u'エ'), + (0x32D4, 'M', u'オ'), + (0x32D5, 'M', u'カ'), + (0x32D6, 'M', u'キ'), + (0x32D7, 'M', u'ク'), + (0x32D8, 'M', u'ケ'), + (0x32D9, 'M', u'コ'), + (0x32DA, 'M', u'サ'), + (0x32DB, 'M', u'シ'), + (0x32DC, 'M', u'ス'), + (0x32DD, 'M', u'セ'), + (0x32DE, 'M', u'ソ'), + (0x32DF, 'M', u'タ'), + (0x32E0, 'M', u'チ'), + (0x32E1, 'M', u'ツ'), + (0x32E2, 'M', u'テ'), + (0x32E3, 'M', u'ト'), + (0x32E4, 'M', u'ナ'), + (0x32E5, 'M', u'ニ'), + (0x32E6, 'M', u'ヌ'), + (0x32E7, 'M', u'ネ'), + (0x32E8, 'M', u'ノ'), + (0x32E9, 'M', u'ハ'), + (0x32EA, 'M', u'ヒ'), + (0x32EB, 'M', u'フ'), + (0x32EC, 'M', u'ヘ'), + (0x32ED, 'M', u'ホ'), + (0x32EE, 'M', u'マ'), + (0x32EF, 'M', u'ミ'), + (0x32F0, 'M', u'ム'), + (0x32F1, 'M', u'メ'), + (0x32F2, 'M', u'モ'), + (0x32F3, 'M', u'ヤ'), + (0x32F4, 'M', u'ユ'), + (0x32F5, 'M', u'ヨ'), + (0x32F6, 'M', u'ラ'), + (0x32F7, 'M', u'リ'), + (0x32F8, 'M', u'ル'), + (0x32F9, 'M', u'レ'), + (0x32FA, 'M', u'ロ'), + (0x32FB, 'M', u'ワ'), + (0x32FC, 'M', u'ヰ'), + (0x32FD, 'M', u'ヱ'), + (0x32FE, 'M', u'ヲ'), + (0x32FF, 'M', u'令和'), + (0x3300, 'M', u'アパート'), + (0x3301, 'M', u'アルファ'), + (0x3302, 'M', u'アンペア'), + (0x3303, 'M', u'アール'), + (0x3304, 'M', u'イニング'), + (0x3305, 'M', u'インチ'), + (0x3306, 'M', u'ウォン'), + (0x3307, 'M', u'エスクード'), + (0x3308, 'M', u'エーカー'), + (0x3309, 'M', u'オンス'), + (0x330A, 'M', u'オーム'), + (0x330B, 'M', u'カイリ'), + (0x330C, 'M', u'カラット'), + (0x330D, 'M', u'カロリー'), + (0x330E, 'M', u'ガロン'), + (0x330F, 'M', u'ガンマ'), + (0x3310, 'M', u'ギガ'), + (0x3311, 'M', u'ギニー'), + ] + +def _seg_33(): + return [ + (0x3312, 'M', u'キュリー'), + (0x3313, 'M', u'ギルダー'), + (0x3314, 'M', u'キロ'), + (0x3315, 'M', u'キログラム'), + (0x3316, 'M', u'キロメートル'), + (0x3317, 'M', u'キロワット'), + (0x3318, 'M', u'グラム'), + (0x3319, 'M', u'グラムトン'), + (0x331A, 'M', u'クルゼイロ'), + (0x331B, 'M', u'クローネ'), + (0x331C, 'M', u'ケース'), + (0x331D, 'M', u'コルナ'), + (0x331E, 'M', u'コーポ'), + (0x331F, 'M', u'サイクル'), + (0x3320, 'M', u'サンチーム'), + (0x3321, 'M', u'シリング'), + (0x3322, 'M', u'センチ'), + (0x3323, 'M', u'セント'), + (0x3324, 'M', u'ダース'), + (0x3325, 'M', u'デシ'), + (0x3326, 'M', u'ドル'), + (0x3327, 'M', u'トン'), + (0x3328, 'M', u'ナノ'), + (0x3329, 'M', u'ノット'), + (0x332A, 'M', u'ハイツ'), + (0x332B, 'M', u'パーセント'), + (0x332C, 'M', u'パーツ'), + (0x332D, 'M', u'バーレル'), + (0x332E, 'M', u'ピアストル'), + (0x332F, 'M', u'ピクル'), + (0x3330, 'M', u'ピコ'), + (0x3331, 'M', u'ビル'), + (0x3332, 'M', u'ファラッド'), + (0x3333, 'M', u'フィート'), + (0x3334, 'M', u'ブッシェル'), + (0x3335, 'M', u'フラン'), + (0x3336, 'M', u'ヘクタール'), + (0x3337, 'M', u'ペソ'), + (0x3338, 'M', u'ペニヒ'), + (0x3339, 'M', u'ヘルツ'), + (0x333A, 'M', u'ペンス'), + (0x333B, 'M', u'ページ'), + (0x333C, 'M', u'ベータ'), + (0x333D, 'M', u'ポイント'), + (0x333E, 'M', u'ボルト'), + (0x333F, 'M', u'ホン'), + (0x3340, 'M', u'ポンド'), + (0x3341, 'M', u'ホール'), + (0x3342, 'M', u'ホーン'), + (0x3343, 'M', u'マイクロ'), + (0x3344, 'M', u'マイル'), + (0x3345, 'M', u'マッハ'), + (0x3346, 'M', u'マルク'), + (0x3347, 'M', u'マンション'), + (0x3348, 'M', u'ミクロン'), + (0x3349, 'M', u'ミリ'), + (0x334A, 'M', u'ミリバール'), + (0x334B, 'M', u'メガ'), + (0x334C, 'M', u'メガトン'), + (0x334D, 'M', u'メートル'), + (0x334E, 'M', u'ヤード'), + (0x334F, 'M', u'ヤール'), + (0x3350, 'M', u'ユアン'), + (0x3351, 'M', u'リットル'), + (0x3352, 'M', u'リラ'), + (0x3353, 'M', u'ルピー'), + (0x3354, 'M', u'ルーブル'), + (0x3355, 'M', u'レム'), + (0x3356, 'M', u'レントゲン'), + (0x3357, 'M', u'ワット'), + (0x3358, 'M', u'0点'), + (0x3359, 'M', u'1点'), + (0x335A, 'M', u'2点'), + (0x335B, 'M', u'3点'), + (0x335C, 'M', u'4点'), + (0x335D, 'M', u'5点'), + (0x335E, 'M', u'6点'), + (0x335F, 'M', u'7点'), + (0x3360, 'M', u'8点'), + (0x3361, 'M', u'9点'), + (0x3362, 'M', u'10点'), + (0x3363, 'M', u'11点'), + (0x3364, 'M', u'12点'), + (0x3365, 'M', u'13点'), + (0x3366, 'M', u'14点'), + (0x3367, 'M', u'15点'), + (0x3368, 'M', u'16点'), + (0x3369, 'M', u'17点'), + (0x336A, 'M', u'18点'), + (0x336B, 'M', u'19点'), + (0x336C, 'M', u'20点'), + (0x336D, 'M', u'21点'), + (0x336E, 'M', u'22点'), + (0x336F, 'M', u'23点'), + (0x3370, 'M', u'24点'), + (0x3371, 'M', u'hpa'), + (0x3372, 'M', u'da'), + (0x3373, 'M', u'au'), + (0x3374, 'M', u'bar'), + (0x3375, 'M', u'ov'), + ] + +def _seg_34(): + return [ + (0x3376, 'M', u'pc'), + (0x3377, 'M', u'dm'), + (0x3378, 'M', u'dm2'), + (0x3379, 'M', u'dm3'), + (0x337A, 'M', u'iu'), + (0x337B, 'M', u'平成'), + (0x337C, 'M', u'昭和'), + (0x337D, 'M', u'大正'), + (0x337E, 'M', u'明治'), + (0x337F, 'M', u'株式会社'), + (0x3380, 'M', u'pa'), + (0x3381, 'M', u'na'), + (0x3382, 'M', u'μa'), + (0x3383, 'M', u'ma'), + (0x3384, 'M', u'ka'), + (0x3385, 'M', u'kb'), + (0x3386, 'M', u'mb'), + (0x3387, 'M', u'gb'), + (0x3388, 'M', u'cal'), + (0x3389, 'M', u'kcal'), + (0x338A, 'M', u'pf'), + (0x338B, 'M', u'nf'), + (0x338C, 'M', u'μf'), + (0x338D, 'M', u'μg'), + (0x338E, 'M', u'mg'), + (0x338F, 'M', u'kg'), + (0x3390, 'M', u'hz'), + (0x3391, 'M', u'khz'), + (0x3392, 'M', u'mhz'), + (0x3393, 'M', u'ghz'), + (0x3394, 'M', u'thz'), + (0x3395, 'M', u'μl'), + (0x3396, 'M', u'ml'), + (0x3397, 'M', u'dl'), + (0x3398, 'M', u'kl'), + (0x3399, 'M', u'fm'), + (0x339A, 'M', u'nm'), + (0x339B, 'M', u'μm'), + (0x339C, 'M', u'mm'), + (0x339D, 'M', u'cm'), + (0x339E, 'M', u'km'), + (0x339F, 'M', u'mm2'), + (0x33A0, 'M', u'cm2'), + (0x33A1, 'M', u'm2'), + (0x33A2, 'M', u'km2'), + (0x33A3, 'M', u'mm3'), + (0x33A4, 'M', u'cm3'), + (0x33A5, 'M', u'm3'), + (0x33A6, 'M', u'km3'), + (0x33A7, 'M', u'm∕s'), + (0x33A8, 'M', u'm∕s2'), + (0x33A9, 'M', u'pa'), + (0x33AA, 'M', u'kpa'), + (0x33AB, 'M', u'mpa'), + (0x33AC, 'M', u'gpa'), + (0x33AD, 'M', u'rad'), + (0x33AE, 'M', u'rad∕s'), + (0x33AF, 'M', u'rad∕s2'), + (0x33B0, 'M', u'ps'), + (0x33B1, 'M', u'ns'), + (0x33B2, 'M', u'μs'), + (0x33B3, 'M', u'ms'), + (0x33B4, 'M', u'pv'), + (0x33B5, 'M', u'nv'), + (0x33B6, 'M', u'μv'), + (0x33B7, 'M', u'mv'), + (0x33B8, 'M', u'kv'), + (0x33B9, 'M', u'mv'), + (0x33BA, 'M', u'pw'), + (0x33BB, 'M', u'nw'), + (0x33BC, 'M', u'μw'), + (0x33BD, 'M', u'mw'), + (0x33BE, 'M', u'kw'), + (0x33BF, 'M', u'mw'), + (0x33C0, 'M', u'kω'), + (0x33C1, 'M', u'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', u'bq'), + (0x33C4, 'M', u'cc'), + (0x33C5, 'M', u'cd'), + (0x33C6, 'M', u'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', u'db'), + (0x33C9, 'M', u'gy'), + (0x33CA, 'M', u'ha'), + (0x33CB, 'M', u'hp'), + (0x33CC, 'M', u'in'), + (0x33CD, 'M', u'kk'), + (0x33CE, 'M', u'km'), + (0x33CF, 'M', u'kt'), + (0x33D0, 'M', u'lm'), + (0x33D1, 'M', u'ln'), + (0x33D2, 'M', u'log'), + (0x33D3, 'M', u'lx'), + (0x33D4, 'M', u'mb'), + (0x33D5, 'M', u'mil'), + (0x33D6, 'M', u'mol'), + (0x33D7, 'M', u'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', u'ppm'), + ] + +def _seg_35(): + return [ + (0x33DA, 'M', u'pr'), + (0x33DB, 'M', u'sr'), + (0x33DC, 'M', u'sv'), + (0x33DD, 'M', u'wb'), + (0x33DE, 'M', u'v∕m'), + (0x33DF, 'M', u'a∕m'), + (0x33E0, 'M', u'1日'), + (0x33E1, 'M', u'2日'), + (0x33E2, 'M', u'3日'), + (0x33E3, 'M', u'4日'), + (0x33E4, 'M', u'5日'), + (0x33E5, 'M', u'6日'), + (0x33E6, 'M', u'7日'), + (0x33E7, 'M', u'8日'), + (0x33E8, 'M', u'9日'), + (0x33E9, 'M', u'10日'), + (0x33EA, 'M', u'11日'), + (0x33EB, 'M', u'12日'), + (0x33EC, 'M', u'13日'), + (0x33ED, 'M', u'14日'), + (0x33EE, 'M', u'15日'), + (0x33EF, 'M', u'16日'), + (0x33F0, 'M', u'17日'), + (0x33F1, 'M', u'18日'), + (0x33F2, 'M', u'19日'), + (0x33F3, 'M', u'20日'), + (0x33F4, 'M', u'21日'), + (0x33F5, 'M', u'22日'), + (0x33F6, 'M', u'23日'), + (0x33F7, 'M', u'24日'), + (0x33F8, 'M', u'25日'), + (0x33F9, 'M', u'26日'), + (0x33FA, 'M', u'27日'), + (0x33FB, 'M', u'28日'), + (0x33FC, 'M', u'29日'), + (0x33FD, 'M', u'30日'), + (0x33FE, 'M', u'31日'), + (0x33FF, 'M', u'gal'), + (0x3400, 'V'), + (0x9FFD, 'X'), + (0xA000, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', u'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', u'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', u'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', u'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', u'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', u'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', u'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', u'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', u'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', u'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', u'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', u'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', u'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', u'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', u'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', u'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', u'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', u'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', u'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', u'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', u'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', u'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', u'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', u'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', u'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', u'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', u'ꚇ'), + (0xA687, 'V'), + ] + +def _seg_36(): + return [ + (0xA688, 'M', u'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', u'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', u'ꚍ'), + (0xA68D, 'V'), + (0xA68E, 'M', u'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', u'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', u'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', u'ꚕ'), + (0xA695, 'V'), + (0xA696, 'M', u'ꚗ'), + (0xA697, 'V'), + (0xA698, 'M', u'ꚙ'), + (0xA699, 'V'), + (0xA69A, 'M', u'ꚛ'), + (0xA69B, 'V'), + (0xA69C, 'M', u'ъ'), + (0xA69D, 'M', u'ь'), + (0xA69E, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', u'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', u'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', u'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', u'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', u'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', u'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', u'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', u'ꜳ'), + (0xA733, 'V'), + (0xA734, 'M', u'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', u'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', u'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', u'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', u'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', u'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', u'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', u'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', u'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', u'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', u'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', u'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', u'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', u'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', u'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', u'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', u'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', u'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', u'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', u'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', u'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', u'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', u'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', u'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', u'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', u'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', u'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', u'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', u'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', u'ꝯ'), + ] + +def _seg_37(): + return [ + (0xA76F, 'V'), + (0xA770, 'M', u'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', u'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', u'ꝼ'), + (0xA77C, 'V'), + (0xA77D, 'M', u'ᵹ'), + (0xA77E, 'M', u'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', u'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', u'ꞃ'), + (0xA783, 'V'), + (0xA784, 'M', u'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', u'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', u'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', u'ɥ'), + (0xA78E, 'V'), + (0xA790, 'M', u'ꞑ'), + (0xA791, 'V'), + (0xA792, 'M', u'ꞓ'), + (0xA793, 'V'), + (0xA796, 'M', u'ꞗ'), + (0xA797, 'V'), + (0xA798, 'M', u'ꞙ'), + (0xA799, 'V'), + (0xA79A, 'M', u'ꞛ'), + (0xA79B, 'V'), + (0xA79C, 'M', u'ꞝ'), + (0xA79D, 'V'), + (0xA79E, 'M', u'ꞟ'), + (0xA79F, 'V'), + (0xA7A0, 'M', u'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', u'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', u'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', u'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', u'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', u'ɦ'), + (0xA7AB, 'M', u'ɜ'), + (0xA7AC, 'M', u'ɡ'), + (0xA7AD, 'M', u'ɬ'), + (0xA7AE, 'M', u'ɪ'), + (0xA7AF, 'V'), + (0xA7B0, 'M', u'ʞ'), + (0xA7B1, 'M', u'ʇ'), + (0xA7B2, 'M', u'ʝ'), + (0xA7B3, 'M', u'ꭓ'), + (0xA7B4, 'M', u'ꞵ'), + (0xA7B5, 'V'), + (0xA7B6, 'M', u'ꞷ'), + (0xA7B7, 'V'), + (0xA7B8, 'M', u'ꞹ'), + (0xA7B9, 'V'), + (0xA7BA, 'M', u'ꞻ'), + (0xA7BB, 'V'), + (0xA7BC, 'M', u'ꞽ'), + (0xA7BD, 'V'), + (0xA7BE, 'M', u'ꞿ'), + (0xA7BF, 'V'), + (0xA7C0, 'X'), + (0xA7C2, 'M', u'ꟃ'), + (0xA7C3, 'V'), + (0xA7C4, 'M', u'ꞔ'), + (0xA7C5, 'M', u'ʂ'), + (0xA7C6, 'M', u'ᶎ'), + (0xA7C7, 'M', u'ꟈ'), + (0xA7C8, 'V'), + (0xA7C9, 'M', u'ꟊ'), + (0xA7CA, 'V'), + (0xA7CB, 'X'), + (0xA7F5, 'M', u'ꟶ'), + (0xA7F6, 'V'), + (0xA7F8, 'M', u'ħ'), + (0xA7F9, 'M', u'œ'), + (0xA7FA, 'V'), + (0xA82D, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C6, 'X'), + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + ] + +def _seg_38(): + return [ + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9FF, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xAB30, 'V'), + (0xAB5C, 'M', u'ꜧ'), + (0xAB5D, 'M', u'ꬷ'), + (0xAB5E, 'M', u'ɫ'), + (0xAB5F, 'M', u'ꭒ'), + (0xAB60, 'V'), + (0xAB69, 'M', u'ʍ'), + (0xAB6A, 'V'), + (0xAB6C, 'X'), + (0xAB70, 'M', u'Ꭰ'), + (0xAB71, 'M', u'Ꭱ'), + (0xAB72, 'M', u'Ꭲ'), + (0xAB73, 'M', u'Ꭳ'), + (0xAB74, 'M', u'Ꭴ'), + (0xAB75, 'M', u'Ꭵ'), + (0xAB76, 'M', u'Ꭶ'), + (0xAB77, 'M', u'Ꭷ'), + (0xAB78, 'M', u'Ꭸ'), + (0xAB79, 'M', u'Ꭹ'), + (0xAB7A, 'M', u'Ꭺ'), + (0xAB7B, 'M', u'Ꭻ'), + (0xAB7C, 'M', u'Ꭼ'), + (0xAB7D, 'M', u'Ꭽ'), + (0xAB7E, 'M', u'Ꭾ'), + (0xAB7F, 'M', u'Ꭿ'), + (0xAB80, 'M', u'Ꮀ'), + (0xAB81, 'M', u'Ꮁ'), + (0xAB82, 'M', u'Ꮂ'), + (0xAB83, 'M', u'Ꮃ'), + (0xAB84, 'M', u'Ꮄ'), + (0xAB85, 'M', u'Ꮅ'), + (0xAB86, 'M', u'Ꮆ'), + (0xAB87, 'M', u'Ꮇ'), + (0xAB88, 'M', u'Ꮈ'), + (0xAB89, 'M', u'Ꮉ'), + (0xAB8A, 'M', u'Ꮊ'), + (0xAB8B, 'M', u'Ꮋ'), + (0xAB8C, 'M', u'Ꮌ'), + (0xAB8D, 'M', u'Ꮍ'), + (0xAB8E, 'M', u'Ꮎ'), + (0xAB8F, 'M', u'Ꮏ'), + (0xAB90, 'M', u'Ꮐ'), + (0xAB91, 'M', u'Ꮑ'), + (0xAB92, 'M', u'Ꮒ'), + (0xAB93, 'M', u'Ꮓ'), + (0xAB94, 'M', u'Ꮔ'), + (0xAB95, 'M', u'Ꮕ'), + (0xAB96, 'M', u'Ꮖ'), + (0xAB97, 'M', u'Ꮗ'), + (0xAB98, 'M', u'Ꮘ'), + (0xAB99, 'M', u'Ꮙ'), + (0xAB9A, 'M', u'Ꮚ'), + (0xAB9B, 'M', u'Ꮛ'), + (0xAB9C, 'M', u'Ꮜ'), + (0xAB9D, 'M', u'Ꮝ'), + (0xAB9E, 'M', u'Ꮞ'), + (0xAB9F, 'M', u'Ꮟ'), + (0xABA0, 'M', u'Ꮠ'), + (0xABA1, 'M', u'Ꮡ'), + (0xABA2, 'M', u'Ꮢ'), + (0xABA3, 'M', u'Ꮣ'), + (0xABA4, 'M', u'Ꮤ'), + (0xABA5, 'M', u'Ꮥ'), + (0xABA6, 'M', u'Ꮦ'), + (0xABA7, 'M', u'Ꮧ'), + (0xABA8, 'M', u'Ꮨ'), + (0xABA9, 'M', u'Ꮩ'), + (0xABAA, 'M', u'Ꮪ'), + (0xABAB, 'M', u'Ꮫ'), + (0xABAC, 'M', u'Ꮬ'), + (0xABAD, 'M', u'Ꮭ'), + (0xABAE, 'M', u'Ꮮ'), + (0xABAF, 'M', u'Ꮯ'), + (0xABB0, 'M', u'Ꮰ'), + (0xABB1, 'M', u'Ꮱ'), + (0xABB2, 'M', u'Ꮲ'), + (0xABB3, 'M', u'Ꮳ'), + ] + +def _seg_39(): + return [ + (0xABB4, 'M', u'Ꮴ'), + (0xABB5, 'M', u'Ꮵ'), + (0xABB6, 'M', u'Ꮶ'), + (0xABB7, 'M', u'Ꮷ'), + (0xABB8, 'M', u'Ꮸ'), + (0xABB9, 'M', u'Ꮹ'), + (0xABBA, 'M', u'Ꮺ'), + (0xABBB, 'M', u'Ꮻ'), + (0xABBC, 'M', u'Ꮼ'), + (0xABBD, 'M', u'Ꮽ'), + (0xABBE, 'M', u'Ꮾ'), + (0xABBF, 'M', u'Ꮿ'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', u'豈'), + (0xF901, 'M', u'更'), + (0xF902, 'M', u'車'), + (0xF903, 'M', u'賈'), + (0xF904, 'M', u'滑'), + (0xF905, 'M', u'串'), + (0xF906, 'M', u'句'), + (0xF907, 'M', u'龜'), + (0xF909, 'M', u'契'), + (0xF90A, 'M', u'金'), + (0xF90B, 'M', u'喇'), + (0xF90C, 'M', u'奈'), + (0xF90D, 'M', u'懶'), + (0xF90E, 'M', u'癩'), + (0xF90F, 'M', u'羅'), + (0xF910, 'M', u'蘿'), + (0xF911, 'M', u'螺'), + (0xF912, 'M', u'裸'), + (0xF913, 'M', u'邏'), + (0xF914, 'M', u'樂'), + (0xF915, 'M', u'洛'), + (0xF916, 'M', u'烙'), + (0xF917, 'M', u'珞'), + (0xF918, 'M', u'落'), + (0xF919, 'M', u'酪'), + (0xF91A, 'M', u'駱'), + (0xF91B, 'M', u'亂'), + (0xF91C, 'M', u'卵'), + (0xF91D, 'M', u'欄'), + (0xF91E, 'M', u'爛'), + (0xF91F, 'M', u'蘭'), + (0xF920, 'M', u'鸞'), + (0xF921, 'M', u'嵐'), + (0xF922, 'M', u'濫'), + (0xF923, 'M', u'藍'), + (0xF924, 'M', u'襤'), + (0xF925, 'M', u'拉'), + (0xF926, 'M', u'臘'), + (0xF927, 'M', u'蠟'), + (0xF928, 'M', u'廊'), + (0xF929, 'M', u'朗'), + (0xF92A, 'M', u'浪'), + (0xF92B, 'M', u'狼'), + (0xF92C, 'M', u'郎'), + (0xF92D, 'M', u'來'), + (0xF92E, 'M', u'冷'), + (0xF92F, 'M', u'勞'), + (0xF930, 'M', u'擄'), + (0xF931, 'M', u'櫓'), + (0xF932, 'M', u'爐'), + (0xF933, 'M', u'盧'), + (0xF934, 'M', u'老'), + (0xF935, 'M', u'蘆'), + (0xF936, 'M', u'虜'), + (0xF937, 'M', u'路'), + (0xF938, 'M', u'露'), + (0xF939, 'M', u'魯'), + (0xF93A, 'M', u'鷺'), + (0xF93B, 'M', u'碌'), + (0xF93C, 'M', u'祿'), + (0xF93D, 'M', u'綠'), + (0xF93E, 'M', u'菉'), + (0xF93F, 'M', u'錄'), + (0xF940, 'M', u'鹿'), + (0xF941, 'M', u'論'), + (0xF942, 'M', u'壟'), + (0xF943, 'M', u'弄'), + (0xF944, 'M', u'籠'), + (0xF945, 'M', u'聾'), + (0xF946, 'M', u'牢'), + (0xF947, 'M', u'磊'), + (0xF948, 'M', u'賂'), + (0xF949, 'M', u'雷'), + (0xF94A, 'M', u'壘'), + (0xF94B, 'M', u'屢'), + (0xF94C, 'M', u'樓'), + (0xF94D, 'M', u'淚'), + (0xF94E, 'M', u'漏'), + ] + +def _seg_40(): + return [ + (0xF94F, 'M', u'累'), + (0xF950, 'M', u'縷'), + (0xF951, 'M', u'陋'), + (0xF952, 'M', u'勒'), + (0xF953, 'M', u'肋'), + (0xF954, 'M', u'凜'), + (0xF955, 'M', u'凌'), + (0xF956, 'M', u'稜'), + (0xF957, 'M', u'綾'), + (0xF958, 'M', u'菱'), + (0xF959, 'M', u'陵'), + (0xF95A, 'M', u'讀'), + (0xF95B, 'M', u'拏'), + (0xF95C, 'M', u'樂'), + (0xF95D, 'M', u'諾'), + (0xF95E, 'M', u'丹'), + (0xF95F, 'M', u'寧'), + (0xF960, 'M', u'怒'), + (0xF961, 'M', u'率'), + (0xF962, 'M', u'異'), + (0xF963, 'M', u'北'), + (0xF964, 'M', u'磻'), + (0xF965, 'M', u'便'), + (0xF966, 'M', u'復'), + (0xF967, 'M', u'不'), + (0xF968, 'M', u'泌'), + (0xF969, 'M', u'數'), + (0xF96A, 'M', u'索'), + (0xF96B, 'M', u'參'), + (0xF96C, 'M', u'塞'), + (0xF96D, 'M', u'省'), + (0xF96E, 'M', u'葉'), + (0xF96F, 'M', u'說'), + (0xF970, 'M', u'殺'), + (0xF971, 'M', u'辰'), + (0xF972, 'M', u'沈'), + (0xF973, 'M', u'拾'), + (0xF974, 'M', u'若'), + (0xF975, 'M', u'掠'), + (0xF976, 'M', u'略'), + (0xF977, 'M', u'亮'), + (0xF978, 'M', u'兩'), + (0xF979, 'M', u'凉'), + (0xF97A, 'M', u'梁'), + (0xF97B, 'M', u'糧'), + (0xF97C, 'M', u'良'), + (0xF97D, 'M', u'諒'), + (0xF97E, 'M', u'量'), + (0xF97F, 'M', u'勵'), + (0xF980, 'M', u'呂'), + (0xF981, 'M', u'女'), + (0xF982, 'M', u'廬'), + (0xF983, 'M', u'旅'), + (0xF984, 'M', u'濾'), + (0xF985, 'M', u'礪'), + (0xF986, 'M', u'閭'), + (0xF987, 'M', u'驪'), + (0xF988, 'M', u'麗'), + (0xF989, 'M', u'黎'), + (0xF98A, 'M', u'力'), + (0xF98B, 'M', u'曆'), + (0xF98C, 'M', u'歷'), + (0xF98D, 'M', u'轢'), + (0xF98E, 'M', u'年'), + (0xF98F, 'M', u'憐'), + (0xF990, 'M', u'戀'), + (0xF991, 'M', u'撚'), + (0xF992, 'M', u'漣'), + (0xF993, 'M', u'煉'), + (0xF994, 'M', u'璉'), + (0xF995, 'M', u'秊'), + (0xF996, 'M', u'練'), + (0xF997, 'M', u'聯'), + (0xF998, 'M', u'輦'), + (0xF999, 'M', u'蓮'), + (0xF99A, 'M', u'連'), + (0xF99B, 'M', u'鍊'), + (0xF99C, 'M', u'列'), + (0xF99D, 'M', u'劣'), + (0xF99E, 'M', u'咽'), + (0xF99F, 'M', u'烈'), + (0xF9A0, 'M', u'裂'), + (0xF9A1, 'M', u'說'), + (0xF9A2, 'M', u'廉'), + (0xF9A3, 'M', u'念'), + (0xF9A4, 'M', u'捻'), + (0xF9A5, 'M', u'殮'), + (0xF9A6, 'M', u'簾'), + (0xF9A7, 'M', u'獵'), + (0xF9A8, 'M', u'令'), + (0xF9A9, 'M', u'囹'), + (0xF9AA, 'M', u'寧'), + (0xF9AB, 'M', u'嶺'), + (0xF9AC, 'M', u'怜'), + (0xF9AD, 'M', u'玲'), + (0xF9AE, 'M', u'瑩'), + (0xF9AF, 'M', u'羚'), + (0xF9B0, 'M', u'聆'), + (0xF9B1, 'M', u'鈴'), + (0xF9B2, 'M', u'零'), + ] + +def _seg_41(): + return [ + (0xF9B3, 'M', u'靈'), + (0xF9B4, 'M', u'領'), + (0xF9B5, 'M', u'例'), + (0xF9B6, 'M', u'禮'), + (0xF9B7, 'M', u'醴'), + (0xF9B8, 'M', u'隸'), + (0xF9B9, 'M', u'惡'), + (0xF9BA, 'M', u'了'), + (0xF9BB, 'M', u'僚'), + (0xF9BC, 'M', u'寮'), + (0xF9BD, 'M', u'尿'), + (0xF9BE, 'M', u'料'), + (0xF9BF, 'M', u'樂'), + (0xF9C0, 'M', u'燎'), + (0xF9C1, 'M', u'療'), + (0xF9C2, 'M', u'蓼'), + (0xF9C3, 'M', u'遼'), + (0xF9C4, 'M', u'龍'), + (0xF9C5, 'M', u'暈'), + (0xF9C6, 'M', u'阮'), + (0xF9C7, 'M', u'劉'), + (0xF9C8, 'M', u'杻'), + (0xF9C9, 'M', u'柳'), + (0xF9CA, 'M', u'流'), + (0xF9CB, 'M', u'溜'), + (0xF9CC, 'M', u'琉'), + (0xF9CD, 'M', u'留'), + (0xF9CE, 'M', u'硫'), + (0xF9CF, 'M', u'紐'), + (0xF9D0, 'M', u'類'), + (0xF9D1, 'M', u'六'), + (0xF9D2, 'M', u'戮'), + (0xF9D3, 'M', u'陸'), + (0xF9D4, 'M', u'倫'), + (0xF9D5, 'M', u'崙'), + (0xF9D6, 'M', u'淪'), + (0xF9D7, 'M', u'輪'), + (0xF9D8, 'M', u'律'), + (0xF9D9, 'M', u'慄'), + (0xF9DA, 'M', u'栗'), + (0xF9DB, 'M', u'率'), + (0xF9DC, 'M', u'隆'), + (0xF9DD, 'M', u'利'), + (0xF9DE, 'M', u'吏'), + (0xF9DF, 'M', u'履'), + (0xF9E0, 'M', u'易'), + (0xF9E1, 'M', u'李'), + (0xF9E2, 'M', u'梨'), + (0xF9E3, 'M', u'泥'), + (0xF9E4, 'M', u'理'), + (0xF9E5, 'M', u'痢'), + (0xF9E6, 'M', u'罹'), + (0xF9E7, 'M', u'裏'), + (0xF9E8, 'M', u'裡'), + (0xF9E9, 'M', u'里'), + (0xF9EA, 'M', u'離'), + (0xF9EB, 'M', u'匿'), + (0xF9EC, 'M', u'溺'), + (0xF9ED, 'M', u'吝'), + (0xF9EE, 'M', u'燐'), + (0xF9EF, 'M', u'璘'), + (0xF9F0, 'M', u'藺'), + (0xF9F1, 'M', u'隣'), + (0xF9F2, 'M', u'鱗'), + (0xF9F3, 'M', u'麟'), + (0xF9F4, 'M', u'林'), + (0xF9F5, 'M', u'淋'), + (0xF9F6, 'M', u'臨'), + (0xF9F7, 'M', u'立'), + (0xF9F8, 'M', u'笠'), + (0xF9F9, 'M', u'粒'), + (0xF9FA, 'M', u'狀'), + (0xF9FB, 'M', u'炙'), + (0xF9FC, 'M', u'識'), + (0xF9FD, 'M', u'什'), + (0xF9FE, 'M', u'茶'), + (0xF9FF, 'M', u'刺'), + (0xFA00, 'M', u'切'), + (0xFA01, 'M', u'度'), + (0xFA02, 'M', u'拓'), + (0xFA03, 'M', u'糖'), + (0xFA04, 'M', u'宅'), + (0xFA05, 'M', u'洞'), + (0xFA06, 'M', u'暴'), + (0xFA07, 'M', u'輻'), + (0xFA08, 'M', u'行'), + (0xFA09, 'M', u'降'), + (0xFA0A, 'M', u'見'), + (0xFA0B, 'M', u'廓'), + (0xFA0C, 'M', u'兀'), + (0xFA0D, 'M', u'嗀'), + (0xFA0E, 'V'), + (0xFA10, 'M', u'塚'), + (0xFA11, 'V'), + (0xFA12, 'M', u'晴'), + (0xFA13, 'V'), + (0xFA15, 'M', u'凞'), + (0xFA16, 'M', u'猪'), + (0xFA17, 'M', u'益'), + (0xFA18, 'M', u'礼'), + ] + +def _seg_42(): + return [ + (0xFA19, 'M', u'神'), + (0xFA1A, 'M', u'祥'), + (0xFA1B, 'M', u'福'), + (0xFA1C, 'M', u'靖'), + (0xFA1D, 'M', u'精'), + (0xFA1E, 'M', u'羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', u'蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', u'諸'), + (0xFA23, 'V'), + (0xFA25, 'M', u'逸'), + (0xFA26, 'M', u'都'), + (0xFA27, 'V'), + (0xFA2A, 'M', u'飯'), + (0xFA2B, 'M', u'飼'), + (0xFA2C, 'M', u'館'), + (0xFA2D, 'M', u'鶴'), + (0xFA2E, 'M', u'郞'), + (0xFA2F, 'M', u'隷'), + (0xFA30, 'M', u'侮'), + (0xFA31, 'M', u'僧'), + (0xFA32, 'M', u'免'), + (0xFA33, 'M', u'勉'), + (0xFA34, 'M', u'勤'), + (0xFA35, 'M', u'卑'), + (0xFA36, 'M', u'喝'), + (0xFA37, 'M', u'嘆'), + (0xFA38, 'M', u'器'), + (0xFA39, 'M', u'塀'), + (0xFA3A, 'M', u'墨'), + (0xFA3B, 'M', u'層'), + (0xFA3C, 'M', u'屮'), + (0xFA3D, 'M', u'悔'), + (0xFA3E, 'M', u'慨'), + (0xFA3F, 'M', u'憎'), + (0xFA40, 'M', u'懲'), + (0xFA41, 'M', u'敏'), + (0xFA42, 'M', u'既'), + (0xFA43, 'M', u'暑'), + (0xFA44, 'M', u'梅'), + (0xFA45, 'M', u'海'), + (0xFA46, 'M', u'渚'), + (0xFA47, 'M', u'漢'), + (0xFA48, 'M', u'煮'), + (0xFA49, 'M', u'爫'), + (0xFA4A, 'M', u'琢'), + (0xFA4B, 'M', u'碑'), + (0xFA4C, 'M', u'社'), + (0xFA4D, 'M', u'祉'), + (0xFA4E, 'M', u'祈'), + (0xFA4F, 'M', u'祐'), + (0xFA50, 'M', u'祖'), + (0xFA51, 'M', u'祝'), + (0xFA52, 'M', u'禍'), + (0xFA53, 'M', u'禎'), + (0xFA54, 'M', u'穀'), + (0xFA55, 'M', u'突'), + (0xFA56, 'M', u'節'), + (0xFA57, 'M', u'練'), + (0xFA58, 'M', u'縉'), + (0xFA59, 'M', u'繁'), + (0xFA5A, 'M', u'署'), + (0xFA5B, 'M', u'者'), + (0xFA5C, 'M', u'臭'), + (0xFA5D, 'M', u'艹'), + (0xFA5F, 'M', u'著'), + (0xFA60, 'M', u'褐'), + (0xFA61, 'M', u'視'), + (0xFA62, 'M', u'謁'), + (0xFA63, 'M', u'謹'), + (0xFA64, 'M', u'賓'), + (0xFA65, 'M', u'贈'), + (0xFA66, 'M', u'辶'), + (0xFA67, 'M', u'逸'), + (0xFA68, 'M', u'難'), + (0xFA69, 'M', u'響'), + (0xFA6A, 'M', u'頻'), + (0xFA6B, 'M', u'恵'), + (0xFA6C, 'M', u'𤋮'), + (0xFA6D, 'M', u'舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', u'並'), + (0xFA71, 'M', u'况'), + (0xFA72, 'M', u'全'), + (0xFA73, 'M', u'侀'), + (0xFA74, 'M', u'充'), + (0xFA75, 'M', u'冀'), + (0xFA76, 'M', u'勇'), + (0xFA77, 'M', u'勺'), + (0xFA78, 'M', u'喝'), + (0xFA79, 'M', u'啕'), + (0xFA7A, 'M', u'喙'), + (0xFA7B, 'M', u'嗢'), + (0xFA7C, 'M', u'塚'), + (0xFA7D, 'M', u'墳'), + (0xFA7E, 'M', u'奄'), + (0xFA7F, 'M', u'奔'), + (0xFA80, 'M', u'婢'), + (0xFA81, 'M', u'嬨'), + ] + +def _seg_43(): + return [ + (0xFA82, 'M', u'廒'), + (0xFA83, 'M', u'廙'), + (0xFA84, 'M', u'彩'), + (0xFA85, 'M', u'徭'), + (0xFA86, 'M', u'惘'), + (0xFA87, 'M', u'慎'), + (0xFA88, 'M', u'愈'), + (0xFA89, 'M', u'憎'), + (0xFA8A, 'M', u'慠'), + (0xFA8B, 'M', u'懲'), + (0xFA8C, 'M', u'戴'), + (0xFA8D, 'M', u'揄'), + (0xFA8E, 'M', u'搜'), + (0xFA8F, 'M', u'摒'), + (0xFA90, 'M', u'敖'), + (0xFA91, 'M', u'晴'), + (0xFA92, 'M', u'朗'), + (0xFA93, 'M', u'望'), + (0xFA94, 'M', u'杖'), + (0xFA95, 'M', u'歹'), + (0xFA96, 'M', u'殺'), + (0xFA97, 'M', u'流'), + (0xFA98, 'M', u'滛'), + (0xFA99, 'M', u'滋'), + (0xFA9A, 'M', u'漢'), + (0xFA9B, 'M', u'瀞'), + (0xFA9C, 'M', u'煮'), + (0xFA9D, 'M', u'瞧'), + (0xFA9E, 'M', u'爵'), + (0xFA9F, 'M', u'犯'), + (0xFAA0, 'M', u'猪'), + (0xFAA1, 'M', u'瑱'), + (0xFAA2, 'M', u'甆'), + (0xFAA3, 'M', u'画'), + (0xFAA4, 'M', u'瘝'), + (0xFAA5, 'M', u'瘟'), + (0xFAA6, 'M', u'益'), + (0xFAA7, 'M', u'盛'), + (0xFAA8, 'M', u'直'), + (0xFAA9, 'M', u'睊'), + (0xFAAA, 'M', u'着'), + (0xFAAB, 'M', u'磌'), + (0xFAAC, 'M', u'窱'), + (0xFAAD, 'M', u'節'), + (0xFAAE, 'M', u'类'), + (0xFAAF, 'M', u'絛'), + (0xFAB0, 'M', u'練'), + (0xFAB1, 'M', u'缾'), + (0xFAB2, 'M', u'者'), + (0xFAB3, 'M', u'荒'), + (0xFAB4, 'M', u'華'), + (0xFAB5, 'M', u'蝹'), + (0xFAB6, 'M', u'襁'), + (0xFAB7, 'M', u'覆'), + (0xFAB8, 'M', u'視'), + (0xFAB9, 'M', u'調'), + (0xFABA, 'M', u'諸'), + (0xFABB, 'M', u'請'), + (0xFABC, 'M', u'謁'), + (0xFABD, 'M', u'諾'), + (0xFABE, 'M', u'諭'), + (0xFABF, 'M', u'謹'), + (0xFAC0, 'M', u'變'), + (0xFAC1, 'M', u'贈'), + (0xFAC2, 'M', u'輸'), + (0xFAC3, 'M', u'遲'), + (0xFAC4, 'M', u'醙'), + (0xFAC5, 'M', u'鉶'), + (0xFAC6, 'M', u'陼'), + (0xFAC7, 'M', u'難'), + (0xFAC8, 'M', u'靖'), + (0xFAC9, 'M', u'韛'), + (0xFACA, 'M', u'響'), + (0xFACB, 'M', u'頋'), + (0xFACC, 'M', u'頻'), + (0xFACD, 'M', u'鬒'), + (0xFACE, 'M', u'龜'), + (0xFACF, 'M', u'𢡊'), + (0xFAD0, 'M', u'𢡄'), + (0xFAD1, 'M', u'𣏕'), + (0xFAD2, 'M', u'㮝'), + (0xFAD3, 'M', u'䀘'), + (0xFAD4, 'M', u'䀹'), + (0xFAD5, 'M', u'𥉉'), + (0xFAD6, 'M', u'𥳐'), + (0xFAD7, 'M', u'𧻓'), + (0xFAD8, 'M', u'齃'), + (0xFAD9, 'M', u'龎'), + (0xFADA, 'X'), + (0xFB00, 'M', u'ff'), + (0xFB01, 'M', u'fi'), + (0xFB02, 'M', u'fl'), + (0xFB03, 'M', u'ffi'), + (0xFB04, 'M', u'ffl'), + (0xFB05, 'M', u'st'), + (0xFB07, 'X'), + (0xFB13, 'M', u'մն'), + (0xFB14, 'M', u'մե'), + (0xFB15, 'M', u'մի'), + (0xFB16, 'M', u'վն'), + ] + +def _seg_44(): + return [ + (0xFB17, 'M', u'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', u'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', u'ײַ'), + (0xFB20, 'M', u'ע'), + (0xFB21, 'M', u'א'), + (0xFB22, 'M', u'ד'), + (0xFB23, 'M', u'ה'), + (0xFB24, 'M', u'כ'), + (0xFB25, 'M', u'ל'), + (0xFB26, 'M', u'ם'), + (0xFB27, 'M', u'ר'), + (0xFB28, 'M', u'ת'), + (0xFB29, '3', u'+'), + (0xFB2A, 'M', u'שׁ'), + (0xFB2B, 'M', u'שׂ'), + (0xFB2C, 'M', u'שּׁ'), + (0xFB2D, 'M', u'שּׂ'), + (0xFB2E, 'M', u'אַ'), + (0xFB2F, 'M', u'אָ'), + (0xFB30, 'M', u'אּ'), + (0xFB31, 'M', u'בּ'), + (0xFB32, 'M', u'גּ'), + (0xFB33, 'M', u'דּ'), + (0xFB34, 'M', u'הּ'), + (0xFB35, 'M', u'וּ'), + (0xFB36, 'M', u'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', u'טּ'), + (0xFB39, 'M', u'יּ'), + (0xFB3A, 'M', u'ךּ'), + (0xFB3B, 'M', u'כּ'), + (0xFB3C, 'M', u'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', u'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', u'נּ'), + (0xFB41, 'M', u'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', u'ףּ'), + (0xFB44, 'M', u'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', u'צּ'), + (0xFB47, 'M', u'קּ'), + (0xFB48, 'M', u'רּ'), + (0xFB49, 'M', u'שּ'), + (0xFB4A, 'M', u'תּ'), + (0xFB4B, 'M', u'וֹ'), + (0xFB4C, 'M', u'בֿ'), + (0xFB4D, 'M', u'כֿ'), + (0xFB4E, 'M', u'פֿ'), + (0xFB4F, 'M', u'אל'), + (0xFB50, 'M', u'ٱ'), + (0xFB52, 'M', u'ٻ'), + (0xFB56, 'M', u'پ'), + (0xFB5A, 'M', u'ڀ'), + (0xFB5E, 'M', u'ٺ'), + (0xFB62, 'M', u'ٿ'), + (0xFB66, 'M', u'ٹ'), + (0xFB6A, 'M', u'ڤ'), + (0xFB6E, 'M', u'ڦ'), + (0xFB72, 'M', u'ڄ'), + (0xFB76, 'M', u'ڃ'), + (0xFB7A, 'M', u'چ'), + (0xFB7E, 'M', u'ڇ'), + (0xFB82, 'M', u'ڍ'), + (0xFB84, 'M', u'ڌ'), + (0xFB86, 'M', u'ڎ'), + (0xFB88, 'M', u'ڈ'), + (0xFB8A, 'M', u'ژ'), + (0xFB8C, 'M', u'ڑ'), + (0xFB8E, 'M', u'ک'), + (0xFB92, 'M', u'گ'), + (0xFB96, 'M', u'ڳ'), + (0xFB9A, 'M', u'ڱ'), + (0xFB9E, 'M', u'ں'), + (0xFBA0, 'M', u'ڻ'), + (0xFBA4, 'M', u'ۀ'), + (0xFBA6, 'M', u'ہ'), + (0xFBAA, 'M', u'ھ'), + (0xFBAE, 'M', u'ے'), + (0xFBB0, 'M', u'ۓ'), + (0xFBB2, 'V'), + (0xFBC2, 'X'), + (0xFBD3, 'M', u'ڭ'), + (0xFBD7, 'M', u'ۇ'), + (0xFBD9, 'M', u'ۆ'), + (0xFBDB, 'M', u'ۈ'), + (0xFBDD, 'M', u'ۇٴ'), + (0xFBDE, 'M', u'ۋ'), + (0xFBE0, 'M', u'ۅ'), + (0xFBE2, 'M', u'ۉ'), + (0xFBE4, 'M', u'ې'), + (0xFBE8, 'M', u'ى'), + (0xFBEA, 'M', u'ئا'), + (0xFBEC, 'M', u'ئە'), + (0xFBEE, 'M', u'ئو'), + (0xFBF0, 'M', u'ئۇ'), + (0xFBF2, 'M', u'ئۆ'), + ] + +def _seg_45(): + return [ + (0xFBF4, 'M', u'ئۈ'), + (0xFBF6, 'M', u'ئې'), + (0xFBF9, 'M', u'ئى'), + (0xFBFC, 'M', u'ی'), + (0xFC00, 'M', u'ئج'), + (0xFC01, 'M', u'ئح'), + (0xFC02, 'M', u'ئم'), + (0xFC03, 'M', u'ئى'), + (0xFC04, 'M', u'ئي'), + (0xFC05, 'M', u'بج'), + (0xFC06, 'M', u'بح'), + (0xFC07, 'M', u'بخ'), + (0xFC08, 'M', u'بم'), + (0xFC09, 'M', u'بى'), + (0xFC0A, 'M', u'بي'), + (0xFC0B, 'M', u'تج'), + (0xFC0C, 'M', u'تح'), + (0xFC0D, 'M', u'تخ'), + (0xFC0E, 'M', u'تم'), + (0xFC0F, 'M', u'تى'), + (0xFC10, 'M', u'تي'), + (0xFC11, 'M', u'ثج'), + (0xFC12, 'M', u'ثم'), + (0xFC13, 'M', u'ثى'), + (0xFC14, 'M', u'ثي'), + (0xFC15, 'M', u'جح'), + (0xFC16, 'M', u'جم'), + (0xFC17, 'M', u'حج'), + (0xFC18, 'M', u'حم'), + (0xFC19, 'M', u'خج'), + (0xFC1A, 'M', u'خح'), + (0xFC1B, 'M', u'خم'), + (0xFC1C, 'M', u'سج'), + (0xFC1D, 'M', u'سح'), + (0xFC1E, 'M', u'سخ'), + (0xFC1F, 'M', u'سم'), + (0xFC20, 'M', u'صح'), + (0xFC21, 'M', u'صم'), + (0xFC22, 'M', u'ضج'), + (0xFC23, 'M', u'ضح'), + (0xFC24, 'M', u'ضخ'), + (0xFC25, 'M', u'ضم'), + (0xFC26, 'M', u'طح'), + (0xFC27, 'M', u'طم'), + (0xFC28, 'M', u'ظم'), + (0xFC29, 'M', u'عج'), + (0xFC2A, 'M', u'عم'), + (0xFC2B, 'M', u'غج'), + (0xFC2C, 'M', u'غم'), + (0xFC2D, 'M', u'فج'), + (0xFC2E, 'M', u'فح'), + (0xFC2F, 'M', u'فخ'), + (0xFC30, 'M', u'فم'), + (0xFC31, 'M', u'فى'), + (0xFC32, 'M', u'في'), + (0xFC33, 'M', u'قح'), + (0xFC34, 'M', u'قم'), + (0xFC35, 'M', u'قى'), + (0xFC36, 'M', u'قي'), + (0xFC37, 'M', u'كا'), + (0xFC38, 'M', u'كج'), + (0xFC39, 'M', u'كح'), + (0xFC3A, 'M', u'كخ'), + (0xFC3B, 'M', u'كل'), + (0xFC3C, 'M', u'كم'), + (0xFC3D, 'M', u'كى'), + (0xFC3E, 'M', u'كي'), + (0xFC3F, 'M', u'لج'), + (0xFC40, 'M', u'لح'), + (0xFC41, 'M', u'لخ'), + (0xFC42, 'M', u'لم'), + (0xFC43, 'M', u'لى'), + (0xFC44, 'M', u'لي'), + (0xFC45, 'M', u'مج'), + (0xFC46, 'M', u'مح'), + (0xFC47, 'M', u'مخ'), + (0xFC48, 'M', u'مم'), + (0xFC49, 'M', u'مى'), + (0xFC4A, 'M', u'مي'), + (0xFC4B, 'M', u'نج'), + (0xFC4C, 'M', u'نح'), + (0xFC4D, 'M', u'نخ'), + (0xFC4E, 'M', u'نم'), + (0xFC4F, 'M', u'نى'), + (0xFC50, 'M', u'ني'), + (0xFC51, 'M', u'هج'), + (0xFC52, 'M', u'هم'), + (0xFC53, 'M', u'هى'), + (0xFC54, 'M', u'هي'), + (0xFC55, 'M', u'يج'), + (0xFC56, 'M', u'يح'), + (0xFC57, 'M', u'يخ'), + (0xFC58, 'M', u'يم'), + (0xFC59, 'M', u'يى'), + (0xFC5A, 'M', u'يي'), + (0xFC5B, 'M', u'ذٰ'), + (0xFC5C, 'M', u'رٰ'), + (0xFC5D, 'M', u'ىٰ'), + (0xFC5E, '3', u' ٌّ'), + (0xFC5F, '3', u' ٍّ'), + ] + +def _seg_46(): + return [ + (0xFC60, '3', u' َّ'), + (0xFC61, '3', u' ُّ'), + (0xFC62, '3', u' ِّ'), + (0xFC63, '3', u' ّٰ'), + (0xFC64, 'M', u'ئر'), + (0xFC65, 'M', u'ئز'), + (0xFC66, 'M', u'ئم'), + (0xFC67, 'M', u'ئن'), + (0xFC68, 'M', u'ئى'), + (0xFC69, 'M', u'ئي'), + (0xFC6A, 'M', u'بر'), + (0xFC6B, 'M', u'بز'), + (0xFC6C, 'M', u'بم'), + (0xFC6D, 'M', u'بن'), + (0xFC6E, 'M', u'بى'), + (0xFC6F, 'M', u'بي'), + (0xFC70, 'M', u'تر'), + (0xFC71, 'M', u'تز'), + (0xFC72, 'M', u'تم'), + (0xFC73, 'M', u'تن'), + (0xFC74, 'M', u'تى'), + (0xFC75, 'M', u'تي'), + (0xFC76, 'M', u'ثر'), + (0xFC77, 'M', u'ثز'), + (0xFC78, 'M', u'ثم'), + (0xFC79, 'M', u'ثن'), + (0xFC7A, 'M', u'ثى'), + (0xFC7B, 'M', u'ثي'), + (0xFC7C, 'M', u'فى'), + (0xFC7D, 'M', u'في'), + (0xFC7E, 'M', u'قى'), + (0xFC7F, 'M', u'قي'), + (0xFC80, 'M', u'كا'), + (0xFC81, 'M', u'كل'), + (0xFC82, 'M', u'كم'), + (0xFC83, 'M', u'كى'), + (0xFC84, 'M', u'كي'), + (0xFC85, 'M', u'لم'), + (0xFC86, 'M', u'لى'), + (0xFC87, 'M', u'لي'), + (0xFC88, 'M', u'ما'), + (0xFC89, 'M', u'مم'), + (0xFC8A, 'M', u'نر'), + (0xFC8B, 'M', u'نز'), + (0xFC8C, 'M', u'نم'), + (0xFC8D, 'M', u'نن'), + (0xFC8E, 'M', u'نى'), + (0xFC8F, 'M', u'ني'), + (0xFC90, 'M', u'ىٰ'), + (0xFC91, 'M', u'ير'), + (0xFC92, 'M', u'يز'), + (0xFC93, 'M', u'يم'), + (0xFC94, 'M', u'ين'), + (0xFC95, 'M', u'يى'), + (0xFC96, 'M', u'يي'), + (0xFC97, 'M', u'ئج'), + (0xFC98, 'M', u'ئح'), + (0xFC99, 'M', u'ئخ'), + (0xFC9A, 'M', u'ئم'), + (0xFC9B, 'M', u'ئه'), + (0xFC9C, 'M', u'بج'), + (0xFC9D, 'M', u'بح'), + (0xFC9E, 'M', u'بخ'), + (0xFC9F, 'M', u'بم'), + (0xFCA0, 'M', u'به'), + (0xFCA1, 'M', u'تج'), + (0xFCA2, 'M', u'تح'), + (0xFCA3, 'M', u'تخ'), + (0xFCA4, 'M', u'تم'), + (0xFCA5, 'M', u'ته'), + (0xFCA6, 'M', u'ثم'), + (0xFCA7, 'M', u'جح'), + (0xFCA8, 'M', u'جم'), + (0xFCA9, 'M', u'حج'), + (0xFCAA, 'M', u'حم'), + (0xFCAB, 'M', u'خج'), + (0xFCAC, 'M', u'خم'), + (0xFCAD, 'M', u'سج'), + (0xFCAE, 'M', u'سح'), + (0xFCAF, 'M', u'سخ'), + (0xFCB0, 'M', u'سم'), + (0xFCB1, 'M', u'صح'), + (0xFCB2, 'M', u'صخ'), + (0xFCB3, 'M', u'صم'), + (0xFCB4, 'M', u'ضج'), + (0xFCB5, 'M', u'ضح'), + (0xFCB6, 'M', u'ضخ'), + (0xFCB7, 'M', u'ضم'), + (0xFCB8, 'M', u'طح'), + (0xFCB9, 'M', u'ظم'), + (0xFCBA, 'M', u'عج'), + (0xFCBB, 'M', u'عم'), + (0xFCBC, 'M', u'غج'), + (0xFCBD, 'M', u'غم'), + (0xFCBE, 'M', u'فج'), + (0xFCBF, 'M', u'فح'), + (0xFCC0, 'M', u'فخ'), + (0xFCC1, 'M', u'فم'), + (0xFCC2, 'M', u'قح'), + (0xFCC3, 'M', u'قم'), + ] + +def _seg_47(): + return [ + (0xFCC4, 'M', u'كج'), + (0xFCC5, 'M', u'كح'), + (0xFCC6, 'M', u'كخ'), + (0xFCC7, 'M', u'كل'), + (0xFCC8, 'M', u'كم'), + (0xFCC9, 'M', u'لج'), + (0xFCCA, 'M', u'لح'), + (0xFCCB, 'M', u'لخ'), + (0xFCCC, 'M', u'لم'), + (0xFCCD, 'M', u'له'), + (0xFCCE, 'M', u'مج'), + (0xFCCF, 'M', u'مح'), + (0xFCD0, 'M', u'مخ'), + (0xFCD1, 'M', u'مم'), + (0xFCD2, 'M', u'نج'), + (0xFCD3, 'M', u'نح'), + (0xFCD4, 'M', u'نخ'), + (0xFCD5, 'M', u'نم'), + (0xFCD6, 'M', u'نه'), + (0xFCD7, 'M', u'هج'), + (0xFCD8, 'M', u'هم'), + (0xFCD9, 'M', u'هٰ'), + (0xFCDA, 'M', u'يج'), + (0xFCDB, 'M', u'يح'), + (0xFCDC, 'M', u'يخ'), + (0xFCDD, 'M', u'يم'), + (0xFCDE, 'M', u'يه'), + (0xFCDF, 'M', u'ئم'), + (0xFCE0, 'M', u'ئه'), + (0xFCE1, 'M', u'بم'), + (0xFCE2, 'M', u'به'), + (0xFCE3, 'M', u'تم'), + (0xFCE4, 'M', u'ته'), + (0xFCE5, 'M', u'ثم'), + (0xFCE6, 'M', u'ثه'), + (0xFCE7, 'M', u'سم'), + (0xFCE8, 'M', u'سه'), + (0xFCE9, 'M', u'شم'), + (0xFCEA, 'M', u'شه'), + (0xFCEB, 'M', u'كل'), + (0xFCEC, 'M', u'كم'), + (0xFCED, 'M', u'لم'), + (0xFCEE, 'M', u'نم'), + (0xFCEF, 'M', u'نه'), + (0xFCF0, 'M', u'يم'), + (0xFCF1, 'M', u'يه'), + (0xFCF2, 'M', u'ـَّ'), + (0xFCF3, 'M', u'ـُّ'), + (0xFCF4, 'M', u'ـِّ'), + (0xFCF5, 'M', u'طى'), + (0xFCF6, 'M', u'طي'), + (0xFCF7, 'M', u'عى'), + (0xFCF8, 'M', u'عي'), + (0xFCF9, 'M', u'غى'), + (0xFCFA, 'M', u'غي'), + (0xFCFB, 'M', u'سى'), + (0xFCFC, 'M', u'سي'), + (0xFCFD, 'M', u'شى'), + (0xFCFE, 'M', u'شي'), + (0xFCFF, 'M', u'حى'), + (0xFD00, 'M', u'حي'), + (0xFD01, 'M', u'جى'), + (0xFD02, 'M', u'جي'), + (0xFD03, 'M', u'خى'), + (0xFD04, 'M', u'خي'), + (0xFD05, 'M', u'صى'), + (0xFD06, 'M', u'صي'), + (0xFD07, 'M', u'ضى'), + (0xFD08, 'M', u'ضي'), + (0xFD09, 'M', u'شج'), + (0xFD0A, 'M', u'شح'), + (0xFD0B, 'M', u'شخ'), + (0xFD0C, 'M', u'شم'), + (0xFD0D, 'M', u'شر'), + (0xFD0E, 'M', u'سر'), + (0xFD0F, 'M', u'صر'), + (0xFD10, 'M', u'ضر'), + (0xFD11, 'M', u'طى'), + (0xFD12, 'M', u'طي'), + (0xFD13, 'M', u'عى'), + (0xFD14, 'M', u'عي'), + (0xFD15, 'M', u'غى'), + (0xFD16, 'M', u'غي'), + (0xFD17, 'M', u'سى'), + (0xFD18, 'M', u'سي'), + (0xFD19, 'M', u'شى'), + (0xFD1A, 'M', u'شي'), + (0xFD1B, 'M', u'حى'), + (0xFD1C, 'M', u'حي'), + (0xFD1D, 'M', u'جى'), + (0xFD1E, 'M', u'جي'), + (0xFD1F, 'M', u'خى'), + (0xFD20, 'M', u'خي'), + (0xFD21, 'M', u'صى'), + (0xFD22, 'M', u'صي'), + (0xFD23, 'M', u'ضى'), + (0xFD24, 'M', u'ضي'), + (0xFD25, 'M', u'شج'), + (0xFD26, 'M', u'شح'), + (0xFD27, 'M', u'شخ'), + ] + +def _seg_48(): + return [ + (0xFD28, 'M', u'شم'), + (0xFD29, 'M', u'شر'), + (0xFD2A, 'M', u'سر'), + (0xFD2B, 'M', u'صر'), + (0xFD2C, 'M', u'ضر'), + (0xFD2D, 'M', u'شج'), + (0xFD2E, 'M', u'شح'), + (0xFD2F, 'M', u'شخ'), + (0xFD30, 'M', u'شم'), + (0xFD31, 'M', u'سه'), + (0xFD32, 'M', u'شه'), + (0xFD33, 'M', u'طم'), + (0xFD34, 'M', u'سج'), + (0xFD35, 'M', u'سح'), + (0xFD36, 'M', u'سخ'), + (0xFD37, 'M', u'شج'), + (0xFD38, 'M', u'شح'), + (0xFD39, 'M', u'شخ'), + (0xFD3A, 'M', u'طم'), + (0xFD3B, 'M', u'ظم'), + (0xFD3C, 'M', u'اً'), + (0xFD3E, 'V'), + (0xFD40, 'X'), + (0xFD50, 'M', u'تجم'), + (0xFD51, 'M', u'تحج'), + (0xFD53, 'M', u'تحم'), + (0xFD54, 'M', u'تخم'), + (0xFD55, 'M', u'تمج'), + (0xFD56, 'M', u'تمح'), + (0xFD57, 'M', u'تمخ'), + (0xFD58, 'M', u'جمح'), + (0xFD5A, 'M', u'حمي'), + (0xFD5B, 'M', u'حمى'), + (0xFD5C, 'M', u'سحج'), + (0xFD5D, 'M', u'سجح'), + (0xFD5E, 'M', u'سجى'), + (0xFD5F, 'M', u'سمح'), + (0xFD61, 'M', u'سمج'), + (0xFD62, 'M', u'سمم'), + (0xFD64, 'M', u'صحح'), + (0xFD66, 'M', u'صمم'), + (0xFD67, 'M', u'شحم'), + (0xFD69, 'M', u'شجي'), + (0xFD6A, 'M', u'شمخ'), + (0xFD6C, 'M', u'شمم'), + (0xFD6E, 'M', u'ضحى'), + (0xFD6F, 'M', u'ضخم'), + (0xFD71, 'M', u'طمح'), + (0xFD73, 'M', u'طمم'), + (0xFD74, 'M', u'طمي'), + (0xFD75, 'M', u'عجم'), + (0xFD76, 'M', u'عمم'), + (0xFD78, 'M', u'عمى'), + (0xFD79, 'M', u'غمم'), + (0xFD7A, 'M', u'غمي'), + (0xFD7B, 'M', u'غمى'), + (0xFD7C, 'M', u'فخم'), + (0xFD7E, 'M', u'قمح'), + (0xFD7F, 'M', u'قمم'), + (0xFD80, 'M', u'لحم'), + (0xFD81, 'M', u'لحي'), + (0xFD82, 'M', u'لحى'), + (0xFD83, 'M', u'لجج'), + (0xFD85, 'M', u'لخم'), + (0xFD87, 'M', u'لمح'), + (0xFD89, 'M', u'محج'), + (0xFD8A, 'M', u'محم'), + (0xFD8B, 'M', u'محي'), + (0xFD8C, 'M', u'مجح'), + (0xFD8D, 'M', u'مجم'), + (0xFD8E, 'M', u'مخج'), + (0xFD8F, 'M', u'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', u'مجخ'), + (0xFD93, 'M', u'همج'), + (0xFD94, 'M', u'همم'), + (0xFD95, 'M', u'نحم'), + (0xFD96, 'M', u'نحى'), + (0xFD97, 'M', u'نجم'), + (0xFD99, 'M', u'نجى'), + (0xFD9A, 'M', u'نمي'), + (0xFD9B, 'M', u'نمى'), + (0xFD9C, 'M', u'يمم'), + (0xFD9E, 'M', u'بخي'), + (0xFD9F, 'M', u'تجي'), + (0xFDA0, 'M', u'تجى'), + (0xFDA1, 'M', u'تخي'), + (0xFDA2, 'M', u'تخى'), + (0xFDA3, 'M', u'تمي'), + (0xFDA4, 'M', u'تمى'), + (0xFDA5, 'M', u'جمي'), + (0xFDA6, 'M', u'جحى'), + (0xFDA7, 'M', u'جمى'), + (0xFDA8, 'M', u'سخى'), + (0xFDA9, 'M', u'صحي'), + (0xFDAA, 'M', u'شحي'), + (0xFDAB, 'M', u'ضحي'), + (0xFDAC, 'M', u'لجي'), + (0xFDAD, 'M', u'لمي'), + (0xFDAE, 'M', u'يحي'), + ] + +def _seg_49(): + return [ + (0xFDAF, 'M', u'يجي'), + (0xFDB0, 'M', u'يمي'), + (0xFDB1, 'M', u'ممي'), + (0xFDB2, 'M', u'قمي'), + (0xFDB3, 'M', u'نحي'), + (0xFDB4, 'M', u'قمح'), + (0xFDB5, 'M', u'لحم'), + (0xFDB6, 'M', u'عمي'), + (0xFDB7, 'M', u'كمي'), + (0xFDB8, 'M', u'نجح'), + (0xFDB9, 'M', u'مخي'), + (0xFDBA, 'M', u'لجم'), + (0xFDBB, 'M', u'كمم'), + (0xFDBC, 'M', u'لجم'), + (0xFDBD, 'M', u'نجح'), + (0xFDBE, 'M', u'جحي'), + (0xFDBF, 'M', u'حجي'), + (0xFDC0, 'M', u'مجي'), + (0xFDC1, 'M', u'فمي'), + (0xFDC2, 'M', u'بحي'), + (0xFDC3, 'M', u'كمم'), + (0xFDC4, 'M', u'عجم'), + (0xFDC5, 'M', u'صمم'), + (0xFDC6, 'M', u'سخي'), + (0xFDC7, 'M', u'نجي'), + (0xFDC8, 'X'), + (0xFDF0, 'M', u'صلے'), + (0xFDF1, 'M', u'قلے'), + (0xFDF2, 'M', u'الله'), + (0xFDF3, 'M', u'اكبر'), + (0xFDF4, 'M', u'محمد'), + (0xFDF5, 'M', u'صلعم'), + (0xFDF6, 'M', u'رسول'), + (0xFDF7, 'M', u'عليه'), + (0xFDF8, 'M', u'وسلم'), + (0xFDF9, 'M', u'صلى'), + (0xFDFA, '3', u'صلى الله عليه وسلم'), + (0xFDFB, '3', u'جل جلاله'), + (0xFDFC, 'M', u'ریال'), + (0xFDFD, 'V'), + (0xFDFE, 'X'), + (0xFE00, 'I'), + (0xFE10, '3', u','), + (0xFE11, 'M', u'、'), + (0xFE12, 'X'), + (0xFE13, '3', u':'), + (0xFE14, '3', u';'), + (0xFE15, '3', u'!'), + (0xFE16, '3', u'?'), + (0xFE17, 'M', u'〖'), + (0xFE18, 'M', u'〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE30, 'X'), + (0xFE31, 'M', u'—'), + (0xFE32, 'M', u'–'), + (0xFE33, '3', u'_'), + (0xFE35, '3', u'('), + (0xFE36, '3', u')'), + (0xFE37, '3', u'{'), + (0xFE38, '3', u'}'), + (0xFE39, 'M', u'〔'), + (0xFE3A, 'M', u'〕'), + (0xFE3B, 'M', u'【'), + (0xFE3C, 'M', u'】'), + (0xFE3D, 'M', u'《'), + (0xFE3E, 'M', u'》'), + (0xFE3F, 'M', u'〈'), + (0xFE40, 'M', u'〉'), + (0xFE41, 'M', u'「'), + (0xFE42, 'M', u'」'), + (0xFE43, 'M', u'『'), + (0xFE44, 'M', u'』'), + (0xFE45, 'V'), + (0xFE47, '3', u'['), + (0xFE48, '3', u']'), + (0xFE49, '3', u' ̅'), + (0xFE4D, '3', u'_'), + (0xFE50, '3', u','), + (0xFE51, 'M', u'、'), + (0xFE52, 'X'), + (0xFE54, '3', u';'), + (0xFE55, '3', u':'), + (0xFE56, '3', u'?'), + (0xFE57, '3', u'!'), + (0xFE58, 'M', u'—'), + (0xFE59, '3', u'('), + (0xFE5A, '3', u')'), + (0xFE5B, '3', u'{'), + (0xFE5C, '3', u'}'), + (0xFE5D, 'M', u'〔'), + (0xFE5E, 'M', u'〕'), + (0xFE5F, '3', u'#'), + (0xFE60, '3', u'&'), + (0xFE61, '3', u'*'), + (0xFE62, '3', u'+'), + (0xFE63, 'M', u'-'), + (0xFE64, '3', u'<'), + (0xFE65, '3', u'>'), + (0xFE66, '3', u'='), + ] + +def _seg_50(): + return [ + (0xFE67, 'X'), + (0xFE68, '3', u'\\'), + (0xFE69, '3', u'$'), + (0xFE6A, '3', u'%'), + (0xFE6B, '3', u'@'), + (0xFE6C, 'X'), + (0xFE70, '3', u' ً'), + (0xFE71, 'M', u'ـً'), + (0xFE72, '3', u' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', u' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', u' َ'), + (0xFE77, 'M', u'ـَ'), + (0xFE78, '3', u' ُ'), + (0xFE79, 'M', u'ـُ'), + (0xFE7A, '3', u' ِ'), + (0xFE7B, 'M', u'ـِ'), + (0xFE7C, '3', u' ّ'), + (0xFE7D, 'M', u'ـّ'), + (0xFE7E, '3', u' ْ'), + (0xFE7F, 'M', u'ـْ'), + (0xFE80, 'M', u'ء'), + (0xFE81, 'M', u'آ'), + (0xFE83, 'M', u'أ'), + (0xFE85, 'M', u'ؤ'), + (0xFE87, 'M', u'إ'), + (0xFE89, 'M', u'ئ'), + (0xFE8D, 'M', u'ا'), + (0xFE8F, 'M', u'ب'), + (0xFE93, 'M', u'ة'), + (0xFE95, 'M', u'ت'), + (0xFE99, 'M', u'ث'), + (0xFE9D, 'M', u'ج'), + (0xFEA1, 'M', u'ح'), + (0xFEA5, 'M', u'خ'), + (0xFEA9, 'M', u'د'), + (0xFEAB, 'M', u'ذ'), + (0xFEAD, 'M', u'ر'), + (0xFEAF, 'M', u'ز'), + (0xFEB1, 'M', u'س'), + (0xFEB5, 'M', u'ش'), + (0xFEB9, 'M', u'ص'), + (0xFEBD, 'M', u'ض'), + (0xFEC1, 'M', u'ط'), + (0xFEC5, 'M', u'ظ'), + (0xFEC9, 'M', u'ع'), + (0xFECD, 'M', u'غ'), + (0xFED1, 'M', u'ف'), + (0xFED5, 'M', u'ق'), + (0xFED9, 'M', u'ك'), + (0xFEDD, 'M', u'ل'), + (0xFEE1, 'M', u'م'), + (0xFEE5, 'M', u'ن'), + (0xFEE9, 'M', u'ه'), + (0xFEED, 'M', u'و'), + (0xFEEF, 'M', u'ى'), + (0xFEF1, 'M', u'ي'), + (0xFEF5, 'M', u'لآ'), + (0xFEF7, 'M', u'لأ'), + (0xFEF9, 'M', u'لإ'), + (0xFEFB, 'M', u'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', u'!'), + (0xFF02, '3', u'"'), + (0xFF03, '3', u'#'), + (0xFF04, '3', u'$'), + (0xFF05, '3', u'%'), + (0xFF06, '3', u'&'), + (0xFF07, '3', u'\''), + (0xFF08, '3', u'('), + (0xFF09, '3', u')'), + (0xFF0A, '3', u'*'), + (0xFF0B, '3', u'+'), + (0xFF0C, '3', u','), + (0xFF0D, 'M', u'-'), + (0xFF0E, 'M', u'.'), + (0xFF0F, '3', u'/'), + (0xFF10, 'M', u'0'), + (0xFF11, 'M', u'1'), + (0xFF12, 'M', u'2'), + (0xFF13, 'M', u'3'), + (0xFF14, 'M', u'4'), + (0xFF15, 'M', u'5'), + (0xFF16, 'M', u'6'), + (0xFF17, 'M', u'7'), + (0xFF18, 'M', u'8'), + (0xFF19, 'M', u'9'), + (0xFF1A, '3', u':'), + (0xFF1B, '3', u';'), + (0xFF1C, '3', u'<'), + (0xFF1D, '3', u'='), + (0xFF1E, '3', u'>'), + (0xFF1F, '3', u'?'), + (0xFF20, '3', u'@'), + (0xFF21, 'M', u'a'), + (0xFF22, 'M', u'b'), + (0xFF23, 'M', u'c'), + ] + +def _seg_51(): + return [ + (0xFF24, 'M', u'd'), + (0xFF25, 'M', u'e'), + (0xFF26, 'M', u'f'), + (0xFF27, 'M', u'g'), + (0xFF28, 'M', u'h'), + (0xFF29, 'M', u'i'), + (0xFF2A, 'M', u'j'), + (0xFF2B, 'M', u'k'), + (0xFF2C, 'M', u'l'), + (0xFF2D, 'M', u'm'), + (0xFF2E, 'M', u'n'), + (0xFF2F, 'M', u'o'), + (0xFF30, 'M', u'p'), + (0xFF31, 'M', u'q'), + (0xFF32, 'M', u'r'), + (0xFF33, 'M', u's'), + (0xFF34, 'M', u't'), + (0xFF35, 'M', u'u'), + (0xFF36, 'M', u'v'), + (0xFF37, 'M', u'w'), + (0xFF38, 'M', u'x'), + (0xFF39, 'M', u'y'), + (0xFF3A, 'M', u'z'), + (0xFF3B, '3', u'['), + (0xFF3C, '3', u'\\'), + (0xFF3D, '3', u']'), + (0xFF3E, '3', u'^'), + (0xFF3F, '3', u'_'), + (0xFF40, '3', u'`'), + (0xFF41, 'M', u'a'), + (0xFF42, 'M', u'b'), + (0xFF43, 'M', u'c'), + (0xFF44, 'M', u'd'), + (0xFF45, 'M', u'e'), + (0xFF46, 'M', u'f'), + (0xFF47, 'M', u'g'), + (0xFF48, 'M', u'h'), + (0xFF49, 'M', u'i'), + (0xFF4A, 'M', u'j'), + (0xFF4B, 'M', u'k'), + (0xFF4C, 'M', u'l'), + (0xFF4D, 'M', u'm'), + (0xFF4E, 'M', u'n'), + (0xFF4F, 'M', u'o'), + (0xFF50, 'M', u'p'), + (0xFF51, 'M', u'q'), + (0xFF52, 'M', u'r'), + (0xFF53, 'M', u's'), + (0xFF54, 'M', u't'), + (0xFF55, 'M', u'u'), + (0xFF56, 'M', u'v'), + (0xFF57, 'M', u'w'), + (0xFF58, 'M', u'x'), + (0xFF59, 'M', u'y'), + (0xFF5A, 'M', u'z'), + (0xFF5B, '3', u'{'), + (0xFF5C, '3', u'|'), + (0xFF5D, '3', u'}'), + (0xFF5E, '3', u'~'), + (0xFF5F, 'M', u'⦅'), + (0xFF60, 'M', u'⦆'), + (0xFF61, 'M', u'.'), + (0xFF62, 'M', u'「'), + (0xFF63, 'M', u'」'), + (0xFF64, 'M', u'、'), + (0xFF65, 'M', u'・'), + (0xFF66, 'M', u'ヲ'), + (0xFF67, 'M', u'ァ'), + (0xFF68, 'M', u'ィ'), + (0xFF69, 'M', u'ゥ'), + (0xFF6A, 'M', u'ェ'), + (0xFF6B, 'M', u'ォ'), + (0xFF6C, 'M', u'ャ'), + (0xFF6D, 'M', u'ュ'), + (0xFF6E, 'M', u'ョ'), + (0xFF6F, 'M', u'ッ'), + (0xFF70, 'M', u'ー'), + (0xFF71, 'M', u'ア'), + (0xFF72, 'M', u'イ'), + (0xFF73, 'M', u'ウ'), + (0xFF74, 'M', u'エ'), + (0xFF75, 'M', u'オ'), + (0xFF76, 'M', u'カ'), + (0xFF77, 'M', u'キ'), + (0xFF78, 'M', u'ク'), + (0xFF79, 'M', u'ケ'), + (0xFF7A, 'M', u'コ'), + (0xFF7B, 'M', u'サ'), + (0xFF7C, 'M', u'シ'), + (0xFF7D, 'M', u'ス'), + (0xFF7E, 'M', u'セ'), + (0xFF7F, 'M', u'ソ'), + (0xFF80, 'M', u'タ'), + (0xFF81, 'M', u'チ'), + (0xFF82, 'M', u'ツ'), + (0xFF83, 'M', u'テ'), + (0xFF84, 'M', u'ト'), + (0xFF85, 'M', u'ナ'), + (0xFF86, 'M', u'ニ'), + (0xFF87, 'M', u'ヌ'), + ] + +def _seg_52(): + return [ + (0xFF88, 'M', u'ネ'), + (0xFF89, 'M', u'ノ'), + (0xFF8A, 'M', u'ハ'), + (0xFF8B, 'M', u'ヒ'), + (0xFF8C, 'M', u'フ'), + (0xFF8D, 'M', u'ヘ'), + (0xFF8E, 'M', u'ホ'), + (0xFF8F, 'M', u'マ'), + (0xFF90, 'M', u'ミ'), + (0xFF91, 'M', u'ム'), + (0xFF92, 'M', u'メ'), + (0xFF93, 'M', u'モ'), + (0xFF94, 'M', u'ヤ'), + (0xFF95, 'M', u'ユ'), + (0xFF96, 'M', u'ヨ'), + (0xFF97, 'M', u'ラ'), + (0xFF98, 'M', u'リ'), + (0xFF99, 'M', u'ル'), + (0xFF9A, 'M', u'レ'), + (0xFF9B, 'M', u'ロ'), + (0xFF9C, 'M', u'ワ'), + (0xFF9D, 'M', u'ン'), + (0xFF9E, 'M', u'゙'), + (0xFF9F, 'M', u'゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', u'ᄀ'), + (0xFFA2, 'M', u'ᄁ'), + (0xFFA3, 'M', u'ᆪ'), + (0xFFA4, 'M', u'ᄂ'), + (0xFFA5, 'M', u'ᆬ'), + (0xFFA6, 'M', u'ᆭ'), + (0xFFA7, 'M', u'ᄃ'), + (0xFFA8, 'M', u'ᄄ'), + (0xFFA9, 'M', u'ᄅ'), + (0xFFAA, 'M', u'ᆰ'), + (0xFFAB, 'M', u'ᆱ'), + (0xFFAC, 'M', u'ᆲ'), + (0xFFAD, 'M', u'ᆳ'), + (0xFFAE, 'M', u'ᆴ'), + (0xFFAF, 'M', u'ᆵ'), + (0xFFB0, 'M', u'ᄚ'), + (0xFFB1, 'M', u'ᄆ'), + (0xFFB2, 'M', u'ᄇ'), + (0xFFB3, 'M', u'ᄈ'), + (0xFFB4, 'M', u'ᄡ'), + (0xFFB5, 'M', u'ᄉ'), + (0xFFB6, 'M', u'ᄊ'), + (0xFFB7, 'M', u'ᄋ'), + (0xFFB8, 'M', u'ᄌ'), + (0xFFB9, 'M', u'ᄍ'), + (0xFFBA, 'M', u'ᄎ'), + (0xFFBB, 'M', u'ᄏ'), + (0xFFBC, 'M', u'ᄐ'), + (0xFFBD, 'M', u'ᄑ'), + (0xFFBE, 'M', u'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', u'ᅡ'), + (0xFFC3, 'M', u'ᅢ'), + (0xFFC4, 'M', u'ᅣ'), + (0xFFC5, 'M', u'ᅤ'), + (0xFFC6, 'M', u'ᅥ'), + (0xFFC7, 'M', u'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', u'ᅧ'), + (0xFFCB, 'M', u'ᅨ'), + (0xFFCC, 'M', u'ᅩ'), + (0xFFCD, 'M', u'ᅪ'), + (0xFFCE, 'M', u'ᅫ'), + (0xFFCF, 'M', u'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', u'ᅭ'), + (0xFFD3, 'M', u'ᅮ'), + (0xFFD4, 'M', u'ᅯ'), + (0xFFD5, 'M', u'ᅰ'), + (0xFFD6, 'M', u'ᅱ'), + (0xFFD7, 'M', u'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', u'ᅳ'), + (0xFFDB, 'M', u'ᅴ'), + (0xFFDC, 'M', u'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', u'¢'), + (0xFFE1, 'M', u'£'), + (0xFFE2, 'M', u'¬'), + (0xFFE3, '3', u' ̄'), + (0xFFE4, 'M', u'¦'), + (0xFFE5, 'M', u'¥'), + (0xFFE6, 'M', u'₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', u'│'), + (0xFFE9, 'M', u'←'), + (0xFFEA, 'M', u'↑'), + (0xFFEB, 'M', u'→'), + (0xFFEC, 'M', u'↓'), + (0xFFED, 'M', u'■'), + (0xFFEE, 'M', u'○'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + ] + +def _seg_53(): + return [ + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018F, 'X'), + (0x10190, 'V'), + (0x1019D, 'X'), + (0x101A0, 'V'), + (0x101A1, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x102E0, 'V'), + (0x102FC, 'X'), + (0x10300, 'V'), + (0x10324, 'X'), + (0x1032D, 'V'), + (0x1034B, 'X'), + (0x10350, 'V'), + (0x1037B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', u'𐐨'), + (0x10401, 'M', u'𐐩'), + (0x10402, 'M', u'𐐪'), + (0x10403, 'M', u'𐐫'), + (0x10404, 'M', u'𐐬'), + (0x10405, 'M', u'𐐭'), + (0x10406, 'M', u'𐐮'), + (0x10407, 'M', u'𐐯'), + (0x10408, 'M', u'𐐰'), + (0x10409, 'M', u'𐐱'), + (0x1040A, 'M', u'𐐲'), + (0x1040B, 'M', u'𐐳'), + (0x1040C, 'M', u'𐐴'), + (0x1040D, 'M', u'𐐵'), + (0x1040E, 'M', u'𐐶'), + (0x1040F, 'M', u'𐐷'), + (0x10410, 'M', u'𐐸'), + (0x10411, 'M', u'𐐹'), + (0x10412, 'M', u'𐐺'), + (0x10413, 'M', u'𐐻'), + (0x10414, 'M', u'𐐼'), + (0x10415, 'M', u'𐐽'), + (0x10416, 'M', u'𐐾'), + (0x10417, 'M', u'𐐿'), + (0x10418, 'M', u'𐑀'), + (0x10419, 'M', u'𐑁'), + (0x1041A, 'M', u'𐑂'), + (0x1041B, 'M', u'𐑃'), + (0x1041C, 'M', u'𐑄'), + (0x1041D, 'M', u'𐑅'), + (0x1041E, 'M', u'𐑆'), + (0x1041F, 'M', u'𐑇'), + (0x10420, 'M', u'𐑈'), + (0x10421, 'M', u'𐑉'), + (0x10422, 'M', u'𐑊'), + (0x10423, 'M', u'𐑋'), + (0x10424, 'M', u'𐑌'), + (0x10425, 'M', u'𐑍'), + (0x10426, 'M', u'𐑎'), + (0x10427, 'M', u'𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x104B0, 'M', u'𐓘'), + (0x104B1, 'M', u'𐓙'), + (0x104B2, 'M', u'𐓚'), + (0x104B3, 'M', u'𐓛'), + (0x104B4, 'M', u'𐓜'), + (0x104B5, 'M', u'𐓝'), + (0x104B6, 'M', u'𐓞'), + (0x104B7, 'M', u'𐓟'), + (0x104B8, 'M', u'𐓠'), + (0x104B9, 'M', u'𐓡'), + (0x104BA, 'M', u'𐓢'), + (0x104BB, 'M', u'𐓣'), + (0x104BC, 'M', u'𐓤'), + (0x104BD, 'M', u'𐓥'), + (0x104BE, 'M', u'𐓦'), + ] + +def _seg_54(): + return [ + (0x104BF, 'M', u'𐓧'), + (0x104C0, 'M', u'𐓨'), + (0x104C1, 'M', u'𐓩'), + (0x104C2, 'M', u'𐓪'), + (0x104C3, 'M', u'𐓫'), + (0x104C4, 'M', u'𐓬'), + (0x104C5, 'M', u'𐓭'), + (0x104C6, 'M', u'𐓮'), + (0x104C7, 'M', u'𐓯'), + (0x104C8, 'M', u'𐓰'), + (0x104C9, 'M', u'𐓱'), + (0x104CA, 'M', u'𐓲'), + (0x104CB, 'M', u'𐓳'), + (0x104CC, 'M', u'𐓴'), + (0x104CD, 'M', u'𐓵'), + (0x104CE, 'M', u'𐓶'), + (0x104CF, 'M', u'𐓷'), + (0x104D0, 'M', u'𐓸'), + (0x104D1, 'M', u'𐓹'), + (0x104D2, 'M', u'𐓺'), + (0x104D3, 'M', u'𐓻'), + (0x104D4, 'X'), + (0x104D8, 'V'), + (0x104FC, 'X'), + (0x10500, 'V'), + (0x10528, 'X'), + (0x10530, 'V'), + (0x10564, 'X'), + (0x1056F, 'V'), + (0x10570, 'X'), + (0x10600, 'V'), + (0x10737, 'X'), + (0x10740, 'V'), + (0x10756, 'X'), + (0x10760, 'V'), + (0x10768, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x1089F, 'X'), + (0x108A7, 'V'), + (0x108B0, 'X'), + (0x108E0, 'V'), + (0x108F3, 'X'), + (0x108F4, 'V'), + (0x108F6, 'X'), + (0x108FB, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BC, 'V'), + (0x109D0, 'X'), + (0x109D2, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A36, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A49, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10AA0, 'X'), + (0x10AC0, 'V'), + (0x10AE7, 'X'), + (0x10AEB, 'V'), + (0x10AF7, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B92, 'X'), + (0x10B99, 'V'), + (0x10B9D, 'X'), + (0x10BA9, 'V'), + (0x10BB0, 'X'), + ] + +def _seg_55(): + return [ + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10C80, 'M', u'𐳀'), + (0x10C81, 'M', u'𐳁'), + (0x10C82, 'M', u'𐳂'), + (0x10C83, 'M', u'𐳃'), + (0x10C84, 'M', u'𐳄'), + (0x10C85, 'M', u'𐳅'), + (0x10C86, 'M', u'𐳆'), + (0x10C87, 'M', u'𐳇'), + (0x10C88, 'M', u'𐳈'), + (0x10C89, 'M', u'𐳉'), + (0x10C8A, 'M', u'𐳊'), + (0x10C8B, 'M', u'𐳋'), + (0x10C8C, 'M', u'𐳌'), + (0x10C8D, 'M', u'𐳍'), + (0x10C8E, 'M', u'𐳎'), + (0x10C8F, 'M', u'𐳏'), + (0x10C90, 'M', u'𐳐'), + (0x10C91, 'M', u'𐳑'), + (0x10C92, 'M', u'𐳒'), + (0x10C93, 'M', u'𐳓'), + (0x10C94, 'M', u'𐳔'), + (0x10C95, 'M', u'𐳕'), + (0x10C96, 'M', u'𐳖'), + (0x10C97, 'M', u'𐳗'), + (0x10C98, 'M', u'𐳘'), + (0x10C99, 'M', u'𐳙'), + (0x10C9A, 'M', u'𐳚'), + (0x10C9B, 'M', u'𐳛'), + (0x10C9C, 'M', u'𐳜'), + (0x10C9D, 'M', u'𐳝'), + (0x10C9E, 'M', u'𐳞'), + (0x10C9F, 'M', u'𐳟'), + (0x10CA0, 'M', u'𐳠'), + (0x10CA1, 'M', u'𐳡'), + (0x10CA2, 'M', u'𐳢'), + (0x10CA3, 'M', u'𐳣'), + (0x10CA4, 'M', u'𐳤'), + (0x10CA5, 'M', u'𐳥'), + (0x10CA6, 'M', u'𐳦'), + (0x10CA7, 'M', u'𐳧'), + (0x10CA8, 'M', u'𐳨'), + (0x10CA9, 'M', u'𐳩'), + (0x10CAA, 'M', u'𐳪'), + (0x10CAB, 'M', u'𐳫'), + (0x10CAC, 'M', u'𐳬'), + (0x10CAD, 'M', u'𐳭'), + (0x10CAE, 'M', u'𐳮'), + (0x10CAF, 'M', u'𐳯'), + (0x10CB0, 'M', u'𐳰'), + (0x10CB1, 'M', u'𐳱'), + (0x10CB2, 'M', u'𐳲'), + (0x10CB3, 'X'), + (0x10CC0, 'V'), + (0x10CF3, 'X'), + (0x10CFA, 'V'), + (0x10D28, 'X'), + (0x10D30, 'V'), + (0x10D3A, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x10E80, 'V'), + (0x10EAA, 'X'), + (0x10EAB, 'V'), + (0x10EAE, 'X'), + (0x10EB0, 'V'), + (0x10EB2, 'X'), + (0x10F00, 'V'), + (0x10F28, 'X'), + (0x10F30, 'V'), + (0x10F5A, 'X'), + (0x10FB0, 'V'), + (0x10FCC, 'X'), + (0x10FE0, 'V'), + (0x10FF7, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11070, 'X'), + (0x1107F, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + (0x110C2, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11148, 'X'), + (0x11150, 'V'), + (0x11177, 'X'), + (0x11180, 'V'), + (0x111E0, 'X'), + (0x111E1, 'V'), + (0x111F5, 'X'), + (0x11200, 'V'), + (0x11212, 'X'), + ] + +def _seg_56(): + return [ + (0x11213, 'V'), + (0x1123F, 'X'), + (0x11280, 'V'), + (0x11287, 'X'), + (0x11288, 'V'), + (0x11289, 'X'), + (0x1128A, 'V'), + (0x1128E, 'X'), + (0x1128F, 'V'), + (0x1129E, 'X'), + (0x1129F, 'V'), + (0x112AA, 'X'), + (0x112B0, 'V'), + (0x112EB, 'X'), + (0x112F0, 'V'), + (0x112FA, 'X'), + (0x11300, 'V'), + (0x11304, 'X'), + (0x11305, 'V'), + (0x1130D, 'X'), + (0x1130F, 'V'), + (0x11311, 'X'), + (0x11313, 'V'), + (0x11329, 'X'), + (0x1132A, 'V'), + (0x11331, 'X'), + (0x11332, 'V'), + (0x11334, 'X'), + (0x11335, 'V'), + (0x1133A, 'X'), + (0x1133B, 'V'), + (0x11345, 'X'), + (0x11347, 'V'), + (0x11349, 'X'), + (0x1134B, 'V'), + (0x1134E, 'X'), + (0x11350, 'V'), + (0x11351, 'X'), + (0x11357, 'V'), + (0x11358, 'X'), + (0x1135D, 'V'), + (0x11364, 'X'), + (0x11366, 'V'), + (0x1136D, 'X'), + (0x11370, 'V'), + (0x11375, 'X'), + (0x11400, 'V'), + (0x1145C, 'X'), + (0x1145D, 'V'), + (0x11462, 'X'), + (0x11480, 'V'), + (0x114C8, 'X'), + (0x114D0, 'V'), + (0x114DA, 'X'), + (0x11580, 'V'), + (0x115B6, 'X'), + (0x115B8, 'V'), + (0x115DE, 'X'), + (0x11600, 'V'), + (0x11645, 'X'), + (0x11650, 'V'), + (0x1165A, 'X'), + (0x11660, 'V'), + (0x1166D, 'X'), + (0x11680, 'V'), + (0x116B9, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x11700, 'V'), + (0x1171B, 'X'), + (0x1171D, 'V'), + (0x1172C, 'X'), + (0x11730, 'V'), + (0x11740, 'X'), + (0x11800, 'V'), + (0x1183C, 'X'), + (0x118A0, 'M', u'𑣀'), + (0x118A1, 'M', u'𑣁'), + (0x118A2, 'M', u'𑣂'), + (0x118A3, 'M', u'𑣃'), + (0x118A4, 'M', u'𑣄'), + (0x118A5, 'M', u'𑣅'), + (0x118A6, 'M', u'𑣆'), + (0x118A7, 'M', u'𑣇'), + (0x118A8, 'M', u'𑣈'), + (0x118A9, 'M', u'𑣉'), + (0x118AA, 'M', u'𑣊'), + (0x118AB, 'M', u'𑣋'), + (0x118AC, 'M', u'𑣌'), + (0x118AD, 'M', u'𑣍'), + (0x118AE, 'M', u'𑣎'), + (0x118AF, 'M', u'𑣏'), + (0x118B0, 'M', u'𑣐'), + (0x118B1, 'M', u'𑣑'), + (0x118B2, 'M', u'𑣒'), + (0x118B3, 'M', u'𑣓'), + (0x118B4, 'M', u'𑣔'), + (0x118B5, 'M', u'𑣕'), + (0x118B6, 'M', u'𑣖'), + (0x118B7, 'M', u'𑣗'), + ] + +def _seg_57(): + return [ + (0x118B8, 'M', u'𑣘'), + (0x118B9, 'M', u'𑣙'), + (0x118BA, 'M', u'𑣚'), + (0x118BB, 'M', u'𑣛'), + (0x118BC, 'M', u'𑣜'), + (0x118BD, 'M', u'𑣝'), + (0x118BE, 'M', u'𑣞'), + (0x118BF, 'M', u'𑣟'), + (0x118C0, 'V'), + (0x118F3, 'X'), + (0x118FF, 'V'), + (0x11907, 'X'), + (0x11909, 'V'), + (0x1190A, 'X'), + (0x1190C, 'V'), + (0x11914, 'X'), + (0x11915, 'V'), + (0x11917, 'X'), + (0x11918, 'V'), + (0x11936, 'X'), + (0x11937, 'V'), + (0x11939, 'X'), + (0x1193B, 'V'), + (0x11947, 'X'), + (0x11950, 'V'), + (0x1195A, 'X'), + (0x119A0, 'V'), + (0x119A8, 'X'), + (0x119AA, 'V'), + (0x119D8, 'X'), + (0x119DA, 'V'), + (0x119E5, 'X'), + (0x11A00, 'V'), + (0x11A48, 'X'), + (0x11A50, 'V'), + (0x11AA3, 'X'), + (0x11AC0, 'V'), + (0x11AF9, 'X'), + (0x11C00, 'V'), + (0x11C09, 'X'), + (0x11C0A, 'V'), + (0x11C37, 'X'), + (0x11C38, 'V'), + (0x11C46, 'X'), + (0x11C50, 'V'), + (0x11C6D, 'X'), + (0x11C70, 'V'), + (0x11C90, 'X'), + (0x11C92, 'V'), + (0x11CA8, 'X'), + (0x11CA9, 'V'), + (0x11CB7, 'X'), + (0x11D00, 'V'), + (0x11D07, 'X'), + (0x11D08, 'V'), + (0x11D0A, 'X'), + (0x11D0B, 'V'), + (0x11D37, 'X'), + (0x11D3A, 'V'), + (0x11D3B, 'X'), + (0x11D3C, 'V'), + (0x11D3E, 'X'), + (0x11D3F, 'V'), + (0x11D48, 'X'), + (0x11D50, 'V'), + (0x11D5A, 'X'), + (0x11D60, 'V'), + (0x11D66, 'X'), + (0x11D67, 'V'), + (0x11D69, 'X'), + (0x11D6A, 'V'), + (0x11D8F, 'X'), + (0x11D90, 'V'), + (0x11D92, 'X'), + (0x11D93, 'V'), + (0x11D99, 'X'), + (0x11DA0, 'V'), + (0x11DAA, 'X'), + (0x11EE0, 'V'), + (0x11EF9, 'X'), + (0x11FB0, 'V'), + (0x11FB1, 'X'), + (0x11FC0, 'V'), + (0x11FF2, 'X'), + (0x11FFF, 'V'), + (0x1239A, 'X'), + (0x12400, 'V'), + (0x1246F, 'X'), + (0x12470, 'V'), + (0x12475, 'X'), + (0x12480, 'V'), + (0x12544, 'X'), + (0x13000, 'V'), + (0x1342F, 'X'), + (0x14400, 'V'), + (0x14647, 'X'), + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16A40, 'V'), + (0x16A5F, 'X'), + ] + +def _seg_58(): + return [ + (0x16A60, 'V'), + (0x16A6A, 'X'), + (0x16A6E, 'V'), + (0x16A70, 'X'), + (0x16AD0, 'V'), + (0x16AEE, 'X'), + (0x16AF0, 'V'), + (0x16AF6, 'X'), + (0x16B00, 'V'), + (0x16B46, 'X'), + (0x16B50, 'V'), + (0x16B5A, 'X'), + (0x16B5B, 'V'), + (0x16B62, 'X'), + (0x16B63, 'V'), + (0x16B78, 'X'), + (0x16B7D, 'V'), + (0x16B90, 'X'), + (0x16E40, 'M', u'𖹠'), + (0x16E41, 'M', u'𖹡'), + (0x16E42, 'M', u'𖹢'), + (0x16E43, 'M', u'𖹣'), + (0x16E44, 'M', u'𖹤'), + (0x16E45, 'M', u'𖹥'), + (0x16E46, 'M', u'𖹦'), + (0x16E47, 'M', u'𖹧'), + (0x16E48, 'M', u'𖹨'), + (0x16E49, 'M', u'𖹩'), + (0x16E4A, 'M', u'𖹪'), + (0x16E4B, 'M', u'𖹫'), + (0x16E4C, 'M', u'𖹬'), + (0x16E4D, 'M', u'𖹭'), + (0x16E4E, 'M', u'𖹮'), + (0x16E4F, 'M', u'𖹯'), + (0x16E50, 'M', u'𖹰'), + (0x16E51, 'M', u'𖹱'), + (0x16E52, 'M', u'𖹲'), + (0x16E53, 'M', u'𖹳'), + (0x16E54, 'M', u'𖹴'), + (0x16E55, 'M', u'𖹵'), + (0x16E56, 'M', u'𖹶'), + (0x16E57, 'M', u'𖹷'), + (0x16E58, 'M', u'𖹸'), + (0x16E59, 'M', u'𖹹'), + (0x16E5A, 'M', u'𖹺'), + (0x16E5B, 'M', u'𖹻'), + (0x16E5C, 'M', u'𖹼'), + (0x16E5D, 'M', u'𖹽'), + (0x16E5E, 'M', u'𖹾'), + (0x16E5F, 'M', u'𖹿'), + (0x16E60, 'V'), + (0x16E9B, 'X'), + (0x16F00, 'V'), + (0x16F4B, 'X'), + (0x16F4F, 'V'), + (0x16F88, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x16FE0, 'V'), + (0x16FE5, 'X'), + (0x16FF0, 'V'), + (0x16FF2, 'X'), + (0x17000, 'V'), + (0x187F8, 'X'), + (0x18800, 'V'), + (0x18CD6, 'X'), + (0x18D00, 'V'), + (0x18D09, 'X'), + (0x1B000, 'V'), + (0x1B11F, 'X'), + (0x1B150, 'V'), + (0x1B153, 'X'), + (0x1B164, 'V'), + (0x1B168, 'X'), + (0x1B170, 'V'), + (0x1B2FC, 'X'), + (0x1BC00, 'V'), + (0x1BC6B, 'X'), + (0x1BC70, 'V'), + (0x1BC7D, 'X'), + (0x1BC80, 'V'), + (0x1BC89, 'X'), + (0x1BC90, 'V'), + (0x1BC9A, 'X'), + (0x1BC9C, 'V'), + (0x1BCA0, 'I'), + (0x1BCA4, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', u'𝅗𝅥'), + (0x1D15F, 'M', u'𝅘𝅥'), + (0x1D160, 'M', u'𝅘𝅥𝅮'), + (0x1D161, 'M', u'𝅘𝅥𝅯'), + (0x1D162, 'M', u'𝅘𝅥𝅰'), + (0x1D163, 'M', u'𝅘𝅥𝅱'), + (0x1D164, 'M', u'𝅘𝅥𝅲'), + (0x1D165, 'V'), + ] + +def _seg_59(): + return [ + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', u'𝆹𝅥'), + (0x1D1BC, 'M', u'𝆺𝅥'), + (0x1D1BD, 'M', u'𝆹𝅥𝅮'), + (0x1D1BE, 'M', u'𝆺𝅥𝅮'), + (0x1D1BF, 'M', u'𝆹𝅥𝅯'), + (0x1D1C0, 'M', u'𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1E9, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D2E0, 'V'), + (0x1D2F4, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D379, 'X'), + (0x1D400, 'M', u'a'), + (0x1D401, 'M', u'b'), + (0x1D402, 'M', u'c'), + (0x1D403, 'M', u'd'), + (0x1D404, 'M', u'e'), + (0x1D405, 'M', u'f'), + (0x1D406, 'M', u'g'), + (0x1D407, 'M', u'h'), + (0x1D408, 'M', u'i'), + (0x1D409, 'M', u'j'), + (0x1D40A, 'M', u'k'), + (0x1D40B, 'M', u'l'), + (0x1D40C, 'M', u'm'), + (0x1D40D, 'M', u'n'), + (0x1D40E, 'M', u'o'), + (0x1D40F, 'M', u'p'), + (0x1D410, 'M', u'q'), + (0x1D411, 'M', u'r'), + (0x1D412, 'M', u's'), + (0x1D413, 'M', u't'), + (0x1D414, 'M', u'u'), + (0x1D415, 'M', u'v'), + (0x1D416, 'M', u'w'), + (0x1D417, 'M', u'x'), + (0x1D418, 'M', u'y'), + (0x1D419, 'M', u'z'), + (0x1D41A, 'M', u'a'), + (0x1D41B, 'M', u'b'), + (0x1D41C, 'M', u'c'), + (0x1D41D, 'M', u'd'), + (0x1D41E, 'M', u'e'), + (0x1D41F, 'M', u'f'), + (0x1D420, 'M', u'g'), + (0x1D421, 'M', u'h'), + (0x1D422, 'M', u'i'), + (0x1D423, 'M', u'j'), + (0x1D424, 'M', u'k'), + (0x1D425, 'M', u'l'), + (0x1D426, 'M', u'm'), + (0x1D427, 'M', u'n'), + (0x1D428, 'M', u'o'), + (0x1D429, 'M', u'p'), + (0x1D42A, 'M', u'q'), + (0x1D42B, 'M', u'r'), + (0x1D42C, 'M', u's'), + (0x1D42D, 'M', u't'), + (0x1D42E, 'M', u'u'), + (0x1D42F, 'M', u'v'), + (0x1D430, 'M', u'w'), + (0x1D431, 'M', u'x'), + (0x1D432, 'M', u'y'), + (0x1D433, 'M', u'z'), + (0x1D434, 'M', u'a'), + (0x1D435, 'M', u'b'), + (0x1D436, 'M', u'c'), + (0x1D437, 'M', u'd'), + (0x1D438, 'M', u'e'), + (0x1D439, 'M', u'f'), + (0x1D43A, 'M', u'g'), + (0x1D43B, 'M', u'h'), + (0x1D43C, 'M', u'i'), + (0x1D43D, 'M', u'j'), + (0x1D43E, 'M', u'k'), + (0x1D43F, 'M', u'l'), + (0x1D440, 'M', u'm'), + (0x1D441, 'M', u'n'), + (0x1D442, 'M', u'o'), + (0x1D443, 'M', u'p'), + (0x1D444, 'M', u'q'), + (0x1D445, 'M', u'r'), + (0x1D446, 'M', u's'), + (0x1D447, 'M', u't'), + (0x1D448, 'M', u'u'), + (0x1D449, 'M', u'v'), + (0x1D44A, 'M', u'w'), + (0x1D44B, 'M', u'x'), + (0x1D44C, 'M', u'y'), + (0x1D44D, 'M', u'z'), + (0x1D44E, 'M', u'a'), + (0x1D44F, 'M', u'b'), + (0x1D450, 'M', u'c'), + (0x1D451, 'M', u'd'), + ] + +def _seg_60(): + return [ + (0x1D452, 'M', u'e'), + (0x1D453, 'M', u'f'), + (0x1D454, 'M', u'g'), + (0x1D455, 'X'), + (0x1D456, 'M', u'i'), + (0x1D457, 'M', u'j'), + (0x1D458, 'M', u'k'), + (0x1D459, 'M', u'l'), + (0x1D45A, 'M', u'm'), + (0x1D45B, 'M', u'n'), + (0x1D45C, 'M', u'o'), + (0x1D45D, 'M', u'p'), + (0x1D45E, 'M', u'q'), + (0x1D45F, 'M', u'r'), + (0x1D460, 'M', u's'), + (0x1D461, 'M', u't'), + (0x1D462, 'M', u'u'), + (0x1D463, 'M', u'v'), + (0x1D464, 'M', u'w'), + (0x1D465, 'M', u'x'), + (0x1D466, 'M', u'y'), + (0x1D467, 'M', u'z'), + (0x1D468, 'M', u'a'), + (0x1D469, 'M', u'b'), + (0x1D46A, 'M', u'c'), + (0x1D46B, 'M', u'd'), + (0x1D46C, 'M', u'e'), + (0x1D46D, 'M', u'f'), + (0x1D46E, 'M', u'g'), + (0x1D46F, 'M', u'h'), + (0x1D470, 'M', u'i'), + (0x1D471, 'M', u'j'), + (0x1D472, 'M', u'k'), + (0x1D473, 'M', u'l'), + (0x1D474, 'M', u'm'), + (0x1D475, 'M', u'n'), + (0x1D476, 'M', u'o'), + (0x1D477, 'M', u'p'), + (0x1D478, 'M', u'q'), + (0x1D479, 'M', u'r'), + (0x1D47A, 'M', u's'), + (0x1D47B, 'M', u't'), + (0x1D47C, 'M', u'u'), + (0x1D47D, 'M', u'v'), + (0x1D47E, 'M', u'w'), + (0x1D47F, 'M', u'x'), + (0x1D480, 'M', u'y'), + (0x1D481, 'M', u'z'), + (0x1D482, 'M', u'a'), + (0x1D483, 'M', u'b'), + (0x1D484, 'M', u'c'), + (0x1D485, 'M', u'd'), + (0x1D486, 'M', u'e'), + (0x1D487, 'M', u'f'), + (0x1D488, 'M', u'g'), + (0x1D489, 'M', u'h'), + (0x1D48A, 'M', u'i'), + (0x1D48B, 'M', u'j'), + (0x1D48C, 'M', u'k'), + (0x1D48D, 'M', u'l'), + (0x1D48E, 'M', u'm'), + (0x1D48F, 'M', u'n'), + (0x1D490, 'M', u'o'), + (0x1D491, 'M', u'p'), + (0x1D492, 'M', u'q'), + (0x1D493, 'M', u'r'), + (0x1D494, 'M', u's'), + (0x1D495, 'M', u't'), + (0x1D496, 'M', u'u'), + (0x1D497, 'M', u'v'), + (0x1D498, 'M', u'w'), + (0x1D499, 'M', u'x'), + (0x1D49A, 'M', u'y'), + (0x1D49B, 'M', u'z'), + (0x1D49C, 'M', u'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', u'c'), + (0x1D49F, 'M', u'd'), + (0x1D4A0, 'X'), + (0x1D4A2, 'M', u'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', u'j'), + (0x1D4A6, 'M', u'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', u'n'), + (0x1D4AA, 'M', u'o'), + (0x1D4AB, 'M', u'p'), + (0x1D4AC, 'M', u'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', u's'), + (0x1D4AF, 'M', u't'), + (0x1D4B0, 'M', u'u'), + (0x1D4B1, 'M', u'v'), + (0x1D4B2, 'M', u'w'), + (0x1D4B3, 'M', u'x'), + (0x1D4B4, 'M', u'y'), + (0x1D4B5, 'M', u'z'), + (0x1D4B6, 'M', u'a'), + (0x1D4B7, 'M', u'b'), + (0x1D4B8, 'M', u'c'), + ] + +def _seg_61(): + return [ + (0x1D4B9, 'M', u'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', u'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', u'h'), + (0x1D4BE, 'M', u'i'), + (0x1D4BF, 'M', u'j'), + (0x1D4C0, 'M', u'k'), + (0x1D4C1, 'M', u'l'), + (0x1D4C2, 'M', u'm'), + (0x1D4C3, 'M', u'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', u'p'), + (0x1D4C6, 'M', u'q'), + (0x1D4C7, 'M', u'r'), + (0x1D4C8, 'M', u's'), + (0x1D4C9, 'M', u't'), + (0x1D4CA, 'M', u'u'), + (0x1D4CB, 'M', u'v'), + (0x1D4CC, 'M', u'w'), + (0x1D4CD, 'M', u'x'), + (0x1D4CE, 'M', u'y'), + (0x1D4CF, 'M', u'z'), + (0x1D4D0, 'M', u'a'), + (0x1D4D1, 'M', u'b'), + (0x1D4D2, 'M', u'c'), + (0x1D4D3, 'M', u'd'), + (0x1D4D4, 'M', u'e'), + (0x1D4D5, 'M', u'f'), + (0x1D4D6, 'M', u'g'), + (0x1D4D7, 'M', u'h'), + (0x1D4D8, 'M', u'i'), + (0x1D4D9, 'M', u'j'), + (0x1D4DA, 'M', u'k'), + (0x1D4DB, 'M', u'l'), + (0x1D4DC, 'M', u'm'), + (0x1D4DD, 'M', u'n'), + (0x1D4DE, 'M', u'o'), + (0x1D4DF, 'M', u'p'), + (0x1D4E0, 'M', u'q'), + (0x1D4E1, 'M', u'r'), + (0x1D4E2, 'M', u's'), + (0x1D4E3, 'M', u't'), + (0x1D4E4, 'M', u'u'), + (0x1D4E5, 'M', u'v'), + (0x1D4E6, 'M', u'w'), + (0x1D4E7, 'M', u'x'), + (0x1D4E8, 'M', u'y'), + (0x1D4E9, 'M', u'z'), + (0x1D4EA, 'M', u'a'), + (0x1D4EB, 'M', u'b'), + (0x1D4EC, 'M', u'c'), + (0x1D4ED, 'M', u'd'), + (0x1D4EE, 'M', u'e'), + (0x1D4EF, 'M', u'f'), + (0x1D4F0, 'M', u'g'), + (0x1D4F1, 'M', u'h'), + (0x1D4F2, 'M', u'i'), + (0x1D4F3, 'M', u'j'), + (0x1D4F4, 'M', u'k'), + (0x1D4F5, 'M', u'l'), + (0x1D4F6, 'M', u'm'), + (0x1D4F7, 'M', u'n'), + (0x1D4F8, 'M', u'o'), + (0x1D4F9, 'M', u'p'), + (0x1D4FA, 'M', u'q'), + (0x1D4FB, 'M', u'r'), + (0x1D4FC, 'M', u's'), + (0x1D4FD, 'M', u't'), + (0x1D4FE, 'M', u'u'), + (0x1D4FF, 'M', u'v'), + (0x1D500, 'M', u'w'), + (0x1D501, 'M', u'x'), + (0x1D502, 'M', u'y'), + (0x1D503, 'M', u'z'), + (0x1D504, 'M', u'a'), + (0x1D505, 'M', u'b'), + (0x1D506, 'X'), + (0x1D507, 'M', u'd'), + (0x1D508, 'M', u'e'), + (0x1D509, 'M', u'f'), + (0x1D50A, 'M', u'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', u'j'), + (0x1D50E, 'M', u'k'), + (0x1D50F, 'M', u'l'), + (0x1D510, 'M', u'm'), + (0x1D511, 'M', u'n'), + (0x1D512, 'M', u'o'), + (0x1D513, 'M', u'p'), + (0x1D514, 'M', u'q'), + (0x1D515, 'X'), + (0x1D516, 'M', u's'), + (0x1D517, 'M', u't'), + (0x1D518, 'M', u'u'), + (0x1D519, 'M', u'v'), + (0x1D51A, 'M', u'w'), + (0x1D51B, 'M', u'x'), + (0x1D51C, 'M', u'y'), + (0x1D51D, 'X'), + ] + +def _seg_62(): + return [ + (0x1D51E, 'M', u'a'), + (0x1D51F, 'M', u'b'), + (0x1D520, 'M', u'c'), + (0x1D521, 'M', u'd'), + (0x1D522, 'M', u'e'), + (0x1D523, 'M', u'f'), + (0x1D524, 'M', u'g'), + (0x1D525, 'M', u'h'), + (0x1D526, 'M', u'i'), + (0x1D527, 'M', u'j'), + (0x1D528, 'M', u'k'), + (0x1D529, 'M', u'l'), + (0x1D52A, 'M', u'm'), + (0x1D52B, 'M', u'n'), + (0x1D52C, 'M', u'o'), + (0x1D52D, 'M', u'p'), + (0x1D52E, 'M', u'q'), + (0x1D52F, 'M', u'r'), + (0x1D530, 'M', u's'), + (0x1D531, 'M', u't'), + (0x1D532, 'M', u'u'), + (0x1D533, 'M', u'v'), + (0x1D534, 'M', u'w'), + (0x1D535, 'M', u'x'), + (0x1D536, 'M', u'y'), + (0x1D537, 'M', u'z'), + (0x1D538, 'M', u'a'), + (0x1D539, 'M', u'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', u'd'), + (0x1D53C, 'M', u'e'), + (0x1D53D, 'M', u'f'), + (0x1D53E, 'M', u'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', u'i'), + (0x1D541, 'M', u'j'), + (0x1D542, 'M', u'k'), + (0x1D543, 'M', u'l'), + (0x1D544, 'M', u'm'), + (0x1D545, 'X'), + (0x1D546, 'M', u'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', u's'), + (0x1D54B, 'M', u't'), + (0x1D54C, 'M', u'u'), + (0x1D54D, 'M', u'v'), + (0x1D54E, 'M', u'w'), + (0x1D54F, 'M', u'x'), + (0x1D550, 'M', u'y'), + (0x1D551, 'X'), + (0x1D552, 'M', u'a'), + (0x1D553, 'M', u'b'), + (0x1D554, 'M', u'c'), + (0x1D555, 'M', u'd'), + (0x1D556, 'M', u'e'), + (0x1D557, 'M', u'f'), + (0x1D558, 'M', u'g'), + (0x1D559, 'M', u'h'), + (0x1D55A, 'M', u'i'), + (0x1D55B, 'M', u'j'), + (0x1D55C, 'M', u'k'), + (0x1D55D, 'M', u'l'), + (0x1D55E, 'M', u'm'), + (0x1D55F, 'M', u'n'), + (0x1D560, 'M', u'o'), + (0x1D561, 'M', u'p'), + (0x1D562, 'M', u'q'), + (0x1D563, 'M', u'r'), + (0x1D564, 'M', u's'), + (0x1D565, 'M', u't'), + (0x1D566, 'M', u'u'), + (0x1D567, 'M', u'v'), + (0x1D568, 'M', u'w'), + (0x1D569, 'M', u'x'), + (0x1D56A, 'M', u'y'), + (0x1D56B, 'M', u'z'), + (0x1D56C, 'M', u'a'), + (0x1D56D, 'M', u'b'), + (0x1D56E, 'M', u'c'), + (0x1D56F, 'M', u'd'), + (0x1D570, 'M', u'e'), + (0x1D571, 'M', u'f'), + (0x1D572, 'M', u'g'), + (0x1D573, 'M', u'h'), + (0x1D574, 'M', u'i'), + (0x1D575, 'M', u'j'), + (0x1D576, 'M', u'k'), + (0x1D577, 'M', u'l'), + (0x1D578, 'M', u'm'), + (0x1D579, 'M', u'n'), + (0x1D57A, 'M', u'o'), + (0x1D57B, 'M', u'p'), + (0x1D57C, 'M', u'q'), + (0x1D57D, 'M', u'r'), + (0x1D57E, 'M', u's'), + (0x1D57F, 'M', u't'), + (0x1D580, 'M', u'u'), + (0x1D581, 'M', u'v'), + (0x1D582, 'M', u'w'), + (0x1D583, 'M', u'x'), + ] + +def _seg_63(): + return [ + (0x1D584, 'M', u'y'), + (0x1D585, 'M', u'z'), + (0x1D586, 'M', u'a'), + (0x1D587, 'M', u'b'), + (0x1D588, 'M', u'c'), + (0x1D589, 'M', u'd'), + (0x1D58A, 'M', u'e'), + (0x1D58B, 'M', u'f'), + (0x1D58C, 'M', u'g'), + (0x1D58D, 'M', u'h'), + (0x1D58E, 'M', u'i'), + (0x1D58F, 'M', u'j'), + (0x1D590, 'M', u'k'), + (0x1D591, 'M', u'l'), + (0x1D592, 'M', u'm'), + (0x1D593, 'M', u'n'), + (0x1D594, 'M', u'o'), + (0x1D595, 'M', u'p'), + (0x1D596, 'M', u'q'), + (0x1D597, 'M', u'r'), + (0x1D598, 'M', u's'), + (0x1D599, 'M', u't'), + (0x1D59A, 'M', u'u'), + (0x1D59B, 'M', u'v'), + (0x1D59C, 'M', u'w'), + (0x1D59D, 'M', u'x'), + (0x1D59E, 'M', u'y'), + (0x1D59F, 'M', u'z'), + (0x1D5A0, 'M', u'a'), + (0x1D5A1, 'M', u'b'), + (0x1D5A2, 'M', u'c'), + (0x1D5A3, 'M', u'd'), + (0x1D5A4, 'M', u'e'), + (0x1D5A5, 'M', u'f'), + (0x1D5A6, 'M', u'g'), + (0x1D5A7, 'M', u'h'), + (0x1D5A8, 'M', u'i'), + (0x1D5A9, 'M', u'j'), + (0x1D5AA, 'M', u'k'), + (0x1D5AB, 'M', u'l'), + (0x1D5AC, 'M', u'm'), + (0x1D5AD, 'M', u'n'), + (0x1D5AE, 'M', u'o'), + (0x1D5AF, 'M', u'p'), + (0x1D5B0, 'M', u'q'), + (0x1D5B1, 'M', u'r'), + (0x1D5B2, 'M', u's'), + (0x1D5B3, 'M', u't'), + (0x1D5B4, 'M', u'u'), + (0x1D5B5, 'M', u'v'), + (0x1D5B6, 'M', u'w'), + (0x1D5B7, 'M', u'x'), + (0x1D5B8, 'M', u'y'), + (0x1D5B9, 'M', u'z'), + (0x1D5BA, 'M', u'a'), + (0x1D5BB, 'M', u'b'), + (0x1D5BC, 'M', u'c'), + (0x1D5BD, 'M', u'd'), + (0x1D5BE, 'M', u'e'), + (0x1D5BF, 'M', u'f'), + (0x1D5C0, 'M', u'g'), + (0x1D5C1, 'M', u'h'), + (0x1D5C2, 'M', u'i'), + (0x1D5C3, 'M', u'j'), + (0x1D5C4, 'M', u'k'), + (0x1D5C5, 'M', u'l'), + (0x1D5C6, 'M', u'm'), + (0x1D5C7, 'M', u'n'), + (0x1D5C8, 'M', u'o'), + (0x1D5C9, 'M', u'p'), + (0x1D5CA, 'M', u'q'), + (0x1D5CB, 'M', u'r'), + (0x1D5CC, 'M', u's'), + (0x1D5CD, 'M', u't'), + (0x1D5CE, 'M', u'u'), + (0x1D5CF, 'M', u'v'), + (0x1D5D0, 'M', u'w'), + (0x1D5D1, 'M', u'x'), + (0x1D5D2, 'M', u'y'), + (0x1D5D3, 'M', u'z'), + (0x1D5D4, 'M', u'a'), + (0x1D5D5, 'M', u'b'), + (0x1D5D6, 'M', u'c'), + (0x1D5D7, 'M', u'd'), + (0x1D5D8, 'M', u'e'), + (0x1D5D9, 'M', u'f'), + (0x1D5DA, 'M', u'g'), + (0x1D5DB, 'M', u'h'), + (0x1D5DC, 'M', u'i'), + (0x1D5DD, 'M', u'j'), + (0x1D5DE, 'M', u'k'), + (0x1D5DF, 'M', u'l'), + (0x1D5E0, 'M', u'm'), + (0x1D5E1, 'M', u'n'), + (0x1D5E2, 'M', u'o'), + (0x1D5E3, 'M', u'p'), + (0x1D5E4, 'M', u'q'), + (0x1D5E5, 'M', u'r'), + (0x1D5E6, 'M', u's'), + (0x1D5E7, 'M', u't'), + ] + +def _seg_64(): + return [ + (0x1D5E8, 'M', u'u'), + (0x1D5E9, 'M', u'v'), + (0x1D5EA, 'M', u'w'), + (0x1D5EB, 'M', u'x'), + (0x1D5EC, 'M', u'y'), + (0x1D5ED, 'M', u'z'), + (0x1D5EE, 'M', u'a'), + (0x1D5EF, 'M', u'b'), + (0x1D5F0, 'M', u'c'), + (0x1D5F1, 'M', u'd'), + (0x1D5F2, 'M', u'e'), + (0x1D5F3, 'M', u'f'), + (0x1D5F4, 'M', u'g'), + (0x1D5F5, 'M', u'h'), + (0x1D5F6, 'M', u'i'), + (0x1D5F7, 'M', u'j'), + (0x1D5F8, 'M', u'k'), + (0x1D5F9, 'M', u'l'), + (0x1D5FA, 'M', u'm'), + (0x1D5FB, 'M', u'n'), + (0x1D5FC, 'M', u'o'), + (0x1D5FD, 'M', u'p'), + (0x1D5FE, 'M', u'q'), + (0x1D5FF, 'M', u'r'), + (0x1D600, 'M', u's'), + (0x1D601, 'M', u't'), + (0x1D602, 'M', u'u'), + (0x1D603, 'M', u'v'), + (0x1D604, 'M', u'w'), + (0x1D605, 'M', u'x'), + (0x1D606, 'M', u'y'), + (0x1D607, 'M', u'z'), + (0x1D608, 'M', u'a'), + (0x1D609, 'M', u'b'), + (0x1D60A, 'M', u'c'), + (0x1D60B, 'M', u'd'), + (0x1D60C, 'M', u'e'), + (0x1D60D, 'M', u'f'), + (0x1D60E, 'M', u'g'), + (0x1D60F, 'M', u'h'), + (0x1D610, 'M', u'i'), + (0x1D611, 'M', u'j'), + (0x1D612, 'M', u'k'), + (0x1D613, 'M', u'l'), + (0x1D614, 'M', u'm'), + (0x1D615, 'M', u'n'), + (0x1D616, 'M', u'o'), + (0x1D617, 'M', u'p'), + (0x1D618, 'M', u'q'), + (0x1D619, 'M', u'r'), + (0x1D61A, 'M', u's'), + (0x1D61B, 'M', u't'), + (0x1D61C, 'M', u'u'), + (0x1D61D, 'M', u'v'), + (0x1D61E, 'M', u'w'), + (0x1D61F, 'M', u'x'), + (0x1D620, 'M', u'y'), + (0x1D621, 'M', u'z'), + (0x1D622, 'M', u'a'), + (0x1D623, 'M', u'b'), + (0x1D624, 'M', u'c'), + (0x1D625, 'M', u'd'), + (0x1D626, 'M', u'e'), + (0x1D627, 'M', u'f'), + (0x1D628, 'M', u'g'), + (0x1D629, 'M', u'h'), + (0x1D62A, 'M', u'i'), + (0x1D62B, 'M', u'j'), + (0x1D62C, 'M', u'k'), + (0x1D62D, 'M', u'l'), + (0x1D62E, 'M', u'm'), + (0x1D62F, 'M', u'n'), + (0x1D630, 'M', u'o'), + (0x1D631, 'M', u'p'), + (0x1D632, 'M', u'q'), + (0x1D633, 'M', u'r'), + (0x1D634, 'M', u's'), + (0x1D635, 'M', u't'), + (0x1D636, 'M', u'u'), + (0x1D637, 'M', u'v'), + (0x1D638, 'M', u'w'), + (0x1D639, 'M', u'x'), + (0x1D63A, 'M', u'y'), + (0x1D63B, 'M', u'z'), + (0x1D63C, 'M', u'a'), + (0x1D63D, 'M', u'b'), + (0x1D63E, 'M', u'c'), + (0x1D63F, 'M', u'd'), + (0x1D640, 'M', u'e'), + (0x1D641, 'M', u'f'), + (0x1D642, 'M', u'g'), + (0x1D643, 'M', u'h'), + (0x1D644, 'M', u'i'), + (0x1D645, 'M', u'j'), + (0x1D646, 'M', u'k'), + (0x1D647, 'M', u'l'), + (0x1D648, 'M', u'm'), + (0x1D649, 'M', u'n'), + (0x1D64A, 'M', u'o'), + (0x1D64B, 'M', u'p'), + ] + +def _seg_65(): + return [ + (0x1D64C, 'M', u'q'), + (0x1D64D, 'M', u'r'), + (0x1D64E, 'M', u's'), + (0x1D64F, 'M', u't'), + (0x1D650, 'M', u'u'), + (0x1D651, 'M', u'v'), + (0x1D652, 'M', u'w'), + (0x1D653, 'M', u'x'), + (0x1D654, 'M', u'y'), + (0x1D655, 'M', u'z'), + (0x1D656, 'M', u'a'), + (0x1D657, 'M', u'b'), + (0x1D658, 'M', u'c'), + (0x1D659, 'M', u'd'), + (0x1D65A, 'M', u'e'), + (0x1D65B, 'M', u'f'), + (0x1D65C, 'M', u'g'), + (0x1D65D, 'M', u'h'), + (0x1D65E, 'M', u'i'), + (0x1D65F, 'M', u'j'), + (0x1D660, 'M', u'k'), + (0x1D661, 'M', u'l'), + (0x1D662, 'M', u'm'), + (0x1D663, 'M', u'n'), + (0x1D664, 'M', u'o'), + (0x1D665, 'M', u'p'), + (0x1D666, 'M', u'q'), + (0x1D667, 'M', u'r'), + (0x1D668, 'M', u's'), + (0x1D669, 'M', u't'), + (0x1D66A, 'M', u'u'), + (0x1D66B, 'M', u'v'), + (0x1D66C, 'M', u'w'), + (0x1D66D, 'M', u'x'), + (0x1D66E, 'M', u'y'), + (0x1D66F, 'M', u'z'), + (0x1D670, 'M', u'a'), + (0x1D671, 'M', u'b'), + (0x1D672, 'M', u'c'), + (0x1D673, 'M', u'd'), + (0x1D674, 'M', u'e'), + (0x1D675, 'M', u'f'), + (0x1D676, 'M', u'g'), + (0x1D677, 'M', u'h'), + (0x1D678, 'M', u'i'), + (0x1D679, 'M', u'j'), + (0x1D67A, 'M', u'k'), + (0x1D67B, 'M', u'l'), + (0x1D67C, 'M', u'm'), + (0x1D67D, 'M', u'n'), + (0x1D67E, 'M', u'o'), + (0x1D67F, 'M', u'p'), + (0x1D680, 'M', u'q'), + (0x1D681, 'M', u'r'), + (0x1D682, 'M', u's'), + (0x1D683, 'M', u't'), + (0x1D684, 'M', u'u'), + (0x1D685, 'M', u'v'), + (0x1D686, 'M', u'w'), + (0x1D687, 'M', u'x'), + (0x1D688, 'M', u'y'), + (0x1D689, 'M', u'z'), + (0x1D68A, 'M', u'a'), + (0x1D68B, 'M', u'b'), + (0x1D68C, 'M', u'c'), + (0x1D68D, 'M', u'd'), + (0x1D68E, 'M', u'e'), + (0x1D68F, 'M', u'f'), + (0x1D690, 'M', u'g'), + (0x1D691, 'M', u'h'), + (0x1D692, 'M', u'i'), + (0x1D693, 'M', u'j'), + (0x1D694, 'M', u'k'), + (0x1D695, 'M', u'l'), + (0x1D696, 'M', u'm'), + (0x1D697, 'M', u'n'), + (0x1D698, 'M', u'o'), + (0x1D699, 'M', u'p'), + (0x1D69A, 'M', u'q'), + (0x1D69B, 'M', u'r'), + (0x1D69C, 'M', u's'), + (0x1D69D, 'M', u't'), + (0x1D69E, 'M', u'u'), + (0x1D69F, 'M', u'v'), + (0x1D6A0, 'M', u'w'), + (0x1D6A1, 'M', u'x'), + (0x1D6A2, 'M', u'y'), + (0x1D6A3, 'M', u'z'), + (0x1D6A4, 'M', u'ı'), + (0x1D6A5, 'M', u'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', u'α'), + (0x1D6A9, 'M', u'β'), + (0x1D6AA, 'M', u'γ'), + (0x1D6AB, 'M', u'δ'), + (0x1D6AC, 'M', u'ε'), + (0x1D6AD, 'M', u'ζ'), + (0x1D6AE, 'M', u'η'), + (0x1D6AF, 'M', u'θ'), + (0x1D6B0, 'M', u'ι'), + ] + +def _seg_66(): + return [ + (0x1D6B1, 'M', u'κ'), + (0x1D6B2, 'M', u'λ'), + (0x1D6B3, 'M', u'μ'), + (0x1D6B4, 'M', u'ν'), + (0x1D6B5, 'M', u'ξ'), + (0x1D6B6, 'M', u'ο'), + (0x1D6B7, 'M', u'π'), + (0x1D6B8, 'M', u'ρ'), + (0x1D6B9, 'M', u'θ'), + (0x1D6BA, 'M', u'σ'), + (0x1D6BB, 'M', u'τ'), + (0x1D6BC, 'M', u'υ'), + (0x1D6BD, 'M', u'φ'), + (0x1D6BE, 'M', u'χ'), + (0x1D6BF, 'M', u'ψ'), + (0x1D6C0, 'M', u'ω'), + (0x1D6C1, 'M', u'∇'), + (0x1D6C2, 'M', u'α'), + (0x1D6C3, 'M', u'β'), + (0x1D6C4, 'M', u'γ'), + (0x1D6C5, 'M', u'δ'), + (0x1D6C6, 'M', u'ε'), + (0x1D6C7, 'M', u'ζ'), + (0x1D6C8, 'M', u'η'), + (0x1D6C9, 'M', u'θ'), + (0x1D6CA, 'M', u'ι'), + (0x1D6CB, 'M', u'κ'), + (0x1D6CC, 'M', u'λ'), + (0x1D6CD, 'M', u'μ'), + (0x1D6CE, 'M', u'ν'), + (0x1D6CF, 'M', u'ξ'), + (0x1D6D0, 'M', u'ο'), + (0x1D6D1, 'M', u'π'), + (0x1D6D2, 'M', u'ρ'), + (0x1D6D3, 'M', u'σ'), + (0x1D6D5, 'M', u'τ'), + (0x1D6D6, 'M', u'υ'), + (0x1D6D7, 'M', u'φ'), + (0x1D6D8, 'M', u'χ'), + (0x1D6D9, 'M', u'ψ'), + (0x1D6DA, 'M', u'ω'), + (0x1D6DB, 'M', u'∂'), + (0x1D6DC, 'M', u'ε'), + (0x1D6DD, 'M', u'θ'), + (0x1D6DE, 'M', u'κ'), + (0x1D6DF, 'M', u'φ'), + (0x1D6E0, 'M', u'ρ'), + (0x1D6E1, 'M', u'π'), + (0x1D6E2, 'M', u'α'), + (0x1D6E3, 'M', u'β'), + (0x1D6E4, 'M', u'γ'), + (0x1D6E5, 'M', u'δ'), + (0x1D6E6, 'M', u'ε'), + (0x1D6E7, 'M', u'ζ'), + (0x1D6E8, 'M', u'η'), + (0x1D6E9, 'M', u'θ'), + (0x1D6EA, 'M', u'ι'), + (0x1D6EB, 'M', u'κ'), + (0x1D6EC, 'M', u'λ'), + (0x1D6ED, 'M', u'μ'), + (0x1D6EE, 'M', u'ν'), + (0x1D6EF, 'M', u'ξ'), + (0x1D6F0, 'M', u'ο'), + (0x1D6F1, 'M', u'π'), + (0x1D6F2, 'M', u'ρ'), + (0x1D6F3, 'M', u'θ'), + (0x1D6F4, 'M', u'σ'), + (0x1D6F5, 'M', u'τ'), + (0x1D6F6, 'M', u'υ'), + (0x1D6F7, 'M', u'φ'), + (0x1D6F8, 'M', u'χ'), + (0x1D6F9, 'M', u'ψ'), + (0x1D6FA, 'M', u'ω'), + (0x1D6FB, 'M', u'∇'), + (0x1D6FC, 'M', u'α'), + (0x1D6FD, 'M', u'β'), + (0x1D6FE, 'M', u'γ'), + (0x1D6FF, 'M', u'δ'), + (0x1D700, 'M', u'ε'), + (0x1D701, 'M', u'ζ'), + (0x1D702, 'M', u'η'), + (0x1D703, 'M', u'θ'), + (0x1D704, 'M', u'ι'), + (0x1D705, 'M', u'κ'), + (0x1D706, 'M', u'λ'), + (0x1D707, 'M', u'μ'), + (0x1D708, 'M', u'ν'), + (0x1D709, 'M', u'ξ'), + (0x1D70A, 'M', u'ο'), + (0x1D70B, 'M', u'π'), + (0x1D70C, 'M', u'ρ'), + (0x1D70D, 'M', u'σ'), + (0x1D70F, 'M', u'τ'), + (0x1D710, 'M', u'υ'), + (0x1D711, 'M', u'φ'), + (0x1D712, 'M', u'χ'), + (0x1D713, 'M', u'ψ'), + (0x1D714, 'M', u'ω'), + (0x1D715, 'M', u'∂'), + (0x1D716, 'M', u'ε'), + ] + +def _seg_67(): + return [ + (0x1D717, 'M', u'θ'), + (0x1D718, 'M', u'κ'), + (0x1D719, 'M', u'φ'), + (0x1D71A, 'M', u'ρ'), + (0x1D71B, 'M', u'π'), + (0x1D71C, 'M', u'α'), + (0x1D71D, 'M', u'β'), + (0x1D71E, 'M', u'γ'), + (0x1D71F, 'M', u'δ'), + (0x1D720, 'M', u'ε'), + (0x1D721, 'M', u'ζ'), + (0x1D722, 'M', u'η'), + (0x1D723, 'M', u'θ'), + (0x1D724, 'M', u'ι'), + (0x1D725, 'M', u'κ'), + (0x1D726, 'M', u'λ'), + (0x1D727, 'M', u'μ'), + (0x1D728, 'M', u'ν'), + (0x1D729, 'M', u'ξ'), + (0x1D72A, 'M', u'ο'), + (0x1D72B, 'M', u'π'), + (0x1D72C, 'M', u'ρ'), + (0x1D72D, 'M', u'θ'), + (0x1D72E, 'M', u'σ'), + (0x1D72F, 'M', u'τ'), + (0x1D730, 'M', u'υ'), + (0x1D731, 'M', u'φ'), + (0x1D732, 'M', u'χ'), + (0x1D733, 'M', u'ψ'), + (0x1D734, 'M', u'ω'), + (0x1D735, 'M', u'∇'), + (0x1D736, 'M', u'α'), + (0x1D737, 'M', u'β'), + (0x1D738, 'M', u'γ'), + (0x1D739, 'M', u'δ'), + (0x1D73A, 'M', u'ε'), + (0x1D73B, 'M', u'ζ'), + (0x1D73C, 'M', u'η'), + (0x1D73D, 'M', u'θ'), + (0x1D73E, 'M', u'ι'), + (0x1D73F, 'M', u'κ'), + (0x1D740, 'M', u'λ'), + (0x1D741, 'M', u'μ'), + (0x1D742, 'M', u'ν'), + (0x1D743, 'M', u'ξ'), + (0x1D744, 'M', u'ο'), + (0x1D745, 'M', u'π'), + (0x1D746, 'M', u'ρ'), + (0x1D747, 'M', u'σ'), + (0x1D749, 'M', u'τ'), + (0x1D74A, 'M', u'υ'), + (0x1D74B, 'M', u'φ'), + (0x1D74C, 'M', u'χ'), + (0x1D74D, 'M', u'ψ'), + (0x1D74E, 'M', u'ω'), + (0x1D74F, 'M', u'∂'), + (0x1D750, 'M', u'ε'), + (0x1D751, 'M', u'θ'), + (0x1D752, 'M', u'κ'), + (0x1D753, 'M', u'φ'), + (0x1D754, 'M', u'ρ'), + (0x1D755, 'M', u'π'), + (0x1D756, 'M', u'α'), + (0x1D757, 'M', u'β'), + (0x1D758, 'M', u'γ'), + (0x1D759, 'M', u'δ'), + (0x1D75A, 'M', u'ε'), + (0x1D75B, 'M', u'ζ'), + (0x1D75C, 'M', u'η'), + (0x1D75D, 'M', u'θ'), + (0x1D75E, 'M', u'ι'), + (0x1D75F, 'M', u'κ'), + (0x1D760, 'M', u'λ'), + (0x1D761, 'M', u'μ'), + (0x1D762, 'M', u'ν'), + (0x1D763, 'M', u'ξ'), + (0x1D764, 'M', u'ο'), + (0x1D765, 'M', u'π'), + (0x1D766, 'M', u'ρ'), + (0x1D767, 'M', u'θ'), + (0x1D768, 'M', u'σ'), + (0x1D769, 'M', u'τ'), + (0x1D76A, 'M', u'υ'), + (0x1D76B, 'M', u'φ'), + (0x1D76C, 'M', u'χ'), + (0x1D76D, 'M', u'ψ'), + (0x1D76E, 'M', u'ω'), + (0x1D76F, 'M', u'∇'), + (0x1D770, 'M', u'α'), + (0x1D771, 'M', u'β'), + (0x1D772, 'M', u'γ'), + (0x1D773, 'M', u'δ'), + (0x1D774, 'M', u'ε'), + (0x1D775, 'M', u'ζ'), + (0x1D776, 'M', u'η'), + (0x1D777, 'M', u'θ'), + (0x1D778, 'M', u'ι'), + (0x1D779, 'M', u'κ'), + (0x1D77A, 'M', u'λ'), + (0x1D77B, 'M', u'μ'), + ] + +def _seg_68(): + return [ + (0x1D77C, 'M', u'ν'), + (0x1D77D, 'M', u'ξ'), + (0x1D77E, 'M', u'ο'), + (0x1D77F, 'M', u'π'), + (0x1D780, 'M', u'ρ'), + (0x1D781, 'M', u'σ'), + (0x1D783, 'M', u'τ'), + (0x1D784, 'M', u'υ'), + (0x1D785, 'M', u'φ'), + (0x1D786, 'M', u'χ'), + (0x1D787, 'M', u'ψ'), + (0x1D788, 'M', u'ω'), + (0x1D789, 'M', u'∂'), + (0x1D78A, 'M', u'ε'), + (0x1D78B, 'M', u'θ'), + (0x1D78C, 'M', u'κ'), + (0x1D78D, 'M', u'φ'), + (0x1D78E, 'M', u'ρ'), + (0x1D78F, 'M', u'π'), + (0x1D790, 'M', u'α'), + (0x1D791, 'M', u'β'), + (0x1D792, 'M', u'γ'), + (0x1D793, 'M', u'δ'), + (0x1D794, 'M', u'ε'), + (0x1D795, 'M', u'ζ'), + (0x1D796, 'M', u'η'), + (0x1D797, 'M', u'θ'), + (0x1D798, 'M', u'ι'), + (0x1D799, 'M', u'κ'), + (0x1D79A, 'M', u'λ'), + (0x1D79B, 'M', u'μ'), + (0x1D79C, 'M', u'ν'), + (0x1D79D, 'M', u'ξ'), + (0x1D79E, 'M', u'ο'), + (0x1D79F, 'M', u'π'), + (0x1D7A0, 'M', u'ρ'), + (0x1D7A1, 'M', u'θ'), + (0x1D7A2, 'M', u'σ'), + (0x1D7A3, 'M', u'τ'), + (0x1D7A4, 'M', u'υ'), + (0x1D7A5, 'M', u'φ'), + (0x1D7A6, 'M', u'χ'), + (0x1D7A7, 'M', u'ψ'), + (0x1D7A8, 'M', u'ω'), + (0x1D7A9, 'M', u'∇'), + (0x1D7AA, 'M', u'α'), + (0x1D7AB, 'M', u'β'), + (0x1D7AC, 'M', u'γ'), + (0x1D7AD, 'M', u'δ'), + (0x1D7AE, 'M', u'ε'), + (0x1D7AF, 'M', u'ζ'), + (0x1D7B0, 'M', u'η'), + (0x1D7B1, 'M', u'θ'), + (0x1D7B2, 'M', u'ι'), + (0x1D7B3, 'M', u'κ'), + (0x1D7B4, 'M', u'λ'), + (0x1D7B5, 'M', u'μ'), + (0x1D7B6, 'M', u'ν'), + (0x1D7B7, 'M', u'ξ'), + (0x1D7B8, 'M', u'ο'), + (0x1D7B9, 'M', u'π'), + (0x1D7BA, 'M', u'ρ'), + (0x1D7BB, 'M', u'σ'), + (0x1D7BD, 'M', u'τ'), + (0x1D7BE, 'M', u'υ'), + (0x1D7BF, 'M', u'φ'), + (0x1D7C0, 'M', u'χ'), + (0x1D7C1, 'M', u'ψ'), + (0x1D7C2, 'M', u'ω'), + (0x1D7C3, 'M', u'∂'), + (0x1D7C4, 'M', u'ε'), + (0x1D7C5, 'M', u'θ'), + (0x1D7C6, 'M', u'κ'), + (0x1D7C7, 'M', u'φ'), + (0x1D7C8, 'M', u'ρ'), + (0x1D7C9, 'M', u'π'), + (0x1D7CA, 'M', u'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', u'0'), + (0x1D7CF, 'M', u'1'), + (0x1D7D0, 'M', u'2'), + (0x1D7D1, 'M', u'3'), + (0x1D7D2, 'M', u'4'), + (0x1D7D3, 'M', u'5'), + (0x1D7D4, 'M', u'6'), + (0x1D7D5, 'M', u'7'), + (0x1D7D6, 'M', u'8'), + (0x1D7D7, 'M', u'9'), + (0x1D7D8, 'M', u'0'), + (0x1D7D9, 'M', u'1'), + (0x1D7DA, 'M', u'2'), + (0x1D7DB, 'M', u'3'), + (0x1D7DC, 'M', u'4'), + (0x1D7DD, 'M', u'5'), + (0x1D7DE, 'M', u'6'), + (0x1D7DF, 'M', u'7'), + (0x1D7E0, 'M', u'8'), + (0x1D7E1, 'M', u'9'), + (0x1D7E2, 'M', u'0'), + (0x1D7E3, 'M', u'1'), + ] + +def _seg_69(): + return [ + (0x1D7E4, 'M', u'2'), + (0x1D7E5, 'M', u'3'), + (0x1D7E6, 'M', u'4'), + (0x1D7E7, 'M', u'5'), + (0x1D7E8, 'M', u'6'), + (0x1D7E9, 'M', u'7'), + (0x1D7EA, 'M', u'8'), + (0x1D7EB, 'M', u'9'), + (0x1D7EC, 'M', u'0'), + (0x1D7ED, 'M', u'1'), + (0x1D7EE, 'M', u'2'), + (0x1D7EF, 'M', u'3'), + (0x1D7F0, 'M', u'4'), + (0x1D7F1, 'M', u'5'), + (0x1D7F2, 'M', u'6'), + (0x1D7F3, 'M', u'7'), + (0x1D7F4, 'M', u'8'), + (0x1D7F5, 'M', u'9'), + (0x1D7F6, 'M', u'0'), + (0x1D7F7, 'M', u'1'), + (0x1D7F8, 'M', u'2'), + (0x1D7F9, 'M', u'3'), + (0x1D7FA, 'M', u'4'), + (0x1D7FB, 'M', u'5'), + (0x1D7FC, 'M', u'6'), + (0x1D7FD, 'M', u'7'), + (0x1D7FE, 'M', u'8'), + (0x1D7FF, 'M', u'9'), + (0x1D800, 'V'), + (0x1DA8C, 'X'), + (0x1DA9B, 'V'), + (0x1DAA0, 'X'), + (0x1DAA1, 'V'), + (0x1DAB0, 'X'), + (0x1E000, 'V'), + (0x1E007, 'X'), + (0x1E008, 'V'), + (0x1E019, 'X'), + (0x1E01B, 'V'), + (0x1E022, 'X'), + (0x1E023, 'V'), + (0x1E025, 'X'), + (0x1E026, 'V'), + (0x1E02B, 'X'), + (0x1E100, 'V'), + (0x1E12D, 'X'), + (0x1E130, 'V'), + (0x1E13E, 'X'), + (0x1E140, 'V'), + (0x1E14A, 'X'), + (0x1E14E, 'V'), + (0x1E150, 'X'), + (0x1E2C0, 'V'), + (0x1E2FA, 'X'), + (0x1E2FF, 'V'), + (0x1E300, 'X'), + (0x1E800, 'V'), + (0x1E8C5, 'X'), + (0x1E8C7, 'V'), + (0x1E8D7, 'X'), + (0x1E900, 'M', u'𞤢'), + (0x1E901, 'M', u'𞤣'), + (0x1E902, 'M', u'𞤤'), + (0x1E903, 'M', u'𞤥'), + (0x1E904, 'M', u'𞤦'), + (0x1E905, 'M', u'𞤧'), + (0x1E906, 'M', u'𞤨'), + (0x1E907, 'M', u'𞤩'), + (0x1E908, 'M', u'𞤪'), + (0x1E909, 'M', u'𞤫'), + (0x1E90A, 'M', u'𞤬'), + (0x1E90B, 'M', u'𞤭'), + (0x1E90C, 'M', u'𞤮'), + (0x1E90D, 'M', u'𞤯'), + (0x1E90E, 'M', u'𞤰'), + (0x1E90F, 'M', u'𞤱'), + (0x1E910, 'M', u'𞤲'), + (0x1E911, 'M', u'𞤳'), + (0x1E912, 'M', u'𞤴'), + (0x1E913, 'M', u'𞤵'), + (0x1E914, 'M', u'𞤶'), + (0x1E915, 'M', u'𞤷'), + (0x1E916, 'M', u'𞤸'), + (0x1E917, 'M', u'𞤹'), + (0x1E918, 'M', u'𞤺'), + (0x1E919, 'M', u'𞤻'), + (0x1E91A, 'M', u'𞤼'), + (0x1E91B, 'M', u'𞤽'), + (0x1E91C, 'M', u'𞤾'), + (0x1E91D, 'M', u'𞤿'), + (0x1E91E, 'M', u'𞥀'), + (0x1E91F, 'M', u'𞥁'), + (0x1E920, 'M', u'𞥂'), + (0x1E921, 'M', u'𞥃'), + (0x1E922, 'V'), + (0x1E94C, 'X'), + (0x1E950, 'V'), + (0x1E95A, 'X'), + (0x1E95E, 'V'), + (0x1E960, 'X'), + ] + +def _seg_70(): + return [ + (0x1EC71, 'V'), + (0x1ECB5, 'X'), + (0x1ED01, 'V'), + (0x1ED3E, 'X'), + (0x1EE00, 'M', u'ا'), + (0x1EE01, 'M', u'ب'), + (0x1EE02, 'M', u'ج'), + (0x1EE03, 'M', u'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', u'و'), + (0x1EE06, 'M', u'ز'), + (0x1EE07, 'M', u'ح'), + (0x1EE08, 'M', u'ط'), + (0x1EE09, 'M', u'ي'), + (0x1EE0A, 'M', u'ك'), + (0x1EE0B, 'M', u'ل'), + (0x1EE0C, 'M', u'م'), + (0x1EE0D, 'M', u'ن'), + (0x1EE0E, 'M', u'س'), + (0x1EE0F, 'M', u'ع'), + (0x1EE10, 'M', u'ف'), + (0x1EE11, 'M', u'ص'), + (0x1EE12, 'M', u'ق'), + (0x1EE13, 'M', u'ر'), + (0x1EE14, 'M', u'ش'), + (0x1EE15, 'M', u'ت'), + (0x1EE16, 'M', u'ث'), + (0x1EE17, 'M', u'خ'), + (0x1EE18, 'M', u'ذ'), + (0x1EE19, 'M', u'ض'), + (0x1EE1A, 'M', u'ظ'), + (0x1EE1B, 'M', u'غ'), + (0x1EE1C, 'M', u'ٮ'), + (0x1EE1D, 'M', u'ں'), + (0x1EE1E, 'M', u'ڡ'), + (0x1EE1F, 'M', u'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', u'ب'), + (0x1EE22, 'M', u'ج'), + (0x1EE23, 'X'), + (0x1EE24, 'M', u'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', u'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', u'ي'), + (0x1EE2A, 'M', u'ك'), + (0x1EE2B, 'M', u'ل'), + (0x1EE2C, 'M', u'م'), + (0x1EE2D, 'M', u'ن'), + (0x1EE2E, 'M', u'س'), + (0x1EE2F, 'M', u'ع'), + (0x1EE30, 'M', u'ف'), + (0x1EE31, 'M', u'ص'), + (0x1EE32, 'M', u'ق'), + (0x1EE33, 'X'), + (0x1EE34, 'M', u'ش'), + (0x1EE35, 'M', u'ت'), + (0x1EE36, 'M', u'ث'), + (0x1EE37, 'M', u'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', u'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', u'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', u'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', u'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', u'ي'), + (0x1EE4A, 'X'), + (0x1EE4B, 'M', u'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', u'ن'), + (0x1EE4E, 'M', u'س'), + (0x1EE4F, 'M', u'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', u'ص'), + (0x1EE52, 'M', u'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', u'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', u'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', u'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', u'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', u'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', u'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', u'ب'), + (0x1EE62, 'M', u'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', u'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', u'ح'), + (0x1EE68, 'M', u'ط'), + (0x1EE69, 'M', u'ي'), + (0x1EE6A, 'M', u'ك'), + ] + +def _seg_71(): + return [ + (0x1EE6B, 'X'), + (0x1EE6C, 'M', u'م'), + (0x1EE6D, 'M', u'ن'), + (0x1EE6E, 'M', u'س'), + (0x1EE6F, 'M', u'ع'), + (0x1EE70, 'M', u'ف'), + (0x1EE71, 'M', u'ص'), + (0x1EE72, 'M', u'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', u'ش'), + (0x1EE75, 'M', u'ت'), + (0x1EE76, 'M', u'ث'), + (0x1EE77, 'M', u'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', u'ض'), + (0x1EE7A, 'M', u'ظ'), + (0x1EE7B, 'M', u'غ'), + (0x1EE7C, 'M', u'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', u'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', u'ا'), + (0x1EE81, 'M', u'ب'), + (0x1EE82, 'M', u'ج'), + (0x1EE83, 'M', u'د'), + (0x1EE84, 'M', u'ه'), + (0x1EE85, 'M', u'و'), + (0x1EE86, 'M', u'ز'), + (0x1EE87, 'M', u'ح'), + (0x1EE88, 'M', u'ط'), + (0x1EE89, 'M', u'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', u'ل'), + (0x1EE8C, 'M', u'م'), + (0x1EE8D, 'M', u'ن'), + (0x1EE8E, 'M', u'س'), + (0x1EE8F, 'M', u'ع'), + (0x1EE90, 'M', u'ف'), + (0x1EE91, 'M', u'ص'), + (0x1EE92, 'M', u'ق'), + (0x1EE93, 'M', u'ر'), + (0x1EE94, 'M', u'ش'), + (0x1EE95, 'M', u'ت'), + (0x1EE96, 'M', u'ث'), + (0x1EE97, 'M', u'خ'), + (0x1EE98, 'M', u'ذ'), + (0x1EE99, 'M', u'ض'), + (0x1EE9A, 'M', u'ظ'), + (0x1EE9B, 'M', u'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', u'ب'), + (0x1EEA2, 'M', u'ج'), + (0x1EEA3, 'M', u'د'), + (0x1EEA4, 'X'), + (0x1EEA5, 'M', u'و'), + (0x1EEA6, 'M', u'ز'), + (0x1EEA7, 'M', u'ح'), + (0x1EEA8, 'M', u'ط'), + (0x1EEA9, 'M', u'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', u'ل'), + (0x1EEAC, 'M', u'م'), + (0x1EEAD, 'M', u'ن'), + (0x1EEAE, 'M', u'س'), + (0x1EEAF, 'M', u'ع'), + (0x1EEB0, 'M', u'ف'), + (0x1EEB1, 'M', u'ص'), + (0x1EEB2, 'M', u'ق'), + (0x1EEB3, 'M', u'ر'), + (0x1EEB4, 'M', u'ش'), + (0x1EEB5, 'M', u'ت'), + (0x1EEB6, 'M', u'ث'), + (0x1EEB7, 'M', u'خ'), + (0x1EEB8, 'M', u'ذ'), + (0x1EEB9, 'M', u'ض'), + (0x1EEBA, 'M', u'ظ'), + (0x1EEBB, 'M', u'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0C0, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0F6, 'X'), + (0x1F101, '3', u'0,'), + (0x1F102, '3', u'1,'), + (0x1F103, '3', u'2,'), + (0x1F104, '3', u'3,'), + (0x1F105, '3', u'4,'), + (0x1F106, '3', u'5,'), + (0x1F107, '3', u'6,'), + (0x1F108, '3', u'7,'), + ] + +def _seg_72(): + return [ + (0x1F109, '3', u'8,'), + (0x1F10A, '3', u'9,'), + (0x1F10B, 'V'), + (0x1F110, '3', u'(a)'), + (0x1F111, '3', u'(b)'), + (0x1F112, '3', u'(c)'), + (0x1F113, '3', u'(d)'), + (0x1F114, '3', u'(e)'), + (0x1F115, '3', u'(f)'), + (0x1F116, '3', u'(g)'), + (0x1F117, '3', u'(h)'), + (0x1F118, '3', u'(i)'), + (0x1F119, '3', u'(j)'), + (0x1F11A, '3', u'(k)'), + (0x1F11B, '3', u'(l)'), + (0x1F11C, '3', u'(m)'), + (0x1F11D, '3', u'(n)'), + (0x1F11E, '3', u'(o)'), + (0x1F11F, '3', u'(p)'), + (0x1F120, '3', u'(q)'), + (0x1F121, '3', u'(r)'), + (0x1F122, '3', u'(s)'), + (0x1F123, '3', u'(t)'), + (0x1F124, '3', u'(u)'), + (0x1F125, '3', u'(v)'), + (0x1F126, '3', u'(w)'), + (0x1F127, '3', u'(x)'), + (0x1F128, '3', u'(y)'), + (0x1F129, '3', u'(z)'), + (0x1F12A, 'M', u'〔s〕'), + (0x1F12B, 'M', u'c'), + (0x1F12C, 'M', u'r'), + (0x1F12D, 'M', u'cd'), + (0x1F12E, 'M', u'wz'), + (0x1F12F, 'V'), + (0x1F130, 'M', u'a'), + (0x1F131, 'M', u'b'), + (0x1F132, 'M', u'c'), + (0x1F133, 'M', u'd'), + (0x1F134, 'M', u'e'), + (0x1F135, 'M', u'f'), + (0x1F136, 'M', u'g'), + (0x1F137, 'M', u'h'), + (0x1F138, 'M', u'i'), + (0x1F139, 'M', u'j'), + (0x1F13A, 'M', u'k'), + (0x1F13B, 'M', u'l'), + (0x1F13C, 'M', u'm'), + (0x1F13D, 'M', u'n'), + (0x1F13E, 'M', u'o'), + (0x1F13F, 'M', u'p'), + (0x1F140, 'M', u'q'), + (0x1F141, 'M', u'r'), + (0x1F142, 'M', u's'), + (0x1F143, 'M', u't'), + (0x1F144, 'M', u'u'), + (0x1F145, 'M', u'v'), + (0x1F146, 'M', u'w'), + (0x1F147, 'M', u'x'), + (0x1F148, 'M', u'y'), + (0x1F149, 'M', u'z'), + (0x1F14A, 'M', u'hv'), + (0x1F14B, 'M', u'mv'), + (0x1F14C, 'M', u'sd'), + (0x1F14D, 'M', u'ss'), + (0x1F14E, 'M', u'ppv'), + (0x1F14F, 'M', u'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', u'mc'), + (0x1F16B, 'M', u'md'), + (0x1F16C, 'M', u'mr'), + (0x1F16D, 'V'), + (0x1F190, 'M', u'dj'), + (0x1F191, 'V'), + (0x1F1AE, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', u'ほか'), + (0x1F201, 'M', u'ココ'), + (0x1F202, 'M', u'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', u'手'), + (0x1F211, 'M', u'字'), + (0x1F212, 'M', u'双'), + (0x1F213, 'M', u'デ'), + (0x1F214, 'M', u'二'), + (0x1F215, 'M', u'多'), + (0x1F216, 'M', u'解'), + (0x1F217, 'M', u'天'), + (0x1F218, 'M', u'交'), + (0x1F219, 'M', u'映'), + (0x1F21A, 'M', u'無'), + (0x1F21B, 'M', u'料'), + (0x1F21C, 'M', u'前'), + (0x1F21D, 'M', u'後'), + (0x1F21E, 'M', u'再'), + (0x1F21F, 'M', u'新'), + (0x1F220, 'M', u'初'), + (0x1F221, 'M', u'終'), + (0x1F222, 'M', u'生'), + (0x1F223, 'M', u'販'), + ] + +def _seg_73(): + return [ + (0x1F224, 'M', u'声'), + (0x1F225, 'M', u'吹'), + (0x1F226, 'M', u'演'), + (0x1F227, 'M', u'投'), + (0x1F228, 'M', u'捕'), + (0x1F229, 'M', u'一'), + (0x1F22A, 'M', u'三'), + (0x1F22B, 'M', u'遊'), + (0x1F22C, 'M', u'左'), + (0x1F22D, 'M', u'中'), + (0x1F22E, 'M', u'右'), + (0x1F22F, 'M', u'指'), + (0x1F230, 'M', u'走'), + (0x1F231, 'M', u'打'), + (0x1F232, 'M', u'禁'), + (0x1F233, 'M', u'空'), + (0x1F234, 'M', u'合'), + (0x1F235, 'M', u'満'), + (0x1F236, 'M', u'有'), + (0x1F237, 'M', u'月'), + (0x1F238, 'M', u'申'), + (0x1F239, 'M', u'割'), + (0x1F23A, 'M', u'営'), + (0x1F23B, 'M', u'配'), + (0x1F23C, 'X'), + (0x1F240, 'M', u'〔本〕'), + (0x1F241, 'M', u'〔三〕'), + (0x1F242, 'M', u'〔二〕'), + (0x1F243, 'M', u'〔安〕'), + (0x1F244, 'M', u'〔点〕'), + (0x1F245, 'M', u'〔打〕'), + (0x1F246, 'M', u'〔盗〕'), + (0x1F247, 'M', u'〔勝〕'), + (0x1F248, 'M', u'〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', u'得'), + (0x1F251, 'M', u'可'), + (0x1F252, 'X'), + (0x1F260, 'V'), + (0x1F266, 'X'), + (0x1F300, 'V'), + (0x1F6D8, 'X'), + (0x1F6E0, 'V'), + (0x1F6ED, 'X'), + (0x1F6F0, 'V'), + (0x1F6FD, 'X'), + (0x1F700, 'V'), + (0x1F774, 'X'), + (0x1F780, 'V'), + (0x1F7D9, 'X'), + (0x1F7E0, 'V'), + (0x1F7EC, 'X'), + (0x1F800, 'V'), + (0x1F80C, 'X'), + (0x1F810, 'V'), + (0x1F848, 'X'), + (0x1F850, 'V'), + (0x1F85A, 'X'), + (0x1F860, 'V'), + (0x1F888, 'X'), + (0x1F890, 'V'), + (0x1F8AE, 'X'), + (0x1F8B0, 'V'), + (0x1F8B2, 'X'), + (0x1F900, 'V'), + (0x1F979, 'X'), + (0x1F97A, 'V'), + (0x1F9CC, 'X'), + (0x1F9CD, 'V'), + (0x1FA54, 'X'), + (0x1FA60, 'V'), + (0x1FA6E, 'X'), + (0x1FA70, 'V'), + (0x1FA75, 'X'), + (0x1FA78, 'V'), + (0x1FA7B, 'X'), + (0x1FA80, 'V'), + (0x1FA87, 'X'), + (0x1FA90, 'V'), + (0x1FAA9, 'X'), + (0x1FAB0, 'V'), + (0x1FAB7, 'X'), + (0x1FAC0, 'V'), + (0x1FAC3, 'X'), + (0x1FAD0, 'V'), + (0x1FAD7, 'X'), + (0x1FB00, 'V'), + (0x1FB93, 'X'), + (0x1FB94, 'V'), + (0x1FBCB, 'X'), + (0x1FBF0, 'M', u'0'), + (0x1FBF1, 'M', u'1'), + (0x1FBF2, 'M', u'2'), + (0x1FBF3, 'M', u'3'), + (0x1FBF4, 'M', u'4'), + (0x1FBF5, 'M', u'5'), + (0x1FBF6, 'M', u'6'), + (0x1FBF7, 'M', u'7'), + (0x1FBF8, 'M', u'8'), + (0x1FBF9, 'M', u'9'), + ] + +def _seg_74(): + return [ + (0x1FBFA, 'X'), + (0x20000, 'V'), + (0x2A6DE, 'X'), + (0x2A700, 'V'), + (0x2B735, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2B820, 'V'), + (0x2CEA2, 'X'), + (0x2CEB0, 'V'), + (0x2EBE1, 'X'), + (0x2F800, 'M', u'丽'), + (0x2F801, 'M', u'丸'), + (0x2F802, 'M', u'乁'), + (0x2F803, 'M', u'𠄢'), + (0x2F804, 'M', u'你'), + (0x2F805, 'M', u'侮'), + (0x2F806, 'M', u'侻'), + (0x2F807, 'M', u'倂'), + (0x2F808, 'M', u'偺'), + (0x2F809, 'M', u'備'), + (0x2F80A, 'M', u'僧'), + (0x2F80B, 'M', u'像'), + (0x2F80C, 'M', u'㒞'), + (0x2F80D, 'M', u'𠘺'), + (0x2F80E, 'M', u'免'), + (0x2F80F, 'M', u'兔'), + (0x2F810, 'M', u'兤'), + (0x2F811, 'M', u'具'), + (0x2F812, 'M', u'𠔜'), + (0x2F813, 'M', u'㒹'), + (0x2F814, 'M', u'內'), + (0x2F815, 'M', u'再'), + (0x2F816, 'M', u'𠕋'), + (0x2F817, 'M', u'冗'), + (0x2F818, 'M', u'冤'), + (0x2F819, 'M', u'仌'), + (0x2F81A, 'M', u'冬'), + (0x2F81B, 'M', u'况'), + (0x2F81C, 'M', u'𩇟'), + (0x2F81D, 'M', u'凵'), + (0x2F81E, 'M', u'刃'), + (0x2F81F, 'M', u'㓟'), + (0x2F820, 'M', u'刻'), + (0x2F821, 'M', u'剆'), + (0x2F822, 'M', u'割'), + (0x2F823, 'M', u'剷'), + (0x2F824, 'M', u'㔕'), + (0x2F825, 'M', u'勇'), + (0x2F826, 'M', u'勉'), + (0x2F827, 'M', u'勤'), + (0x2F828, 'M', u'勺'), + (0x2F829, 'M', u'包'), + (0x2F82A, 'M', u'匆'), + (0x2F82B, 'M', u'北'), + (0x2F82C, 'M', u'卉'), + (0x2F82D, 'M', u'卑'), + (0x2F82E, 'M', u'博'), + (0x2F82F, 'M', u'即'), + (0x2F830, 'M', u'卽'), + (0x2F831, 'M', u'卿'), + (0x2F834, 'M', u'𠨬'), + (0x2F835, 'M', u'灰'), + (0x2F836, 'M', u'及'), + (0x2F837, 'M', u'叟'), + (0x2F838, 'M', u'𠭣'), + (0x2F839, 'M', u'叫'), + (0x2F83A, 'M', u'叱'), + (0x2F83B, 'M', u'吆'), + (0x2F83C, 'M', u'咞'), + (0x2F83D, 'M', u'吸'), + (0x2F83E, 'M', u'呈'), + (0x2F83F, 'M', u'周'), + (0x2F840, 'M', u'咢'), + (0x2F841, 'M', u'哶'), + (0x2F842, 'M', u'唐'), + (0x2F843, 'M', u'啓'), + (0x2F844, 'M', u'啣'), + (0x2F845, 'M', u'善'), + (0x2F847, 'M', u'喙'), + (0x2F848, 'M', u'喫'), + (0x2F849, 'M', u'喳'), + (0x2F84A, 'M', u'嗂'), + (0x2F84B, 'M', u'圖'), + (0x2F84C, 'M', u'嘆'), + (0x2F84D, 'M', u'圗'), + (0x2F84E, 'M', u'噑'), + (0x2F84F, 'M', u'噴'), + (0x2F850, 'M', u'切'), + (0x2F851, 'M', u'壮'), + (0x2F852, 'M', u'城'), + (0x2F853, 'M', u'埴'), + (0x2F854, 'M', u'堍'), + (0x2F855, 'M', u'型'), + (0x2F856, 'M', u'堲'), + (0x2F857, 'M', u'報'), + (0x2F858, 'M', u'墬'), + (0x2F859, 'M', u'𡓤'), + (0x2F85A, 'M', u'売'), + (0x2F85B, 'M', u'壷'), + ] + +def _seg_75(): + return [ + (0x2F85C, 'M', u'夆'), + (0x2F85D, 'M', u'多'), + (0x2F85E, 'M', u'夢'), + (0x2F85F, 'M', u'奢'), + (0x2F860, 'M', u'𡚨'), + (0x2F861, 'M', u'𡛪'), + (0x2F862, 'M', u'姬'), + (0x2F863, 'M', u'娛'), + (0x2F864, 'M', u'娧'), + (0x2F865, 'M', u'姘'), + (0x2F866, 'M', u'婦'), + (0x2F867, 'M', u'㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', u'嬈'), + (0x2F86A, 'M', u'嬾'), + (0x2F86C, 'M', u'𡧈'), + (0x2F86D, 'M', u'寃'), + (0x2F86E, 'M', u'寘'), + (0x2F86F, 'M', u'寧'), + (0x2F870, 'M', u'寳'), + (0x2F871, 'M', u'𡬘'), + (0x2F872, 'M', u'寿'), + (0x2F873, 'M', u'将'), + (0x2F874, 'X'), + (0x2F875, 'M', u'尢'), + (0x2F876, 'M', u'㞁'), + (0x2F877, 'M', u'屠'), + (0x2F878, 'M', u'屮'), + (0x2F879, 'M', u'峀'), + (0x2F87A, 'M', u'岍'), + (0x2F87B, 'M', u'𡷤'), + (0x2F87C, 'M', u'嵃'), + (0x2F87D, 'M', u'𡷦'), + (0x2F87E, 'M', u'嵮'), + (0x2F87F, 'M', u'嵫'), + (0x2F880, 'M', u'嵼'), + (0x2F881, 'M', u'巡'), + (0x2F882, 'M', u'巢'), + (0x2F883, 'M', u'㠯'), + (0x2F884, 'M', u'巽'), + (0x2F885, 'M', u'帨'), + (0x2F886, 'M', u'帽'), + (0x2F887, 'M', u'幩'), + (0x2F888, 'M', u'㡢'), + (0x2F889, 'M', u'𢆃'), + (0x2F88A, 'M', u'㡼'), + (0x2F88B, 'M', u'庰'), + (0x2F88C, 'M', u'庳'), + (0x2F88D, 'M', u'庶'), + (0x2F88E, 'M', u'廊'), + (0x2F88F, 'M', u'𪎒'), + (0x2F890, 'M', u'廾'), + (0x2F891, 'M', u'𢌱'), + (0x2F893, 'M', u'舁'), + (0x2F894, 'M', u'弢'), + (0x2F896, 'M', u'㣇'), + (0x2F897, 'M', u'𣊸'), + (0x2F898, 'M', u'𦇚'), + (0x2F899, 'M', u'形'), + (0x2F89A, 'M', u'彫'), + (0x2F89B, 'M', u'㣣'), + (0x2F89C, 'M', u'徚'), + (0x2F89D, 'M', u'忍'), + (0x2F89E, 'M', u'志'), + (0x2F89F, 'M', u'忹'), + (0x2F8A0, 'M', u'悁'), + (0x2F8A1, 'M', u'㤺'), + (0x2F8A2, 'M', u'㤜'), + (0x2F8A3, 'M', u'悔'), + (0x2F8A4, 'M', u'𢛔'), + (0x2F8A5, 'M', u'惇'), + (0x2F8A6, 'M', u'慈'), + (0x2F8A7, 'M', u'慌'), + (0x2F8A8, 'M', u'慎'), + (0x2F8A9, 'M', u'慌'), + (0x2F8AA, 'M', u'慺'), + (0x2F8AB, 'M', u'憎'), + (0x2F8AC, 'M', u'憲'), + (0x2F8AD, 'M', u'憤'), + (0x2F8AE, 'M', u'憯'), + (0x2F8AF, 'M', u'懞'), + (0x2F8B0, 'M', u'懲'), + (0x2F8B1, 'M', u'懶'), + (0x2F8B2, 'M', u'成'), + (0x2F8B3, 'M', u'戛'), + (0x2F8B4, 'M', u'扝'), + (0x2F8B5, 'M', u'抱'), + (0x2F8B6, 'M', u'拔'), + (0x2F8B7, 'M', u'捐'), + (0x2F8B8, 'M', u'𢬌'), + (0x2F8B9, 'M', u'挽'), + (0x2F8BA, 'M', u'拼'), + (0x2F8BB, 'M', u'捨'), + (0x2F8BC, 'M', u'掃'), + (0x2F8BD, 'M', u'揤'), + (0x2F8BE, 'M', u'𢯱'), + (0x2F8BF, 'M', u'搢'), + (0x2F8C0, 'M', u'揅'), + (0x2F8C1, 'M', u'掩'), + (0x2F8C2, 'M', u'㨮'), + ] + +def _seg_76(): + return [ + (0x2F8C3, 'M', u'摩'), + (0x2F8C4, 'M', u'摾'), + (0x2F8C5, 'M', u'撝'), + (0x2F8C6, 'M', u'摷'), + (0x2F8C7, 'M', u'㩬'), + (0x2F8C8, 'M', u'敏'), + (0x2F8C9, 'M', u'敬'), + (0x2F8CA, 'M', u'𣀊'), + (0x2F8CB, 'M', u'旣'), + (0x2F8CC, 'M', u'書'), + (0x2F8CD, 'M', u'晉'), + (0x2F8CE, 'M', u'㬙'), + (0x2F8CF, 'M', u'暑'), + (0x2F8D0, 'M', u'㬈'), + (0x2F8D1, 'M', u'㫤'), + (0x2F8D2, 'M', u'冒'), + (0x2F8D3, 'M', u'冕'), + (0x2F8D4, 'M', u'最'), + (0x2F8D5, 'M', u'暜'), + (0x2F8D6, 'M', u'肭'), + (0x2F8D7, 'M', u'䏙'), + (0x2F8D8, 'M', u'朗'), + (0x2F8D9, 'M', u'望'), + (0x2F8DA, 'M', u'朡'), + (0x2F8DB, 'M', u'杞'), + (0x2F8DC, 'M', u'杓'), + (0x2F8DD, 'M', u'𣏃'), + (0x2F8DE, 'M', u'㭉'), + (0x2F8DF, 'M', u'柺'), + (0x2F8E0, 'M', u'枅'), + (0x2F8E1, 'M', u'桒'), + (0x2F8E2, 'M', u'梅'), + (0x2F8E3, 'M', u'𣑭'), + (0x2F8E4, 'M', u'梎'), + (0x2F8E5, 'M', u'栟'), + (0x2F8E6, 'M', u'椔'), + (0x2F8E7, 'M', u'㮝'), + (0x2F8E8, 'M', u'楂'), + (0x2F8E9, 'M', u'榣'), + (0x2F8EA, 'M', u'槪'), + (0x2F8EB, 'M', u'檨'), + (0x2F8EC, 'M', u'𣚣'), + (0x2F8ED, 'M', u'櫛'), + (0x2F8EE, 'M', u'㰘'), + (0x2F8EF, 'M', u'次'), + (0x2F8F0, 'M', u'𣢧'), + (0x2F8F1, 'M', u'歔'), + (0x2F8F2, 'M', u'㱎'), + (0x2F8F3, 'M', u'歲'), + (0x2F8F4, 'M', u'殟'), + (0x2F8F5, 'M', u'殺'), + (0x2F8F6, 'M', u'殻'), + (0x2F8F7, 'M', u'𣪍'), + (0x2F8F8, 'M', u'𡴋'), + (0x2F8F9, 'M', u'𣫺'), + (0x2F8FA, 'M', u'汎'), + (0x2F8FB, 'M', u'𣲼'), + (0x2F8FC, 'M', u'沿'), + (0x2F8FD, 'M', u'泍'), + (0x2F8FE, 'M', u'汧'), + (0x2F8FF, 'M', u'洖'), + (0x2F900, 'M', u'派'), + (0x2F901, 'M', u'海'), + (0x2F902, 'M', u'流'), + (0x2F903, 'M', u'浩'), + (0x2F904, 'M', u'浸'), + (0x2F905, 'M', u'涅'), + (0x2F906, 'M', u'𣴞'), + (0x2F907, 'M', u'洴'), + (0x2F908, 'M', u'港'), + (0x2F909, 'M', u'湮'), + (0x2F90A, 'M', u'㴳'), + (0x2F90B, 'M', u'滋'), + (0x2F90C, 'M', u'滇'), + (0x2F90D, 'M', u'𣻑'), + (0x2F90E, 'M', u'淹'), + (0x2F90F, 'M', u'潮'), + (0x2F910, 'M', u'𣽞'), + (0x2F911, 'M', u'𣾎'), + (0x2F912, 'M', u'濆'), + (0x2F913, 'M', u'瀹'), + (0x2F914, 'M', u'瀞'), + (0x2F915, 'M', u'瀛'), + (0x2F916, 'M', u'㶖'), + (0x2F917, 'M', u'灊'), + (0x2F918, 'M', u'災'), + (0x2F919, 'M', u'灷'), + (0x2F91A, 'M', u'炭'), + (0x2F91B, 'M', u'𠔥'), + (0x2F91C, 'M', u'煅'), + (0x2F91D, 'M', u'𤉣'), + (0x2F91E, 'M', u'熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', u'爨'), + (0x2F921, 'M', u'爵'), + (0x2F922, 'M', u'牐'), + (0x2F923, 'M', u'𤘈'), + (0x2F924, 'M', u'犀'), + (0x2F925, 'M', u'犕'), + (0x2F926, 'M', u'𤜵'), + ] + +def _seg_77(): + return [ + (0x2F927, 'M', u'𤠔'), + (0x2F928, 'M', u'獺'), + (0x2F929, 'M', u'王'), + (0x2F92A, 'M', u'㺬'), + (0x2F92B, 'M', u'玥'), + (0x2F92C, 'M', u'㺸'), + (0x2F92E, 'M', u'瑇'), + (0x2F92F, 'M', u'瑜'), + (0x2F930, 'M', u'瑱'), + (0x2F931, 'M', u'璅'), + (0x2F932, 'M', u'瓊'), + (0x2F933, 'M', u'㼛'), + (0x2F934, 'M', u'甤'), + (0x2F935, 'M', u'𤰶'), + (0x2F936, 'M', u'甾'), + (0x2F937, 'M', u'𤲒'), + (0x2F938, 'M', u'異'), + (0x2F939, 'M', u'𢆟'), + (0x2F93A, 'M', u'瘐'), + (0x2F93B, 'M', u'𤾡'), + (0x2F93C, 'M', u'𤾸'), + (0x2F93D, 'M', u'𥁄'), + (0x2F93E, 'M', u'㿼'), + (0x2F93F, 'M', u'䀈'), + (0x2F940, 'M', u'直'), + (0x2F941, 'M', u'𥃳'), + (0x2F942, 'M', u'𥃲'), + (0x2F943, 'M', u'𥄙'), + (0x2F944, 'M', u'𥄳'), + (0x2F945, 'M', u'眞'), + (0x2F946, 'M', u'真'), + (0x2F948, 'M', u'睊'), + (0x2F949, 'M', u'䀹'), + (0x2F94A, 'M', u'瞋'), + (0x2F94B, 'M', u'䁆'), + (0x2F94C, 'M', u'䂖'), + (0x2F94D, 'M', u'𥐝'), + (0x2F94E, 'M', u'硎'), + (0x2F94F, 'M', u'碌'), + (0x2F950, 'M', u'磌'), + (0x2F951, 'M', u'䃣'), + (0x2F952, 'M', u'𥘦'), + (0x2F953, 'M', u'祖'), + (0x2F954, 'M', u'𥚚'), + (0x2F955, 'M', u'𥛅'), + (0x2F956, 'M', u'福'), + (0x2F957, 'M', u'秫'), + (0x2F958, 'M', u'䄯'), + (0x2F959, 'M', u'穀'), + (0x2F95A, 'M', u'穊'), + (0x2F95B, 'M', u'穏'), + (0x2F95C, 'M', u'𥥼'), + (0x2F95D, 'M', u'𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', u'䈂'), + (0x2F961, 'M', u'𥮫'), + (0x2F962, 'M', u'篆'), + (0x2F963, 'M', u'築'), + (0x2F964, 'M', u'䈧'), + (0x2F965, 'M', u'𥲀'), + (0x2F966, 'M', u'糒'), + (0x2F967, 'M', u'䊠'), + (0x2F968, 'M', u'糨'), + (0x2F969, 'M', u'糣'), + (0x2F96A, 'M', u'紀'), + (0x2F96B, 'M', u'𥾆'), + (0x2F96C, 'M', u'絣'), + (0x2F96D, 'M', u'䌁'), + (0x2F96E, 'M', u'緇'), + (0x2F96F, 'M', u'縂'), + (0x2F970, 'M', u'繅'), + (0x2F971, 'M', u'䌴'), + (0x2F972, 'M', u'𦈨'), + (0x2F973, 'M', u'𦉇'), + (0x2F974, 'M', u'䍙'), + (0x2F975, 'M', u'𦋙'), + (0x2F976, 'M', u'罺'), + (0x2F977, 'M', u'𦌾'), + (0x2F978, 'M', u'羕'), + (0x2F979, 'M', u'翺'), + (0x2F97A, 'M', u'者'), + (0x2F97B, 'M', u'𦓚'), + (0x2F97C, 'M', u'𦔣'), + (0x2F97D, 'M', u'聠'), + (0x2F97E, 'M', u'𦖨'), + (0x2F97F, 'M', u'聰'), + (0x2F980, 'M', u'𣍟'), + (0x2F981, 'M', u'䏕'), + (0x2F982, 'M', u'育'), + (0x2F983, 'M', u'脃'), + (0x2F984, 'M', u'䐋'), + (0x2F985, 'M', u'脾'), + (0x2F986, 'M', u'媵'), + (0x2F987, 'M', u'𦞧'), + (0x2F988, 'M', u'𦞵'), + (0x2F989, 'M', u'𣎓'), + (0x2F98A, 'M', u'𣎜'), + (0x2F98B, 'M', u'舁'), + (0x2F98C, 'M', u'舄'), + (0x2F98D, 'M', u'辞'), + ] + +def _seg_78(): + return [ + (0x2F98E, 'M', u'䑫'), + (0x2F98F, 'M', u'芑'), + (0x2F990, 'M', u'芋'), + (0x2F991, 'M', u'芝'), + (0x2F992, 'M', u'劳'), + (0x2F993, 'M', u'花'), + (0x2F994, 'M', u'芳'), + (0x2F995, 'M', u'芽'), + (0x2F996, 'M', u'苦'), + (0x2F997, 'M', u'𦬼'), + (0x2F998, 'M', u'若'), + (0x2F999, 'M', u'茝'), + (0x2F99A, 'M', u'荣'), + (0x2F99B, 'M', u'莭'), + (0x2F99C, 'M', u'茣'), + (0x2F99D, 'M', u'莽'), + (0x2F99E, 'M', u'菧'), + (0x2F99F, 'M', u'著'), + (0x2F9A0, 'M', u'荓'), + (0x2F9A1, 'M', u'菊'), + (0x2F9A2, 'M', u'菌'), + (0x2F9A3, 'M', u'菜'), + (0x2F9A4, 'M', u'𦰶'), + (0x2F9A5, 'M', u'𦵫'), + (0x2F9A6, 'M', u'𦳕'), + (0x2F9A7, 'M', u'䔫'), + (0x2F9A8, 'M', u'蓱'), + (0x2F9A9, 'M', u'蓳'), + (0x2F9AA, 'M', u'蔖'), + (0x2F9AB, 'M', u'𧏊'), + (0x2F9AC, 'M', u'蕤'), + (0x2F9AD, 'M', u'𦼬'), + (0x2F9AE, 'M', u'䕝'), + (0x2F9AF, 'M', u'䕡'), + (0x2F9B0, 'M', u'𦾱'), + (0x2F9B1, 'M', u'𧃒'), + (0x2F9B2, 'M', u'䕫'), + (0x2F9B3, 'M', u'虐'), + (0x2F9B4, 'M', u'虜'), + (0x2F9B5, 'M', u'虧'), + (0x2F9B6, 'M', u'虩'), + (0x2F9B7, 'M', u'蚩'), + (0x2F9B8, 'M', u'蚈'), + (0x2F9B9, 'M', u'蜎'), + (0x2F9BA, 'M', u'蛢'), + (0x2F9BB, 'M', u'蝹'), + (0x2F9BC, 'M', u'蜨'), + (0x2F9BD, 'M', u'蝫'), + (0x2F9BE, 'M', u'螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', u'蟡'), + (0x2F9C1, 'M', u'蠁'), + (0x2F9C2, 'M', u'䗹'), + (0x2F9C3, 'M', u'衠'), + (0x2F9C4, 'M', u'衣'), + (0x2F9C5, 'M', u'𧙧'), + (0x2F9C6, 'M', u'裗'), + (0x2F9C7, 'M', u'裞'), + (0x2F9C8, 'M', u'䘵'), + (0x2F9C9, 'M', u'裺'), + (0x2F9CA, 'M', u'㒻'), + (0x2F9CB, 'M', u'𧢮'), + (0x2F9CC, 'M', u'𧥦'), + (0x2F9CD, 'M', u'䚾'), + (0x2F9CE, 'M', u'䛇'), + (0x2F9CF, 'M', u'誠'), + (0x2F9D0, 'M', u'諭'), + (0x2F9D1, 'M', u'變'), + (0x2F9D2, 'M', u'豕'), + (0x2F9D3, 'M', u'𧲨'), + (0x2F9D4, 'M', u'貫'), + (0x2F9D5, 'M', u'賁'), + (0x2F9D6, 'M', u'贛'), + (0x2F9D7, 'M', u'起'), + (0x2F9D8, 'M', u'𧼯'), + (0x2F9D9, 'M', u'𠠄'), + (0x2F9DA, 'M', u'跋'), + (0x2F9DB, 'M', u'趼'), + (0x2F9DC, 'M', u'跰'), + (0x2F9DD, 'M', u'𠣞'), + (0x2F9DE, 'M', u'軔'), + (0x2F9DF, 'M', u'輸'), + (0x2F9E0, 'M', u'𨗒'), + (0x2F9E1, 'M', u'𨗭'), + (0x2F9E2, 'M', u'邔'), + (0x2F9E3, 'M', u'郱'), + (0x2F9E4, 'M', u'鄑'), + (0x2F9E5, 'M', u'𨜮'), + (0x2F9E6, 'M', u'鄛'), + (0x2F9E7, 'M', u'鈸'), + (0x2F9E8, 'M', u'鋗'), + (0x2F9E9, 'M', u'鋘'), + (0x2F9EA, 'M', u'鉼'), + (0x2F9EB, 'M', u'鏹'), + (0x2F9EC, 'M', u'鐕'), + (0x2F9ED, 'M', u'𨯺'), + (0x2F9EE, 'M', u'開'), + (0x2F9EF, 'M', u'䦕'), + (0x2F9F0, 'M', u'閷'), + (0x2F9F1, 'M', u'𨵷'), + ] + +def _seg_79(): + return [ + (0x2F9F2, 'M', u'䧦'), + (0x2F9F3, 'M', u'雃'), + (0x2F9F4, 'M', u'嶲'), + (0x2F9F5, 'M', u'霣'), + (0x2F9F6, 'M', u'𩅅'), + (0x2F9F7, 'M', u'𩈚'), + (0x2F9F8, 'M', u'䩮'), + (0x2F9F9, 'M', u'䩶'), + (0x2F9FA, 'M', u'韠'), + (0x2F9FB, 'M', u'𩐊'), + (0x2F9FC, 'M', u'䪲'), + (0x2F9FD, 'M', u'𩒖'), + (0x2F9FE, 'M', u'頋'), + (0x2FA00, 'M', u'頩'), + (0x2FA01, 'M', u'𩖶'), + (0x2FA02, 'M', u'飢'), + (0x2FA03, 'M', u'䬳'), + (0x2FA04, 'M', u'餩'), + (0x2FA05, 'M', u'馧'), + (0x2FA06, 'M', u'駂'), + (0x2FA07, 'M', u'駾'), + (0x2FA08, 'M', u'䯎'), + (0x2FA09, 'M', u'𩬰'), + (0x2FA0A, 'M', u'鬒'), + (0x2FA0B, 'M', u'鱀'), + (0x2FA0C, 'M', u'鳽'), + (0x2FA0D, 'M', u'䳎'), + (0x2FA0E, 'M', u'䳭'), + (0x2FA0F, 'M', u'鵧'), + (0x2FA10, 'M', u'𪃎'), + (0x2FA11, 'M', u'䳸'), + (0x2FA12, 'M', u'𪄅'), + (0x2FA13, 'M', u'𪈎'), + (0x2FA14, 'M', u'𪊑'), + (0x2FA15, 'M', u'麻'), + (0x2FA16, 'M', u'䵖'), + (0x2FA17, 'M', u'黹'), + (0x2FA18, 'M', u'黾'), + (0x2FA19, 'M', u'鼅'), + (0x2FA1A, 'M', u'鼏'), + (0x2FA1B, 'M', u'鼖'), + (0x2FA1C, 'M', u'鼻'), + (0x2FA1D, 'M', u'𪘀'), + (0x2FA1E, 'X'), + (0x30000, 'V'), + (0x3134B, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() + + _seg_78() + + _seg_79() +) diff --git a/lib/requests-2.25.1.dist-info/INSTALLER b/lib/requests-2.25.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/requests-2.25.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/requests-2.25.1.dist-info/LICENSE b/lib/requests-2.25.1.dist-info/LICENSE new file mode 100644 index 0000000..67db858 --- /dev/null +++ b/lib/requests-2.25.1.dist-info/LICENSE @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/lib/requests-2.25.1.dist-info/METADATA b/lib/requests-2.25.1.dist-info/METADATA new file mode 100644 index 0000000..6aaa2dd --- /dev/null +++ b/lib/requests-2.25.1.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: requests +Version: 2.25.1 +Summary: Python HTTP for Humans. +Home-page: https://requests.readthedocs.io +Author: Kenneth Reitz +Author-email: me@kennethreitz.org +License: Apache 2.0 +Project-URL: Documentation, https://requests.readthedocs.io +Project-URL: Source, https://github.com/psf/requests +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* +Description-Content-Type: text/markdown +Requires-Dist: chardet (<5,>=3.0.2) +Requires-Dist: idna (<3,>=2.5) +Requires-Dist: urllib3 (<1.27,>=1.21.1) +Requires-Dist: certifi (>=2017.4.17) +Provides-Extra: security +Requires-Dist: pyOpenSSL (>=0.14) ; extra == 'security' +Requires-Dist: cryptography (>=1.3.4) ; extra == 'security' +Provides-Extra: socks +Requires-Dist: PySocks (!=1.5.7,>=1.5.6) ; extra == 'socks' +Requires-Dist: win-inet-pton ; (sys_platform == "win32" and python_version == "2.7") and extra == 'socks' + +# Requests + +**Requests** is a simple, yet elegant HTTP library. + +```python +>>> import requests +>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass')) +>>> r.status_code +200 +>>> r.headers['content-type'] +'application/json; charset=utf8' +>>> r.encoding +'utf-8' +>>> r.text +'{"type":"User"...' +>>> r.json() +{'disk_usage': 368627, 'private_gists': 484, ...} +``` + +Requests allows you to send HTTP/1.1 requests extremely easily. There’s no need to manually add query strings to your URLs, or to form-encode your `PUT` & `POST` data — but nowadays, just use the `json` method! + +Requests is one of the most downloaded Python package today, pulling in around `14M downloads / week`— according to GitHub, Requests is currently [depended upon](https://github.com/psf/requests/network/dependents?package_id=UGFja2FnZS01NzA4OTExNg%3D%3D) by `500,000+` repositories. You may certainly put your trust in this code. + +[![Downloads](https://pepy.tech/badge/requests/month)](https://pepy.tech/project/requests/month) +[![Supported Versions](https://img.shields.io/pypi/pyversions/requests.svg)](https://pypi.org/project/requests) +[![Contributors](https://img.shields.io/github/contributors/psf/requests.svg)](https://github.com/psf/requests/graphs/contributors) + +## Installing Requests and Supported Versions + +Requests is available on PyPI: + +```console +$ python -m pip install requests +``` + +Requests officially supports Python 2.7 & 3.5+. + +## Supported Features & Best–Practices + +Requests is ready for the demands of building robust and reliable HTTP–speaking applications, for the needs of today. + +- Keep-Alive & Connection Pooling +- International Domains and URLs +- Sessions with Cookie Persistence +- Browser-style TLS/SSL Verification +- Basic & Digest Authentication +- Familiar `dict`–like Cookies +- Automatic Content Decompression and Decoding +- Multi-part File Uploads +- SOCKS Proxy Support +- Connection Timeouts +- Streaming Downloads +- Automatic honoring of `.netrc` +- Chunked HTTP Requests + +## API Reference and User Guide available on [Read the Docs](https://requests.readthedocs.io) + +[![Read the Docs](https://raw.githubusercontent.com/psf/requests/master/ext/ss.png)](https://requests.readthedocs.io) + +--- + +[![Kenneth Reitz](https://raw.githubusercontent.com/psf/requests/master/ext/kr.png)](https://kennethreitz.org) [![Python Software Foundation](https://raw.githubusercontent.com/psf/requests/master/ext/psf.png)](https://www.python.org/psf) + + diff --git a/lib/requests-2.25.1.dist-info/RECORD b/lib/requests-2.25.1.dist-info/RECORD new file mode 100644 index 0000000..8f1b3d7 --- /dev/null +++ b/lib/requests-2.25.1.dist-info/RECORD @@ -0,0 +1,43 @@ +requests-2.25.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +requests-2.25.1.dist-info/LICENSE,sha256=CeipvOyAZxBGUsFoaFqwkx54aPnIKEtm9a5u2uXxEws,10142 +requests-2.25.1.dist-info/METADATA,sha256=RuNh38uN0IMsRT3OwaTNB_WyGx6RMwwQoMwujXfkUVM,4168 +requests-2.25.1.dist-info/RECORD,, +requests-2.25.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +requests-2.25.1.dist-info/WHEEL,sha256=Z-nyYpwrcSqxfdux5Mbn_DQ525iP7J2DG3JgGvOYyTQ,110 +requests-2.25.1.dist-info/top_level.txt,sha256=fMSVmHfb5rbGOo6xv-O_tUX6j-WyixssE-SnwcDRxNQ,9 +requests/__init__.py,sha256=rsmg7xmbbCE_zmDcG6EDk_pyvdEfadztdBaWIkInlH8,4141 +requests/__pycache__/__init__.cpython-312.pyc,, +requests/__pycache__/__version__.cpython-312.pyc,, +requests/__pycache__/_internal_utils.cpython-312.pyc,, +requests/__pycache__/adapters.cpython-312.pyc,, +requests/__pycache__/api.cpython-312.pyc,, +requests/__pycache__/auth.cpython-312.pyc,, +requests/__pycache__/certs.cpython-312.pyc,, +requests/__pycache__/compat.cpython-312.pyc,, +requests/__pycache__/cookies.cpython-312.pyc,, +requests/__pycache__/exceptions.cpython-312.pyc,, +requests/__pycache__/help.cpython-312.pyc,, +requests/__pycache__/hooks.cpython-312.pyc,, +requests/__pycache__/models.cpython-312.pyc,, +requests/__pycache__/packages.cpython-312.pyc,, +requests/__pycache__/sessions.cpython-312.pyc,, +requests/__pycache__/status_codes.cpython-312.pyc,, +requests/__pycache__/structures.cpython-312.pyc,, +requests/__pycache__/utils.cpython-312.pyc,, +requests/__version__.py,sha256=k4J8c1yFRFzwGWwlN7miaDOclFtbcIs1GlnmT17YbXQ,441 +requests/_internal_utils.py,sha256=Zx3PnEUccyfsB-ie11nZVAW8qClJy0gx1qNME7rgT18,1096 +requests/adapters.py,sha256=WelSM1BCQXdbjEuDsBxqKDADeY8BHmxlrwbNnLN2rr4,21344 +requests/api.py,sha256=PlHM-HT3PQ5lyufoeGmV-nJxRi7UnUyGVh7OV7B9XV4,6496 +requests/auth.py,sha256=OMoJIVKyRLy9THr91y8rxysZuclwPB-K1Xg1zBomUhQ,10207 +requests/certs.py,sha256=dOB5rV2DZ13dEhq9BUa_4hd5kAqg59e_zUZB00faYz8,453 +requests/compat.py,sha256=iBRvu-X540CH4PJsuxr0vcGTnl_TZhq_75SwmeckQ7w,1782 +requests/cookies.py,sha256=Y-bKX6TvW3FnYlE6Au0SXtVVWcaNdFvuAwQxw-G0iTI,18430 +requests/exceptions.py,sha256=xXoj1rdhnxTS_DYphKZ9OvFZJQZ333A64REc9ZDZIgU,3161 +requests/help.py,sha256=lLcBtKAar8T6T78e9Tc4Zfd_EEJFhntxgib1JHNctEI,3515 +requests/hooks.py,sha256=QReGyy0bRcr5rkwCuObNakbYsc7EkiKeBwG4qHekr2Q,757 +requests/models.py,sha256=Uhb4Ra_ubNGBf-6ktHShgO5mUSCGZKa5D_wLGVCMtYk,34308 +requests/packages.py,sha256=Q2rF0L5mc3wQAvc6q_lAVtPTDOaOeFgD-7kWSQLkjEQ,542 +requests/sessions.py,sha256=BsnR-zYILgoFzJ6yq4T8ht_i0PwwPGVAxWxWaV5dcHg,30137 +requests/status_codes.py,sha256=gT79Pbs_cQjBgp-fvrUgg1dn2DQO32bDj4TInjnMPSc,4188 +requests/structures.py,sha256=msAtr9mq1JxHd-JRyiILfdFlpbJwvvFuP3rfUQT_QxE,3005 +requests/utils.py,sha256=_K9AgkN6efPe-a-zgZurXzds5PBC0CzDkyjAE2oCQFQ,30529 diff --git a/lib/requests-2.25.1.dist-info/REQUESTED b/lib/requests-2.25.1.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/lib/requests-2.25.1.dist-info/WHEEL b/lib/requests-2.25.1.dist-info/WHEEL new file mode 100644 index 0000000..01b8fc7 --- /dev/null +++ b/lib/requests-2.25.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/lib/requests-2.25.1.dist-info/top_level.txt b/lib/requests-2.25.1.dist-info/top_level.txt new file mode 100644 index 0000000..f229360 --- /dev/null +++ b/lib/requests-2.25.1.dist-info/top_level.txt @@ -0,0 +1 @@ +requests diff --git a/lib/requests/__init__.py b/lib/requests/__init__.py new file mode 100644 index 0000000..f8f9429 --- /dev/null +++ b/lib/requests/__init__.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +Requests is an HTTP library, written in Python, for human beings. +Basic GET usage: + + >>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> b'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('https://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key1": "value1", + "key2": "value2" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at . + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +import urllib3 +import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.26 + assert major == 1 + assert minor >= 21 + assert minor <= 26 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 5.0.0 + assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0) + + +def _check_cryptography(cryptography_version): + # cryptography < 1.3.4 + try: + cryptography_version = list(map(int, cryptography_version.split('.'))) + except ValueError: + return + + if cryptography_version < [1, 3, 4]: + warning = 'Old version of cryptography ({}) may cause slowdown.'.format(cryptography_version) + warnings.warn(warning, RequestsDependencyWarning) + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({}) or chardet ({}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet.__version__), + RequestsDependencyWarning) + +# Attempt to enable urllib3's fallback for SNI support +# if the standard library doesn't support SNI or the +# 'ssl' library isn't available. +try: + try: + import ssl + except ImportError: + ssl = None + + if not getattr(ssl, "HAS_SNI", False): + from urllib3.contrib import pyopenssl + pyopenssl.inject_into_urllib3() + + # Check cryptography version + from cryptography import __version__ as cryptography_version + _check_cryptography(cryptography_version) +except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +from logging import NullHandler + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/lib/requests/__pycache__/__init__.cpython-312.pyc b/lib/requests/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02148c872a8818407b3a7aaccd11e292a68464a0 GIT binary patch literal 4726 zcmb^#TTB~Q_KwH)jBVZzLr4e{2muFd9(iI22}vMH3rR$1tB#P|iRWSlW<2hlafw@4 zu~ntg?n=vF*~dqA+mEi&k4U>8mG)y*X*XJFf9$}n=`>L)RjU<$G-=f;{n>NJV`DW{ zwOZ{U&b{}X`#A4&;O~`{egvP_{q|hA2B9zLqWE#n6gv z6oWR6U5J$5QJBk>IJn0f$XliITC>=!?GyKDEn*AY%)?ErTn+gB;(qObctC3vTeXAY zK^tEK_%^Xk6GXvY*Q$rKcCp=_*TK9)?6Bwc>S3)@?9`5kN3<@n%f>aR-C9TtX-CDQ zT94SH^@_b(SPW|sF{1T}eOkZRZ|`eV2ed(PP&+0bv)4iOxOPH3Vb7buJ}1SK+9~mr zc3M2G4T(cqRE%oF;;=R%j%a7ZGuo&)3VW%I&x&VZY*x=|=frciR?aTG`K(s(`JxsV z-hP$}RykL+KylxXXm}qUky}36U$iiTGOiAUeb_(eI*iD$b29ksJ2JPh?^*2s;&s@w zXXBUAI`i`jOXwE+GFoDQlPciC3;J=1l{W49@6p^0vhm$TeCUAm6x`WAjbBY;!!(4; zGc(tPN#!PyNXGw@ANu@zn-xQll7%B`;YhErL=@A+NkK^p*E8n4p6nIobRx{BHQ0I+ zE6Icr@t>CrB`#bVpApiAl)zEHUl4@R(NRIsQaUjO;;>Uh6X8q=7fE2VyKCMwQ%1C} zZ)s^MlCs~4=p@kmq>5TJCNx~FSl4duFnD~}yBj2EW3Igz0 zn6!i5wf3ms;02+bvIdCu0(0%Xg?$CWV2Lo;Ucj$7bmzhqzkg;P3%WUvNx|kC2K&mO zLxKe(ouZb*vJe&wjD=TVz8%CKfHcWJc?-_HhnCTTlc;T~17zlogI$3gvMa$Xo`Ry_dJetGm`;g6Kq>B$ z*~M;zNG;q(@BiK>yNml6I5P|9S6nOXirXxfK(y>C?kK~tKY%OUwBm*vT+1%mLtid% zw#>@j#o4kIx7bozF+VP+jAXv$|H_-}TXrq8%kDWg?z-iooDi?A%~R&{({BH&9Ugh!JWbYgiRo6sR8nelmpK0zZ> zcsg?-I{ShFhi4}x0As1tMF{QLNj)y9volyr&8C!8*pvw5xbWPfIhP?zbF=W|Y$31StFKh<; zSFddcS~k)fiTi=hth+NC=={oy_`urPO>Y0jtM@r!n{UeV2Xp+v4P%S%*!80QM|19` z)$z3x>zxl;S~u{okA4vUu=D+eKX%;3e>l3{xprc8{PRG~`q;bCth;e7x()O5?+$0( z!L{M?xqVf>r7zdgcbDC4IevHgu9R&#{oh>Pu+ezib32`F4sQj9?)vTrhO+LVToFD2 zF;Toc4yl2u)t@{7@E){kW{J8Nf2JFV_UEE;>@BYL#=ST$7T#h^(YQ`PWdDw#9!Yv- zb|J8Lt~lF^@D;|aEMga`inG0OnK4UEXz?v*G2o{InN%A4gA&iuGM+)DBJRFQDC6MX zR9@T1cc@&iAHSx`g5#`$J}1OUCS}rcmzvKA-EXXf1Wn2aaVc#;23PeZSzk&t;RG5866DxbP914PVNJ$MWGzx$vdGv76z^&BIfh zZCA7Wfn6T)2Y#j8=eoA*F6Zm6=+@I$*E#CL!D z6^AN?cPVfUlo*;=Z6VXaJnBFRW!98_6yc zR0+W@NM)ta(flEcyF7LycH`=m38*o?R7QuSVi+nc0a zVlh)ORUC_1)v=h2jW|(Kw2}gXi^YJ)Sd4Um0EN9b(~2qs$sdbJX(-eL<~5}`)}a0Y z1{iRvCNSW#Dr1mFoLUQ19+uJ~ya>E`(k4_)nD9_s7okZqLafC(1=HfEv60fD_*&K1 z2~I&vAUmWGZ*flAvRKG#mU|uwyyd374WX^F#ir7x<(09DO>A+xEt3Jva0WK)G|Sy6 zOehz$pEJNkYnzXft7b;mr=(`vFBlJMMl3W0Jp?H`&^%z>stcvnzCGB)yokNS1@z+fW z6$Z5EDxOnR6BBY2P^5=~UJAk#(7#Mc9|ips&>BPr0a%C}qx0i*?$toYszFXr%t;EM zHv)N}StO_Fa)^Q`1;Z3jKOrL&oS|S8fW0nIYx3I)#rusBsuB%s|R&(oC;lsO3quq{MFQqpMb`6XF)EdF~$=wEeqB74e@ zfJ|u>j}jShwA2^`AS4!s`LgB^<9;&1Ag1~=RP`CEeuxGhdmEVON39*deDU_B{NYo%!>2xO$`4KEh9);#r?%^QzVWy`;awJve774! z6-_i>*Kb$V{fwm8q^(r(|U0j{mBi6{&U|%75dBY==d4- huOke=dx)C|u=h9?@b~--od@iBm1m-fy%%Hv{s$Dg$kG4+ literal 0 HcmV?d00001 diff --git a/lib/requests/__pycache__/__version__.cpython-312.pyc b/lib/requests/__pycache__/__version__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..564507d79abb5c4f864878d3b82dd1744c705204 GIT binary patch literal 579 zcmY*W&ui2`6i#-xyV-2BU94D;g1IP`+Uy$evWQsfpfhkSW7wnq0}H+NjEK`H%cHV{GbWQu!kaYmR zjPrZ2e9(yIX+-yQ((+oQ?X^kA>yQm^gLJ(v>3Kb3cn0Zv{leTEEDb?lY^~w<4vuoQ}uqqmH1MsECp*kPgeruIsoDocm0_-O@_yDNR$V zBKtXIsw}q?`gn1rh(>TSF)z(Sj)REWt}`ijk1}2eHjk9;PTYz8pFQ7%7ybPB*v@j<>DA%Ih4C=SNFLKiVgz-X-<4BHtG2G| zD^s&}s(yWKzuKzJ{i;_FZ&ZVN^EznOZe`ZncYkQ3dUzAWkyBaq;Lck^48i^z(a*jO literal 0 HcmV?d00001 diff --git a/lib/requests/__pycache__/_internal_utils.cpython-312.pyc b/lib/requests/__pycache__/_internal_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f1ee3343714d9719272ed93b6451b0743f4428bb GIT binary patch literal 1547 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 XGyS*w9o<#j_o|%TP1f&ixh literal 0 HcmV?d00001 diff --git a/lib/requests/__pycache__/api.cpython-312.pyc b/lib/requests/__pycache__/api.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01a2bf32c611c44fc42139443b52f40bf7fe5b24 GIT binary patch literal 7240 zcmeHMO>7&-72YLRf216@PVB}>>kjIo6m3d$EIUpKN46r#wNpV7BD!c?724JAP+V)d z%g!#%&{dio0<^iby%g4=D0Jw-MlL?|kXzexFBBRe1<_j%MQ*OuB85-=-t3SfCD*WB z8*qWFz}eZ^**9&yP`R|lkoIP z;z~l-oa6`Em83K5^nIXTF`Rx}^*IA*`<;ExAjSr8ZwTi>oKrXtIceNYHH_?Y*ME}| z{6{q&M&X!MbyGj-I#Q`(*$r7GaB3cBZl&t+3iqRsMP<(3QctnTg-c_pRKX6a4dJeq zqXHYTv+U%FS5C5(2Kz4eeIAuD-Hon~r3#*Fb3fz-Hd(doGC!GPA?IxN($vh{;tVSV z0?P@`93EM&7mlSq)3N2O-Wm*f7`lNU+HGTyO$P8wdzKpeNS#k> z?dzpd%`Yb4%D zzOB{utYQ6oNYkdEWF%@f>}2^4w&y$Ov4ZVcVOTJg-Pl>xnJ{5JhNDomgjHb`SSxS} z>MSin=Jt7gw+NF3D_6M=r?cBVLELYXdIYQih9%Wus-j21l)%B_SzLQsw1G|S7fY1fur(a15+4I>tm zSX2X~LQ-I*5upU@)rduXa?~WzSy49V@aPa`jxiwlqV@_4ugg zuJMirv4z`;wG~bj#T-PkjFPs)NstxGwH(KdBc3TGJ8L7jakmq{WYC_RVb!8?Z>(S- zP7#DwSf7IB4J&l*{It7@ij|*|=7@nkiP=5!BDcbW8kM7+By=&Tvx?;-nQ$nLybQs0 z%Z)l(Auz9T(TNVqBb^PbaFi#`V4@gAIcAZGO8`?O(+85g;H82&0@*$iGgB($m_XEZ zTn6V^jMm5I zbCj>^W!Ekvrb958NMc?DUWj4TSxl~T7E9{5hcW^!8ABlxvf}I_v$=@el51NLSFVoB z(S4Sv0F-h5s9I6ES1dw+O--_un(qM1*k&!{543O039uHoDm{C3DKlQMyb!*~Nqq$m ztDqh`ab0&kj}&n$6?hYxdky9Ub)S+SSLsh7iMF>}{GzP4IYzsX0TFu4_FN=0X^l8Z zjEq%zB|FA0l~|FAd5(=_NLU7`Z;dxHSv>9vgdaUaPq{7A5O^OY@*d4lebn9#A)u9mQ9KzxMgc#G3KtV z0kv$_5Pi5I`sr@}THO+>VQZkxaEX=@2=C2L6_zdohT+nzg=Vr^okl)dnhk8rTPpHO zb*buBMB2eTgoJqJ70Wb-9-!f7<`YybSduB8rq zI&^qz=GsjB{pUYEgy!=k-Tz$9x+~jz z;UEP4>fov5@A_UJnCs!^v`fj)X{{UDdg5w_p<_TD^eVH%uOl*E*)Ds76YQd<`sEn@NljD=4C|)eC1e_qDh&P*v38+GI8mWhWu1*!VMkCj34~O$Wx5Jx-q_$ z&Tf7SP1DH6VCm$3JWZ)Y){bwW)BSD7(Wx%1qb4{Be5XmO08Uze=z;@r+b0~q&+JD9 z`pUpaJ4w?}8Xx&P#p5CUsZ<>UK##zs4BAl3puOGF8#|9kuWDgNa1gc0=&nZ4iP9*?-7u-;2n zzDc9hY~U9Xmq8>Spjz?T#^P4`_$Gq*c+)s8jh)r!vWdC5Y`QhDyzB(_@^VX)ulMm= zwS2jeR9R9WS%ze$kZzSL(LbxCDET^cZ}4pVkF^OwGzn3zg#|QslDe+{qkm90{`G>U tf8}ofs6MH0oBFW++T9~5ee~{2!}_u9Bg6W6o!V2>yt;j4NRRpUe*j~2Qy~BV literal 0 HcmV?d00001 diff --git a/lib/requests/__pycache__/auth.cpython-312.pyc b/lib/requests/__pycache__/auth.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..653fbd6c75f060560873e7cc43d165e596afc560 GIT binary patch literal 13826 zcmdrzTW}lKb-Q>I?-$>swBkb|C_Y4*k|ouYO^dP~ktju?VwsVOK-i@S2n6W6OG!ik zM`=AZsJInbPlnVu8PkntEZLrkoR8YhPn=|?Nv0nm1SX)@O3Nh9blfjRRHhkybb8KR zEI@#uA4#V(>6LKy?zzuB=iYP9J@@cmZ8kFl$)I~-^xwBJ%y02UP5NAB^*4~2V|ZqS z;aOf2VMkc{)Qo88Q#+!iPu+-)KJ_Dd`ZSCf;Hixm$4w(9mf>~0K2kAm9x;zwMl9pj z5i7+RBDQh+h@Iw*5y!Z5#7Xm}h-=(E;)Z<1h=(_iczMh7%t)n%ImqzV=NaB6RK2NH zW;jw!v39^Zgz7xDhGLz7bqO_jY%RsQ0qa>)w{A+~^TyAaiSX>CAWC9aU{V@0KeslS z&BJ3MksFWklM#Un#-dUn6cssXOyIDx5S2o~fE0>Fxv@Z$j|fEMMq`9KsrG387-u`= zW95qTyZVG^FvbfXvw-qxWz!^yOazE1$XZb%viW>KgjtYK^a50`60S%j5S0AESnOg* z5dBij9}W;GaY8N%V_p*c`PwepkDm`ggE1k%3nacJFfkFyO|JV&=jF?nJ7H$yoiL~} z4Lz2Q1e0J# zHR|Z45pJC7PjU2DG5f+wSfU}8%Koz z;YKH6?gFiTDHh_n2@*RW5yr(X*l#A-;KGF%nJW4S9O`n6@P7#(AsZqfFQPqhgTk3r z+;Mw-HrX5!L7GW{Xiy+Vz{#e|0TKlPB+5F>$p(}Q0ZDcb3KK+7B;C_W6@pt_)=5(n zf^1ME3c>wNP+-Wqa4Zy+^+@^&D(Z4PmrW|+WFrbts32kkj^iGl*uVGeX{aZjJql9s z?7+mtAPA(hM`OW2_9K9%wPLa!_XCtBWXD6nlu~_u1D#yFA z=dOt<+2IG78VdUH9fc)nfT8dw-UV=#dEjNNRWoC+nU^fv@0y&~ZPT`U8m+D7zYI+6 z<{O6jE18=OxO+0D-mGbN z+O#`k+PkXN)ER!yXdH&C2k)5}tLN&_DtsRkM4%>BcCS_eW{wdUQ0NRQb5P_OP_nuy ztxqSLaM!{r5#oIaxnKm=IqZ{w#06llA|biZ_yp_?P<>SKi5zGfP)6J+iH#R&59BNU zR%_^p1-Z!QrRCqSKFv_P0SD#AK+%DwofIV$1iVE`pn_-zaFw}h-?G^BM8-a_Xc{1mfEv1` z$F?Y!{C?T&_bVzN@>ak9*~vg8S7P-0`B>2JC#}%v7DL<8k;!I2P;dw`q6NV7%m=!C zt2$QyB&*cJD&?8d1|{W~!fSywdR_<6!0Q1Trwl%$Y&$eOe1dLf{K)v@0}^QNF_3MD zUn76l*e4(gQQTbsR^=sYP84-!D81MDdmq1+ia(4_Ms?02Zyoy=-+}KQ?{rTTd^X zzIo(bU8b==ZS60MyrHUxuR!M0*#|7b79~kFsuFBD z2J-AGTZMainBowDo>z0n{f&$}YqhdFUqzM|W{bIV)*DqK_%HYlrTL1ue zTKjGfzjN;GbMFuSiA z6NYepc^1Awl`u(D0%RrHKB69SCd?57O3Y+MqT*V8lmo0ehXsFR(wr~@wi2+`9M%R{ zOTq$JGhpo$tLGhnwI;0B>QnWjEbn~Yl(bFPUuCBZydi0q^3JeC-k3}}5{|IBFhezW zg%vg66Llq>P@Z=PsiiPmcf!fL%a@^(CJs(CXv>7r)GJ9Zv%DvvrH~1u>0OduX1}dZ zx)Lm{;el3a#wLSFRoqzWxHdW%(NAMu@{cOjb&HXW3_OsnVdF`;4zrOOsWJs)X*7>rkFSJqeGsG=&?~ zT;Zv%;m_C?>NT3eTrRWb!B?yEQ^uB>)xvO#nkzgL`L7A1Ia`v{dGQ9mrjAKg=l7M9 zt`!emO*#szafPWPCp`(h=+H0;Tf&o2%DuSeR8^U*i9V9h^R>8YL=Rt^(1+24E=hcy z+TSIH)aClAR7c~X9nE9U6-l@oprh5U83Xp{Mr+ug-?w}{tc&tHs)6pPMmqAQ1ne4q zbD{<2+VZ?PtXZ+~gu)9yEZeljEF!0jXvei4%)jKlPy^GFX zO5L~-sN31QbJt%wg$+Ou_>A&2wkU-PnIHW;i+D}LZv&-QdjWj%I(}~UxrIQcx-DDX zo38H7RQD}9`__{L@ISHvA4ynM4qvub{}$iDHuq+D(x8COgM~ z28H7yNPZTrGSH1Vu}uA3581uc=Kz;3tSGZQh`E3`Mkkj$1Yf1jq=%-*B7yPqd|=<_ zlW}URTQC{X1>lcYnH#=0o_%}EVoP79Zs%3y3m&rF5821bvrvKP0K|2zJ9b|oe+}7> zQM!MOmZq!=fKTor+YvXbcY^&*adT4#N3~NfPgNA;O@N;yA;{Ti4RInC6@~t$hb&+^ zI7MakH?@jQac2kIR^*hKf`JN(&{keu9UQ2<{w5qBI*SJTXsJIDE$gtM# znHg7Q*4dPHHf5dL(#~x+jcMnOlz!RiEr+$cvvw|R=d$+Jw7oTJ_oeN=o2?o9j+A!U zTa)!}O?$Uyz1!2??OAVk+S`5GlJP#4s#u0GT+L}$bJo?CcC}?)9cfp`%`+L-u9N}V zr7Bh|-bG8pa_y$+BP+E{uWY`tIaAx7I3GH>9Wfo`G>!r3`mH_4E7jI&#HP zeLXpyyyIwI(57_D7SHv4*Y?4kz|8*nwpY4tbfvv*X)CxWR_Zsu(*JV*8?Cp!?=*g| zanbg8N+Z{7dR4b*YfWi>ZLgl!d}BPN{XosESe!G1Dv5g1-kv*_9_Uu_iDa$qcdYF< z18HmbFRkq>#SRg7&3s?BzB66lnXTWGhX3w8DdSzMV@9X)s4MO4%2>Oz)?I1quG^P0 z*2h!qvZ*3<`uf@Fv-8_BwkB|zQ`C#Y*GHyDzHv5dKZSpBaC$VUr{l>Yp zsV>ES%}Y8N5jr-Mzpy;7r{eOY;Zr`Zt>2n0$M5v7tZX z-j~|{Ylr)Ts+xJv8h$JJQyU)ZhmeFJKnETW{8;y}fB`FQV30 zvVUN8et+AKb}f33q^(DQsgAmNKJ92;G&QeR9q4&OYkBnv0O*Vj!?QFIHz<;_uA+kX zaY_TBQrfuhq#z0sSLBg{a18L+LG%X1KoNltL6`tUQc0cm zVGHDC!$pWSxF8n!Xk~{IPnB;Q-&7(eO3Hr+Jy9`qm07V^ulHZ;U+&(q*7c@kthMVY zgl7&)p$KRx2zLXOT8>6R%@xhXIuNINUULzsDpp2WaL8=rlSR7IgqKg{XuhJ-eZW=Tm>Phyvt8J5I1m=Rh8 zB?%mGKs9LdmGW)C6;!U37LUH*3d&Qw5bYGkK!=jVo20x$DU6rYCF!k-{1@s9ju&v% zpjB3qczr_4Yu_@fH_0kZ%g^7BXHlAf;#@Af=0Q1;ceoS^RC?0#a%-ctP*=^VZIXH^ z@0tNeNt;?;c$QypfNd|-QFH2d!c6qxP8C~tmLEZ-3bbOv-G$m}4qD*_O-TYQo;ymC z${Q#xvu1hAV^ANQIc&JEq#?Y9cdf@I^rI}?iD+J9|A9>!z)8G&eVy=Mt;Z$uUJIl} z!ce%NN*GRkMycSl#$#sHRvHdmgxHP31smF0XxwsOA#xBx1%-vg_~daY_id6bc-=B7!o>~50a05S1w1*4U4hX^BWuA_jPX+#up?X~ z16Z8IVz{rnED%{k1lbsjjZcIkf^0r~aOn8S1N#R~9Ux|`q!lO6E9N)U0YwA1L;7GO z22r!RU~FQF;GTfUom`l#tR;cVvIBzEz{nL;Ecqsm`F99j!0Kk`DGGWD;&yRTQ65}F zAyI-DKiL3bvw-j!sr^k*L6LcEV-RT=8C*(1Je&>(kTrfHq5{dWQ89AOImHB5R`J^M zItz;a6Pk$&zzVQv-Hg*S6PO#H9balQsIDbz$Fj$pI<#VOWG#(pOJmluC2iTV zXz2uV!)CvJc>3`5q3NNlb#vOfc|n)udedBQmfMx)b}d;SU3R(WYG-Tb8fP09H}~A` zr3UPZ#WQnh4*Vl8J$J{_db1_l{#d&Gv26R1bo-H?elgQNv{EqgI__9IZnJ4?58Phe zb$jR9XWQpT-Xh;k-byaH`&0YxZhiD!?GKFa8Q<5u|J35iQ|}rxyN5GdPpg_2uFk*) z!g*dhylk~yKRA8x#l!GHb9-j@%^G2Jc#%7W!WAf3^SimUnz_``-QH4^F># zdda$<8k=0&$}MS5Adm<&+tD1VkjRr;@ax zkjDK{lJX*wEq70(M8s5l4yCVt#|BC*?+b@H=5I?1Q=-?}Wz?)XOQ6oi?ZDhBO@($F znqGOufTmY7Q&9IU4Do`=wt+cT@ajLqym;XGMrgF%v9vAwIphLJqJ6n_>+4^7^-HgR`PDCf=UibYH{G){73S-XX~(>I zVes|iuO44A^}(S{#bjG{r(1R}nf5FfZKD+oefr~rO2)bAKBKQ_hZB6^YWj#Xn(w&1z5E6aJA8$mw-(1l|#9k?m~RY|8~e9c?2dv(8^dB zA4fyD;*}+WUkUJQ2QHDl*lL}V4@Ct1G+e(ZR6bKM9t{;MGZ=>A?ZCnM)xm~*){Udi z=whZzn65v%649(&6OOiB?T9Kl@)W)zK$oS61{{Vl9l5X5>AUY+P5Qq3UY^yr+&`+- z>U-{++x4#dXIMADHi%MN#V9pO0@{VIUI~EvTkP{S1Ybvhw+Q4A0_rL>ptEULpAube zKx-i&Q74?@V?(itMg;v^8O0`WKujs@u4o_v-p^1(q|xc%zN2|+S~ToGJ~Vt_XxKme z%!vd3r;eXI=0AP%=z*dA#|IA#%GE`s$4(y|KI}g+aB`Ri4#E`~{mTO->KCnH8r7u` zrkGgZX;os0_mO{rdcYP&yaWJT0WAA_gPzr`+8NgTAye@oWBHJ=f5b?Zq_w(=m7(d2km;u XAA7*Sfl+i>P=N z{0-9I;mMmf_au7qRw-V3GBZ0p_#lt>9{IlazPx231@KD1I_|dYY}OZCK(UwN1;G1KCjVvmlkNf zqp$umN{<%OL8WWAS_J8+ zR%HWPA^d#(v7=~XVRh9dJroQpmTZnGrH=(Px&{`|>!MV1c-l`p0ZixV1cbK0U@BGp z0=RVE%31BDR?yWerUDnIs7|ESszT)_9cjT76bq*2*fkFlq>^i#fYWy3oiTXbD-InT z8fJs6vZ4KiycOJwq`%vD9Y?EShh2^Gykb)2`QdoD+Q@URi#%U#^crm(F1L3St1#4u z#!BTslZ%$*^2xzo_ROJm*^~vhZ_GpHSvJ)LE3+f4OlG9n^~}!E?~0`tjXf1vDQB5! z{6eejYN7YKg{G#t9Nk|p@PWMA|^h!*cU(W$-yxArfBDQ;+oAlyjYJcST3 zc6}WCX1d3eBq?f$&w$Nf7SE6j&yp<9ksQyHJTH&}FOni3AOn1m4Dul|q^Wx*8|K4g zn2(SVK1xRU7#ZW^WITSBWQX`+ayYhiHbExfe2N|6lVmcErP)z_lpKw1iyh-7QsT$S zaejiF;8SEuLv)&)gx?IECDZg2IYrC#6?(dvAZL`-)XCYlPEA38H^VCb)1fr)&tpeh zmYq}D4$LXXUgfWmiC9;P&F#^9ephcE^u`+D-39jgUhTWOr|Ar62Lz=``)Sxgc~eum z+xiru>1iaA{raRx>IVAihc$FNaRaSs<>H-HOVHI84P{uV`#f-@_4$97WnEu(!xHx! zEk;Yrj@Mu`EV(@Jg)H^1xHXr#vR!h+5SU6eD%U9WN*}i6vhS7VN^r;OJLfCbGu1sG zJktT6B>>9l$XIRpl19mv*E6hmvjf%&qijFe^U^KBs8{zJG_sbc41|B%rEo|YZM)VE zoG^^W_j)$JuqkZ|U;2GLBO74r5M@L6VD35I{J}FSewL?D&~$ zqCo|1Ty*QQY>7OSMidkj6$~gyD=-wOArwgkDFuT7WkU=pTg|t~D99?v0f3lv-S=<0 zbj1;6O{hsNC&Z|FKBiz?1>T5~w%zdSwjCww%MPfKQ6g+Zb#GA-y1r+-Uek}T4Q^z* zp&hj6`uq9F3ZW$!T?u_J!ZBtp$31dM2p^6^)tFm5P<))#0jduyfyxvbC1#t86W&P; z=p%DJ&Qc7kq(;=yOx#%G6peldfkg$EdX>^b~ZX+iSF%6T*O~ zZy6$>s2 zwv81272~#vj0NoxzS_mJkMVF9Pj>O~Kk$`@_zDmWjdreXWDA{38`eN)eq&&wb7f;> z{F~`-jh}{RI*YNre)aC+uSRBDN5&<68@qmObC)XEZ+V%JDE^Zz}X7-=WH&JTnPo!zZE-t7_6kmjD3cthi QQ|SIwdj4GEenkWP7qz1!x&QzG literal 0 HcmV?d00001 diff --git a/lib/requests/__pycache__/cookies.cpython-312.pyc b/lib/requests/__pycache__/cookies.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01716d6e2a9a9716ed63d093302fbf39821bf758 GIT binary patch literal 25276 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 literal 0 HcmV?d00001 diff --git a/lib/requests/__pycache__/models.cpython-312.pyc b/lib/requests/__pycache__/models.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e03047a9cfcefebbf03b0ada846fba5a2adcb951 GIT binary patch literal 35026 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

xxB2> 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 og@Q`p%XX&p{F5EN9ePqx;;V_1yB-U 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 VALnmxDB=6~JB>E}D9;e-{|%Ncb4vgK literal 0 HcmV?d00001 diff --git a/lib/requests/__version__.py b/lib/requests/__version__.py new file mode 100644 index 0000000..1267488 --- /dev/null +++ b/lib/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = 'requests' +__description__ = 'Python HTTP for Humans.' +__url__ = 'https://requests.readthedocs.io' +__version__ = '2.25.1' +__build__ = 0x022501 +__author__ = 'Kenneth Reitz' +__author_email__ = 'me@kennethreitz.org' +__license__ = 'Apache 2.0' +__copyright__ = 'Copyright 2020 Kenneth Reitz' +__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/lib/requests/_internal_utils.py b/lib/requests/_internal_utils.py new file mode 100644 index 0000000..759d9a5 --- /dev/null +++ b/lib/requests/_internal_utils.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" + +from .compat import is_py2, builtin_str, str + + +def to_native_string(string, encoding='ascii'): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode('ascii') + return True + except UnicodeEncodeError: + return False diff --git a/lib/requests/adapters.py b/lib/requests/adapters.py new file mode 100644 index 0000000..fa4d9b3 --- /dev/null +++ b/lib/requests/adapters.py @@ -0,0 +1,533 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from urllib3.poolmanager import PoolManager, proxy_from_url +from urllib3.response import HTTPResponse +from urllib3.util import parse_url +from urllib3.util import Timeout as TimeoutSauce +from urllib3.util.retry import Retry +from urllib3.exceptions import ClosedPoolError +from urllib3.exceptions import ConnectTimeoutError +from urllib3.exceptions import HTTPError as _HTTPError +from urllib3.exceptions import MaxRetryError +from urllib3.exceptions import NewConnectionError +from urllib3.exceptions import ProxyError as _ProxyError +from urllib3.exceptions import ProtocolError +from urllib3.exceptions import ReadTimeoutError +from urllib3.exceptions import SSLError as _SSLError +from urllib3.exceptions import ResponseError +from urllib3.exceptions import LocationValueError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths, + get_encoding_from_headers, prepend_scheme_if_needed, + get_auth_from_url, urldefragauth, select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema, InvalidProxyURL, + InvalidURL) +from .auth import _basic_auth_str + +try: + from urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest ` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session ` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return {attr: getattr(self, attr, None) for attr in self.__attrs__} + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response ` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter ` + + :param req: The :class:`PreparedRequest ` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter `. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_url = parse_url(proxy) + if not proxy_url.host: + raise InvalidProxyURL("Please check proxy URL. It is malformed" + " and could be missing the host.") + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param request: The :class:`PreparedRequest ` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter `. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param request: The :class:`PreparedRequest ` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter `. + + :param proxy: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest ` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + try: + conn = self.get_connection(request.url, proxies) + except LocationValueError as e: + raise InvalidURL(e, request=request) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7, use buffering of HTTP responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 3.3+ + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/lib/requests/api.py b/lib/requests/api.py new file mode 100644 index 0000000..e978e20 --- /dev/null +++ b/lib/requests/api.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- + +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +from . import sessions + + +def request(method, url, **kwargs): + """Constructs and sends a :class:`Request `. + + :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary, list of tuples or bytes to send + in the query string for the :class:`Request`. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) ` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response ` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'https://httpbin.org/get') + >>> req + + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary, list of tuples or bytes to send + in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. If + `allow_redirects` is not provided, it will be set to `False` (as + opposed to the default :meth:`request` behavior). + :return: :class:`Response ` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response ` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/lib/requests/auth.py b/lib/requests/auth.py new file mode 100644 index 0000000..eeface3 --- /dev/null +++ b/lib/requests/auth.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +""" +requests.auth +~~~~~~~~~~~~~ + +This module contains the authentication handlers for Requests. +""" + +import os +import re +import time +import hashlib +import threading +import warnings + +from base64 import b64encode + +from .compat import urlparse, str, basestring +from .cookies import extract_cookies_to_jar +from ._internal_utils import to_native_string +from .utils import parse_dict_header + +CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' +CONTENT_TYPE_MULTI_PART = 'multipart/form-data' + + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + + # "I want us to put a big-ol' comment on top of it that + # says that this behaviour is dumb but we need to preserve + # it because people are relying on it." + # - Lukasa + # + # These are here solely to maintain backwards compatibility + # for things like ints. This will be removed in 3.0.0. + if not isinstance(username, basestring): + warnings.warn( + "Non-string usernames will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(username), + category=DeprecationWarning, + ) + username = str(username) + + if not isinstance(password, basestring): + warnings.warn( + "Non-string passwords will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(type(password)), + category=DeprecationWarning, + ) + password = str(password) + # -- End Removal -- + + if isinstance(username, str): + username = username.encode('latin1') + + if isinstance(password, str): + password = password.encode('latin1') + + authstr = 'Basic ' + to_native_string( + b64encode(b':'.join((username, password))).strip() + ) + + return authstr + + +class AuthBase(object): + """Base class that all auth implementations derive from""" + + def __call__(self, r): + raise NotImplementedError('Auth hooks must be callable.') + + +class HTTPBasicAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other + + def __call__(self, r): + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authentication to a given Request object.""" + + def __call__(self, r): + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPDigestAuth(AuthBase): + """Attaches HTTP Digest Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + # Keep state in per-thread local storage + self._thread_local = threading.local() + + def init_per_thread_state(self): + # Ensure state is initialized just once per-thread + if not hasattr(self._thread_local, 'init'): + self._thread_local.init = True + self._thread_local.last_nonce = '' + self._thread_local.nonce_count = 0 + self._thread_local.chal = {} + self._thread_local.pos = None + self._thread_local.num_401_calls = None + + def build_digest_header(self, method, url): + """ + :rtype: str + """ + + realm = self._thread_local.chal['realm'] + nonce = self._thread_local.chal['nonce'] + qop = self._thread_local.chal.get('qop') + algorithm = self._thread_local.chal.get('algorithm') + opaque = self._thread_local.chal.get('opaque') + hash_utf8 = None + + if algorithm is None: + _algorithm = 'MD5' + else: + _algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': + def md5_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.md5(x).hexdigest() + hash_utf8 = md5_utf8 + elif _algorithm == 'SHA': + def sha_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha1(x).hexdigest() + hash_utf8 = sha_utf8 + elif _algorithm == 'SHA-256': + def sha256_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha256(x).hexdigest() + hash_utf8 = sha256_utf8 + elif _algorithm == 'SHA-512': + def sha512_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha512(x).hexdigest() + hash_utf8 = sha512_utf8 + + KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) + + if hash_utf8 is None: + return None + + # XXX not implemented yet + entdig = None + p_parsed = urlparse(url) + #: path is request-uri defined in RFC 2616 which should not be empty + path = p_parsed.path or "/" + if p_parsed.query: + path += '?' + p_parsed.query + + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (method, path) + + HA1 = hash_utf8(A1) + HA2 = hash_utf8(A2) + + if nonce == self._thread_local.last_nonce: + self._thread_local.nonce_count += 1 + else: + self._thread_local.nonce_count = 1 + ncvalue = '%08x' % self._thread_local.nonce_count + s = str(self._thread_local.nonce_count).encode('utf-8') + s += nonce.encode('utf-8') + s += time.ctime().encode('utf-8') + s += os.urandom(8) + + cnonce = (hashlib.sha1(s).hexdigest()[:16]) + if _algorithm == 'MD5-SESS': + HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) + + if not qop: + respdig = KD(HA1, "%s:%s" % (nonce, HA2)) + elif qop == 'auth' or 'auth' in qop.split(','): + noncebit = "%s:%s:%s:%s:%s" % ( + nonce, ncvalue, cnonce, 'auth', HA2 + ) + respdig = KD(HA1, noncebit) + else: + # XXX handle auth-int. + return None + + self._thread_local.last_nonce = nonce + + # XXX should the partial digests be encoded too? + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (self.username, realm, nonce, path, respdig) + if opaque: + base += ', opaque="%s"' % opaque + if algorithm: + base += ', algorithm="%s"' % algorithm + if entdig: + base += ', digest="%s"' % entdig + if qop: + base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) + + return 'Digest %s' % (base) + + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self._thread_local.num_401_calls = 1 + + def handle_401(self, r, **kwargs): + """ + Takes the given response and tries digest-auth, if needed. + + :rtype: requests.Response + """ + + # If response is not 4xx, do not auth + # See https://github.com/psf/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + + if self._thread_local.pos is not None: + # Rewind the file position indicator of the body to where + # it was to resend the request. + r.request.body.seek(self._thread_local.pos) + s_auth = r.headers.get('www-authenticate', '') + + if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: + + self._thread_local.num_401_calls += 1 + pat = re.compile(r'digest ', flags=re.IGNORECASE) + self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) + + # Consume content and release the original connection + # to allow our new request to reuse the same one. + r.content + r.close() + prep = r.request.copy() + extract_cookies_to_jar(prep._cookies, r.request, r.raw) + prep.prepare_cookies(prep._cookies) + + prep.headers['Authorization'] = self.build_digest_header( + prep.method, prep.url) + _r = r.connection.send(prep, **kwargs) + _r.history.append(r) + _r.request = prep + + return _r + + self._thread_local.num_401_calls = 1 + return r + + def __call__(self, r): + # Initialize per-thread state, if needed + self.init_per_thread_state() + # If we have a saved nonce, skip the 401 + if self._thread_local.last_nonce: + r.headers['Authorization'] = self.build_digest_header(r.method, r.url) + try: + self._thread_local.pos = r.body.tell() + except AttributeError: + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self._thread_local.pos = None + r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) + self._thread_local.num_401_calls = 1 + + return r + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other diff --git a/lib/requests/certs.py b/lib/requests/certs.py new file mode 100644 index 0000000..d1a378d --- /dev/null +++ b/lib/requests/certs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from certifi import where + +if __name__ == '__main__': + print(where()) diff --git a/lib/requests/compat.py b/lib/requests/compat.py new file mode 100644 index 0000000..5de0769 --- /dev/null +++ b/lib/requests/compat.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- + +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module handles import compatibility issues between Python 2 and +Python 3. +""" + +import chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = (_ver[0] == 2) + +#: Python 3.x? +is_py3 = (_ver[0] == 3) + +try: + import simplejson as json +except ImportError: + import json + +# --------- +# Specifics +# --------- + +if is_py2: + from urllib import ( + quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, + proxy_bypass, proxy_bypass_environment, getproxies_environment) + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag + from urllib2 import parse_http_list + import cookielib + from Cookie import Morsel + from StringIO import StringIO + # Keep OrderedDict for backwards compatibility. + from collections import Callable, Mapping, MutableMapping, OrderedDict + + + builtin_str = str + bytes = str + str = unicode + basestring = basestring + numeric_types = (int, long, float) + integer_types = (int, long) + +elif is_py3: + from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag + from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment + from http import cookiejar as cookielib + from http.cookies import Morsel + from io import StringIO + # Keep OrderedDict for backwards compatibility. + from collections import OrderedDict + from collections.abc import Callable, Mapping, MutableMapping + + builtin_str = str + str = str + bytes = bytes + basestring = (str, bytes) + numeric_types = (int, float) + integer_types = (int,) diff --git a/lib/requests/cookies.py b/lib/requests/cookies.py new file mode 100644 index 0000000..56fccd9 --- /dev/null +++ b/lib/requests/cookies.py @@ -0,0 +1,549 @@ +# -*- coding: utf-8 -*- + +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import copy +import time +import calendar + +from ._internal_utils import to_native_string +from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest(object): + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get('Host'): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers['Host'], encoding='utf-8') + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse([ + parsed.scheme, host, parsed.path, parsed.params, parsed.query, + parsed.fragment + ]) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse(object): + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, '_original_response') and + response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get('Cookie') + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if ( + (domain is None or cookie.domain == domain) and + (path is None or cookie.path == path) + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super(RequestsCookieJar, self).__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): + cookie.value = cookie.value.replace('\\"', '') + return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super(RequestsCookieJar, self).update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: # if there are multiple cookies that meet passed in criteria + raise CookieConflictError('There are multiple cookies with name, %r' % (name)) + toReturn = cookie.value # we will eventually return this as long as no cookie conflict + + if toReturn: + return toReturn + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop('_cookies_lock') + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if '_cookies_lock' not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.set_policy(self.get_policy()) + new_cj.update(self) + return new_cj + + def get_policy(self): + """Return the CookiePolicy instance used.""" + return self._policy + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, 'copy'): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = { + 'version': 0, + 'name': name, + 'value': value, + 'port': None, + 'domain': '', + 'path': '/', + 'secure': False, + 'expires': None, + 'discard': True, + 'comment': None, + 'comment_url': None, + 'rest': {'HttpOnly': None}, + 'rfc2109': False, + } + + badargs = set(kwargs) - set(result) + if badargs: + err = 'create_cookie() got unexpected keyword arguments: %s' + raise TypeError(err % list(badargs)) + + result.update(kwargs) + result['port_specified'] = bool(result['port']) + result['domain_specified'] = bool(result['domain']) + result['domain_initial_dot'] = result['domain'].startswith('.') + result['path_specified'] = bool(result['path']) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel['max-age']: + try: + expires = int(time.time() + int(morsel['max-age'])) + except ValueError: + raise TypeError('max-age: %s must be integer' % morsel['max-age']) + elif morsel['expires']: + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = calendar.timegm( + time.strptime(morsel['expires'], time_template) + ) + return create_cookie( + comment=morsel['comment'], + comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, + rest={'HttpOnly': morsel['httponly']}, + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + :rtype: CookieJar + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + :rtype: CookieJar + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError('You can only merge into CookieJar') + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict( + cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/lib/requests/exceptions.py b/lib/requests/exceptions.py new file mode 100644 index 0000000..0e9c820 --- /dev/null +++ b/lib/requests/exceptions.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class InvalidProxyURL(InvalidURL): + """The proxy URL provided is invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content.""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed.""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """Requests encountered an error when trying to rewind a body.""" + +# Warnings + + +class RequestsWarning(Warning): + """Base warning for Requests.""" + + +class FileModeWarning(RequestsWarning, DeprecationWarning): + """A file was opened in text mode, but Requests determined its binary length.""" + + +class RequestsDependencyWarning(RequestsWarning): + """An imported dependency doesn't match the expected version range.""" diff --git a/lib/requests/help.py b/lib/requests/help.py new file mode 100644 index 0000000..e53d35e --- /dev/null +++ b/lib/requests/help.py @@ -0,0 +1,119 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +import idna +import urllib3 +import chardet + +from . import __version__ as requests_version + +try: + from urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + system_ssl = ssl.OPENSSL_VERSION_NUMBER + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/lib/requests/hooks.py b/lib/requests/hooks.py new file mode 100644 index 0000000..7a51f21 --- /dev/null +++ b/lib/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return {event: [] for event in HOOKS} + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or {} + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/lib/requests/models.py b/lib/requests/models.py new file mode 100644 index 0000000..ec2edc2 --- /dev/null +++ b/lib/requests/models.py @@ -0,0 +1,956 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import datetime +import sys + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/psf/requests/issues/3578. +import encodings.idna + +from urllib3.fields import RequestField +from urllib3.filepost import encode_multipart_formdata +from urllib3.util import parse_url +from urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + Callable, Mapping, + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + elif hasattr(fp, 'read'): + fdata = fp.read() + elif fp is None: + continue + else: + fdata = fp + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request ` object. + + Used to prepare a :class:`PreparedRequest `, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary or + list of tuples ``[(key, value)]`` is provided, form-encoding will + take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: URL parameters to append to the URL. If a dictionary or + list of tuples ``[(key, value)]`` is provided, form-encoding will + take place. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'https://httpbin.org/get') + >>> req.prepare() + + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest ` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest ` object, + containing the exact bytes that will be sent to the server. + + Instances are generated from a :class:`Request ` object, and + should not be instantiated manually; doing so may produce undesirable + effects. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'https://httpbin.org/get') + >>> r = req.prepare() + >>> r + + + >>> s = requests.Session() + >>> s.send(r) + + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/psf/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, Mapping)) + ]) + + if is_stream: + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest ` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response ` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + #: This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response ` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest ` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return {attr: getattr(self, attr, None) for attr in self.__attrs__} + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400, False if not. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b'' + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/lib/requests/packages.py b/lib/requests/packages.py new file mode 100644 index 0000000..7232fe0 --- /dev/null +++ b/lib/requests/packages.py @@ -0,0 +1,14 @@ +import sys + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ('urllib3', 'idna', 'chardet'): + locals()[package] = __import__(package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == package or mod.startswith(package + '.'): + sys.modules['requests.packages.' + mod] = sys.modules[mod] + +# Kinda cool, though, right? diff --git a/lib/requests/sessions.py b/lib/requests/sessions.py new file mode 100644 index 0000000..45ab8a5 --- /dev/null +++ b/lib/requests/sessions.py @@ -0,0 +1,781 @@ +# -*- coding: utf-8 -*- + +""" +requests.sessions +~~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import sys +import time +from datetime import timedelta +from collections import OrderedDict + +from .auth import _basic_auth_str +from .compat import cookielib, is_py3, urljoin, urlparse, Mapping +from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) +from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT +from .hooks import default_hooks, dispatch_hook +from ._internal_utils import to_native_string +from .utils import to_key_val_list, default_headers, DEFAULT_PORTS +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + +from .structures import CaseInsensitiveDict +from .adapters import HTTPAdapter + +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url, rewind_body +) + +from .status_codes import codes + +# formerly defined here, reexposed here for backward compatibility +from .models import REDIRECT_STATI + +# Preferred clock, based on which one is more accurate on a given system. +if sys.platform == 'win32': + try: # Python 3.4+ + preferred_clock = time.perf_counter + except AttributeError: # Earlier than Python 3. + preferred_clock = time.clock +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and + isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get('response') == []: + return request_hooks + + if request_hooks is None or request_hooks.get('response') == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin(object): + + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers['location'] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + if is_py3: + location = location.encode('latin1') + return to_native_string(location, 'utf8') + return None + + def should_strip_auth(self, old_url, new_url): + """Decide whether Authorization header should be removed when redirecting""" + old_parsed = urlparse(old_url) + new_parsed = urlparse(new_url) + if old_parsed.hostname != new_parsed.hostname: + return True + # Special case: allow http -> https redirect when using the standard + # ports. This isn't specified by RFC 7235, but is kept to avoid + # breaking backwards compatibility with older versions of requests + # that allowed any redirects on the same host. + if (old_parsed.scheme == 'http' and old_parsed.port in (80, None) + and new_parsed.scheme == 'https' and new_parsed.port in (443, None)): + return False + + # Handle default port usage corresponding to scheme. + changed_port = old_parsed.port != new_parsed.port + changed_scheme = old_parsed.scheme != new_parsed.scheme + default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) + if (not changed_scheme and old_parsed.port in default_port + and new_parsed.port in default_port): + return False + + # Standard case: root URI must match + return changed_port or changed_scheme + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + previous_fragment = urlparse(req.url).fragment + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects('Exceeded {} redirects.'.format(self.max_redirects), response=resp) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith('//'): + parsed_rurl = urlparse(resp.url) + url = ':'.join([to_native_string(parsed_rurl.scheme), url]) + + # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) + parsed = urlparse(url) + if parsed.fragment == '' and previous_fragment: + parsed = parsed._replace(fragment=previous_fragment) + elif parsed.fragment: + previous_fragment = parsed.fragment + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/psf/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/psf/requests/issues/3490 + purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + headers.pop('Cookie', None) + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers and self.should_strip_auth(response.request.url, url): + # If we get redirected to a new host, we should strip out any + # authentication headers. + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # https://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('https://httpbin.org/get') + + + Or as a context manager:: + + >>> with requests.Session() as s: + ... s.get('https://httpbin.org/get') + + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request ` sent from this + #: :class:`Session `. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request `. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request `. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request `. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + #: Defaults to `True`, requiring requests to verify the TLS certificate at the + #: remote end. + #: If verify is set to `False`, requests will accept any TLS certificate + #: presented by the server, and will ignore hostname mismatches and/or + #: expired certificates, which will make your application vulnerable to + #: man-in-the-middle (MitM) attacks. + #: Only set this to `False` for testing. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar `, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest ` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request ` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request `, prepares it and sends it. + Returns :class:`Response ` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) ` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. When set to + ``False``, requests will accept any TLS certificate presented by + the server, and will ignore hostname mismatches and/or expired + certificates, which will make your application vulnerable to + man-in-the-middle (MitM) attacks. Setting verify to ``False`` + may be useful during local development or testing. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, list of tuples, bytes, or file-like + object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Resolve redirects if allowed. + if allow_redirects: + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + history = [resp for resp in gen] + else: + history = [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix.lower()): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for {!r}".format(url)) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = {attr: getattr(self, attr, None) for attr in self.__attrs__} + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + .. deprecated:: 1.0.0 + + This method has been deprecated since version 1.0.0 and is only kept for + backwards compatibility. New code should use :class:`~requests.sessions.Session` + to create a session. This may be removed at a future date. + + :rtype: Session + """ + return Session() diff --git a/lib/requests/status_codes.py b/lib/requests/status_codes.py new file mode 100644 index 0000000..d80a7cd --- /dev/null +++ b/lib/requests/status_codes.py @@ -0,0 +1,123 @@ +# -*- coding: utf-8 -*- + +r""" +The ``codes`` object defines a mapping from common names for HTTP statuses +to their numerical codes, accessible either as attributes or as dictionary +items. + +Example:: + + >>> import requests + >>> requests.codes['temporary_redirect'] + 307 + >>> requests.codes.teapot + 418 + >>> requests.codes['\o/'] + 200 + +Some codes have multiple names, and both upper- and lower-case versions of +the names are allowed. For example, ``codes.ok``, ``codes.OK``, and +``codes.okay`` all correspond to the HTTP status code 200. +""" + +from .structures import LookupDict + +_codes = { + + # Informational. + 100: ('continue',), + 101: ('switching_protocols',), + 102: ('processing',), + 103: ('checkpoint',), + 122: ('uri_too_long', 'request_uri_too_long'), + 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), + 201: ('created',), + 202: ('accepted',), + 203: ('non_authoritative_info', 'non_authoritative_information'), + 204: ('no_content',), + 205: ('reset_content', 'reset'), + 206: ('partial_content', 'partial'), + 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), + 208: ('already_reported',), + 226: ('im_used',), + + # Redirection. + 300: ('multiple_choices',), + 301: ('moved_permanently', 'moved', '\\o-'), + 302: ('found',), + 303: ('see_other', 'other'), + 304: ('not_modified',), + 305: ('use_proxy',), + 306: ('switch_proxy',), + 307: ('temporary_redirect', 'temporary_moved', 'temporary'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 + + # Client Error. + 400: ('bad_request', 'bad'), + 401: ('unauthorized',), + 402: ('payment_required', 'payment'), + 403: ('forbidden',), + 404: ('not_found', '-o-'), + 405: ('method_not_allowed', 'not_allowed'), + 406: ('not_acceptable',), + 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), + 408: ('request_timeout', 'timeout'), + 409: ('conflict',), + 410: ('gone',), + 411: ('length_required',), + 412: ('precondition_failed', 'precondition'), + 413: ('request_entity_too_large',), + 414: ('request_uri_too_large',), + 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), + 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), + 417: ('expectation_failed',), + 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), + 421: ('misdirected_request',), + 422: ('unprocessable_entity', 'unprocessable'), + 423: ('locked',), + 424: ('failed_dependency', 'dependency'), + 425: ('unordered_collection', 'unordered'), + 426: ('upgrade_required', 'upgrade'), + 428: ('precondition_required', 'precondition'), + 429: ('too_many_requests', 'too_many'), + 431: ('header_fields_too_large', 'fields_too_large'), + 444: ('no_response', 'none'), + 449: ('retry_with', 'retry'), + 450: ('blocked_by_windows_parental_controls', 'parental_controls'), + 451: ('unavailable_for_legal_reasons', 'legal_reasons'), + 499: ('client_closed_request',), + + # Server Error. + 500: ('internal_server_error', 'server_error', '/o\\', '✗'), + 501: ('not_implemented',), + 502: ('bad_gateway',), + 503: ('service_unavailable', 'unavailable'), + 504: ('gateway_timeout',), + 505: ('http_version_not_supported', 'http_version'), + 506: ('variant_also_negotiates',), + 507: ('insufficient_storage',), + 509: ('bandwidth_limit_exceeded', 'bandwidth'), + 510: ('not_extended',), + 511: ('network_authentication_required', 'network_auth', 'network_authentication'), +} + +codes = LookupDict(name='status_codes') + +def _init(): + for code, titles in _codes.items(): + for title in titles: + setattr(codes, title, code) + if not title.startswith(('\\', '/')): + setattr(codes, title.upper(), code) + + def doc(code): + names = ', '.join('``%s``' % n for n in _codes[code]) + return '* %d: %s' % (code, names) + + global __doc__ + __doc__ = (__doc__ + '\n' + + '\n'.join(doc(code) for code in sorted(_codes)) + if __doc__ is not None else None) + +_init() diff --git a/lib/requests/structures.py b/lib/requests/structures.py new file mode 100644 index 0000000..8ee0ba7 --- /dev/null +++ b/lib/requests/structures.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +""" +requests.structures +~~~~~~~~~~~~~~~~~~~ + +Data structures that power Requests. +""" + +from collections import OrderedDict + +from .compat import Mapping, MutableMapping + + +class CaseInsensitiveDict(MutableMapping): + """A case-insensitive ``dict``-like object. + + Implements all methods and operations of + ``MutableMapping`` as well as dict's ``copy``. Also + provides ``lower_items``. + + All keys are expected to be strings. The structure remembers the + case of the last key to be set, and ``iter(instance)``, + ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` + will contain case-sensitive keys. However, querying and contains + testing is case insensitive:: + + cid = CaseInsensitiveDict() + cid['Accept'] = 'application/json' + cid['aCCEPT'] == 'application/json' # True + list(cid) == ['Accept'] # True + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header, regardless + of how the header name was originally stored. + + If the constructor, ``.update``, or equality comparison + operations are given keys that have equal ``.lower()``s, the + behavior is undefined. + """ + + def __init__(self, data=None, **kwargs): + self._store = OrderedDict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + # Use the lowercased key for lookups, but store the actual + # key alongside the value. + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def lower_items(self): + """Like iteritems(), but with all lowercase keys.""" + return ( + (lowerkey, keyval[1]) + for (lowerkey, keyval) + in self._store.items() + ) + + def __eq__(self, other): + if isinstance(other, Mapping): + other = CaseInsensitiveDict(other) + else: + return NotImplemented + # Compare insensitively + return dict(self.lower_items()) == dict(other.lower_items()) + + # Copy is required + def copy(self): + return CaseInsensitiveDict(self._store.values()) + + def __repr__(self): + return str(dict(self.items())) + + +class LookupDict(dict): + """Dictionary lookup object.""" + + def __init__(self, name=None): + self.name = name + super(LookupDict, self).__init__() + + def __repr__(self): + return '' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/lib/requests/utils.py b/lib/requests/utils.py new file mode 100644 index 0000000..db67938 --- /dev/null +++ b/lib/requests/utils.py @@ -0,0 +1,992 @@ +# -*- coding: utf-8 -*- + +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import codecs +import contextlib +import io +import os +import re +import socket +import struct +import sys +import tempfile +import warnings +import zipfile +from collections import OrderedDict + +from .__version__ import __version__ +from . import certs +# to_native_string is unused here, but imported here for backwards compatibility +from ._internal_utils import to_native_string +from .compat import parse_http_list as _parse_list_header +from .compat import ( + quote, urlparse, bytes, str, unquote, getproxies, + proxy_bypass, urlunparse, basestring, integer_types, is_py3, + proxy_bypass_environment, getproxies_environment, Mapping) +from .cookies import cookiejar_from_dict +from .structures import CaseInsensitiveDict +from .exceptions import ( + InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) + +NETRC_FILES = ('.netrc', '_netrc') + +DEFAULT_CA_BUNDLE_PATH = certs.where() + +DEFAULT_PORTS = {'http': 80, 'https': 443} + + +if sys.platform == 'win32': + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + try: + if is_py3: + import winreg + else: + import _winreg as winreg + except ImportError: + return False + + try: + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it + proxyEnable = int(winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0]) + # ProxyOverride is almost always a string + proxyOverride = winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0] + except OSError: + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + netrc_file = os.environ.get('NETRC') + if netrc_file is not None: + netrc_locations = (netrc_file,) + else: + netrc_locations = ('~/{}'.format(f) for f in NETRC_FILES) + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in netrc_locations: + try: + loc = os.path.expanduser(f) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See https://bugs.python.org/issue20164 & + # https://github.com/psf/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # App Engine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def extract_zipped_paths(path): + """Replace nonexistent paths that look like they refer to a member of a zip + archive with the location of an extracted copy of the target, or else + just return the provided path unchanged. + """ + if os.path.exists(path): + # this is already a valid path, no need to do anything further + return path + + # find the first valid part of the provided path and treat that as a zip archive + # assume the rest of the path is the name of a member in the archive + archive, member = os.path.split(path) + while archive and not os.path.exists(archive): + archive, prefix = os.path.split(archive) + member = '/'.join([prefix, member]) + + if not zipfile.is_zipfile(archive): + return path + + zip_file = zipfile.ZipFile(archive) + if member not in zip_file.namelist(): + return path + + # we have a valid zip archive and a valid member of that archive + tmp = tempfile.gettempdir() + extracted_path = os.path.join(tmp, *member.split('/')) + if not os.path.exists(extracted_path): + extracted_path = zip_file.extract(member, path=tmp) + + return extracted_path + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + Traceback (most recent call last): + ... + ValueError: cannot encode objects that are not 2-tuples + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + Traceback (most recent call last): + ... + ValueError: cannot encode objects that are not 2-tuples + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r']', flags=re.I) + pragma_re = re.compile(r']', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def _parse_content_type_header(header): + """Returns content type and parameters from given header + + :param header: string + :return: tuple containing content type and dictionary of + parameters + """ + + tokens = header.split(';') + content_type, params = tokens[0].strip(), tokens[1:] + params_dict = {} + items_to_strip = "\"' " + + for param in params: + param = param.strip() + if param: + key, value = param, True + index_of_equals = param.find("=") + if index_of_equals != -1: + key = param[:index_of_equals].strip(items_to_strip) + value = param[index_of_equals + 1:].strip(items_to_strip) + params_dict[key.lower()] = value + return content_type, params_dict + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = _parse_content_type_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + if 'application/json' in content_type: + # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset + return 'utf-8' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + # Prioritize lowercase environment variables over uppercase + # to keep a consistent behaviour with other http projects (curl, wget). + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + parsed = urlparse(url) + + if parsed.hostname is None: + # URLs don't always have hostnames, e.g. file:/// urls. + return True + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the hostname, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + if is_ipv4_address(parsed.hostname): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(parsed.hostname, proxy_ip): + return True + elif parsed.hostname == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + host_with_port = parsed.hostname + if parsed.port: + host_with_port += ':{}'.format(parsed.port) + + for host in no_proxy: + if parsed.hostname.endswith(host) or host_with_port.endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + with set_environ('no_proxy', no_proxy_arg): + # parsed.hostname can be `None` in cases such as a file URI. + try: + bypass = proxy_bypass(parsed.hostname) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a list of parsed link headers proxies. + + i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + value = value.strip(replace_chars) + if not value: + return links + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/lib/urllib3-1.26.19.dist-info/INSTALLER b/lib/urllib3-1.26.19.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/lib/urllib3-1.26.19.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/lib/urllib3-1.26.19.dist-info/LICENSE.txt b/lib/urllib3-1.26.19.dist-info/LICENSE.txt new file mode 100644 index 0000000..429a176 --- /dev/null +++ b/lib/urllib3-1.26.19.dist-info/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2008-2020 Andrey Petrov and contributors (see CONTRIBUTORS.txt) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/lib/urllib3-1.26.19.dist-info/METADATA b/lib/urllib3-1.26.19.dist-info/METADATA new file mode 100644 index 0000000..5d891c2 --- /dev/null +++ b/lib/urllib3-1.26.19.dist-info/METADATA @@ -0,0 +1,1499 @@ +Metadata-Version: 2.1 +Name: urllib3 +Version: 1.26.19 +Summary: HTTP library with thread-safe connection pooling, file post, and more. +Home-page: https://urllib3.readthedocs.io/ +Author: Andrey Petrov +Author-email: andrey.petrov@shazow.net +License: MIT +Project-URL: Documentation, https://urllib3.readthedocs.io/ +Project-URL: Code, https://github.com/urllib3/urllib3 +Project-URL: Issue tracker, https://github.com/urllib3/urllib3/issues +Keywords: urllib httplib threadsafe filepost http https ssl pooling +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* +Description-Content-Type: text/x-rst +License-File: LICENSE.txt +Provides-Extra: brotli +Requires-Dist: brotlicffi >=0.8.0 ; ((os_name != "nt" or python_version >= "3") and platform_python_implementation != "CPython") and extra == 'brotli' +Requires-Dist: brotli ==1.0.9 ; (os_name != "nt" and python_version < "3" and platform_python_implementation == "CPython") and extra == 'brotli' +Requires-Dist: brotlipy >=0.6.0 ; (os_name == "nt" and python_version < "3") and extra == 'brotli' +Requires-Dist: brotli >=1.0.9 ; (python_version >= "3" and platform_python_implementation == "CPython") and extra == 'brotli' +Provides-Extra: secure +Requires-Dist: pyOpenSSL >=0.14 ; extra == 'secure' +Requires-Dist: cryptography >=1.3.4 ; extra == 'secure' +Requires-Dist: idna >=2.0.0 ; extra == 'secure' +Requires-Dist: certifi ; extra == 'secure' +Requires-Dist: urllib3-secure-extra ; extra == 'secure' +Requires-Dist: ipaddress ; (python_version == "2.7") and extra == 'secure' +Provides-Extra: socks +Requires-Dist: PySocks !=1.5.7,<2.0,>=1.5.6 ; extra == 'socks' + + +urllib3 is a powerful, *user-friendly* HTTP client for Python. Much of the +Python ecosystem already uses urllib3 and you should too. +urllib3 brings many critical features that are missing from the Python +standard libraries: + +- Thread safety. +- Connection pooling. +- Client-side SSL/TLS verification. +- File uploads with multipart encoding. +- Helpers for retrying requests and dealing with HTTP redirects. +- Support for gzip, deflate, and brotli encoding. +- Proxy support for HTTP and SOCKS. +- 100% test coverage. + +urllib3 is powerful and easy to use: + +.. code-block:: python + + >>> import urllib3 + >>> http = urllib3.PoolManager() + >>> r = http.request('GET', 'http://httpbin.org/robots.txt') + >>> r.status + 200 + >>> r.data + 'User-agent: *\nDisallow: /deny\n' + + +Installing +---------- + +urllib3 can be installed with `pip `_:: + + $ python -m pip install urllib3 + +Alternatively, you can grab the latest source code from `GitHub `_:: + + $ git clone https://github.com/urllib3/urllib3.git + $ cd urllib3 + $ git checkout 1.26.x + $ pip install . + + +Documentation +------------- + +urllib3 has usage and reference documentation at `urllib3.readthedocs.io `_. + + +Contributing +------------ + +urllib3 happily accepts contributions. Please see our +`contributing documentation `_ +for some tips on getting started. + + +Security Disclosures +-------------------- + +To report a security vulnerability, please use the +`Tidelift security contact `_. +Tidelift will coordinate the fix and disclosure with maintainers. + + +Maintainers +----------- + +- `@sethmlarson `__ (Seth M. Larson) +- `@pquentin `__ (Quentin Pradet) +- `@theacodes `__ (Thea Flowers) +- `@haikuginger `__ (Jess Shapiro) +- `@lukasa `__ (Cory Benfield) +- `@sigmavirus24 `__ (Ian Stapleton Cordasco) +- `@shazow `__ (Andrey Petrov) + +👋 + + +Sponsorship +----------- + +If your company benefits from this library, please consider `sponsoring its +development `_. + + +For Enterprise +-------------- + +.. |tideliftlogo| image:: https://nedbatchelder.com/pix/Tidelift_Logos_RGB_Tidelift_Shorthand_On-White_small.png + :width: 75 + :alt: Tidelift + +.. list-table:: + :widths: 10 100 + + * - |tideliftlogo| + - Professional support for urllib3 is available as part of the `Tidelift + Subscription`_. Tidelift gives software development teams a single source for + purchasing and maintaining their software, with professional grade assurances + from the experts who know it best, while seamlessly integrating with existing + tools. + +.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme + + +Changes +======= + +1.26.19 (2024-06-17) +-------------------- + +- Added the ``Proxy-Authorization`` header to the list of headers to strip from requests when redirecting to a different host. As before, different headers can be set via ``Retry.remove_headers_on_redirect``. +- Fixed handling of OpenSSL 3.2.0 new error message for misconfiguring an HTTP proxy as HTTPS. (`#3405 `__) + + +1.26.18 (2023-10-17) +-------------------- + +* Made body stripped from HTTP requests changing the request method to GET after HTTP 303 "See Other" redirect responses. + + +1.26.17 (2023-10-02) +-------------------- + +* Added the ``Cookie`` header to the list of headers to strip from requests when redirecting to a different host. As before, different headers can be set via ``Retry.remove_headers_on_redirect``. + + +1.26.16 (2023-05-23) +-------------------- + +* Fixed thread-safety issue where accessing a ``PoolManager`` with many distinct origins + would cause connection pools to be closed while requests are in progress (`#2954 `_) + + +1.26.15 (2023-03-10) +-------------------- + +* Fix socket timeout value when ``HTTPConnection`` is reused (`#2645 `__) +* Remove "!" character from the unreserved characters in IPv6 Zone ID parsing + (`#2899 `__) +* Fix IDNA handling of '\x80' byte (`#2901 `__) + +1.26.14 (2023-01-11) +-------------------- + +* Fixed parsing of port 0 (zero) returning None, instead of 0. (`#2850 `__) +* Removed deprecated getheaders() calls in contrib module. + +1.26.13 (2022-11-23) +-------------------- + +* Deprecated the ``HTTPResponse.getheaders()`` and ``HTTPResponse.getheader()`` methods. +* Fixed an issue where parsing a URL with leading zeroes in the port would be rejected + even when the port number after removing the zeroes was valid. +* Fixed a deprecation warning when using cryptography v39.0.0. +* Removed the ``<4`` in the ``Requires-Python`` packaging metadata field. + + +1.26.12 (2022-08-22) +-------------------- + +* Deprecated the `urllib3[secure]` extra and the `urllib3.contrib.pyopenssl` module. + Both will be removed in v2.x. See this `GitHub issue `_ + for justification and info on how to migrate. + + +1.26.11 (2022-07-25) +-------------------- + +* Fixed an issue where reading more than 2 GiB in a call to ``HTTPResponse.read`` would + raise an ``OverflowError`` on Python 3.9 and earlier. + + +1.26.10 (2022-07-07) +-------------------- + +* Removed support for Python 3.5 +* Fixed an issue where a ``ProxyError`` recommending configuring the proxy as HTTP + instead of HTTPS could appear even when an HTTPS proxy wasn't configured. + + +1.26.9 (2022-03-16) +------------------- + +* Changed ``urllib3[brotli]`` extra to favor installing Brotli libraries that are still + receiving updates like ``brotli`` and ``brotlicffi`` instead of ``brotlipy``. + This change does not impact behavior of urllib3, only which dependencies are installed. +* Fixed a socket leaking when ``HTTPSConnection.connect()`` raises an exception. +* Fixed ``server_hostname`` being forwarded from ``PoolManager`` to ``HTTPConnectionPool`` + when requesting an HTTP URL. Should only be forwarded when requesting an HTTPS URL. + + +1.26.8 (2022-01-07) +------------------- + +* Added extra message to ``urllib3.exceptions.ProxyError`` when urllib3 detects that + a proxy is configured to use HTTPS but the proxy itself appears to only use HTTP. +* Added a mention of the size of the connection pool when discarding a connection due to the pool being full. +* Added explicit support for Python 3.11. +* Deprecated the ``Retry.MAX_BACKOFF`` class property in favor of ``Retry.DEFAULT_MAX_BACKOFF`` + to better match the rest of the default parameter names. ``Retry.MAX_BACKOFF`` is removed in v2.0. +* Changed location of the vendored ``ssl.match_hostname`` function from ``urllib3.packages.ssl_match_hostname`` + to ``urllib3.util.ssl_match_hostname`` to ensure Python 3.10+ compatibility after being repackaged + by downstream distributors. +* Fixed absolute imports, all imports are now relative. + + +1.26.7 (2021-09-22) +------------------- + +* Fixed a bug with HTTPS hostname verification involving IP addresses and lack + of SNI. (Issue #2400) +* Fixed a bug where IPv6 braces weren't stripped during certificate hostname + matching. (Issue #2240) + + +1.26.6 (2021-06-25) +------------------- + +* Deprecated the ``urllib3.contrib.ntlmpool`` module. urllib3 is not able to support + it properly due to `reasons listed in this issue `_. + If you are a user of this module please leave a comment. +* Changed ``HTTPConnection.request_chunked()`` to not erroneously emit multiple + ``Transfer-Encoding`` headers in the case that one is already specified. +* Fixed typo in deprecation message to recommend ``Retry.DEFAULT_ALLOWED_METHODS``. + + +1.26.5 (2021-05-26) +------------------- + +* Fixed deprecation warnings emitted in Python 3.10. +* Updated vendored ``six`` library to 1.16.0. +* Improved performance of URL parser when splitting + the authority component. + + +1.26.4 (2021-03-15) +------------------- + +* Changed behavior of the default ``SSLContext`` when connecting to HTTPS proxy + during HTTPS requests. The default ``SSLContext`` now sets ``check_hostname=True``. + + +1.26.3 (2021-01-26) +------------------- + +* Fixed bytes and string comparison issue with headers (Pull #2141) + +* Changed ``ProxySchemeUnknown`` error message to be + more actionable if the user supplies a proxy URL without + a scheme. (Pull #2107) + + +1.26.2 (2020-11-12) +------------------- + +* Fixed an issue where ``wrap_socket`` and ``CERT_REQUIRED`` wouldn't + be imported properly on Python 2.7.8 and earlier (Pull #2052) + + +1.26.1 (2020-11-11) +------------------- + +* Fixed an issue where two ``User-Agent`` headers would be sent if a + ``User-Agent`` header key is passed as ``bytes`` (Pull #2047) + + +1.26.0 (2020-11-10) +------------------- + +* **NOTE: urllib3 v2.0 will drop support for Python 2**. + `Read more in the v2.0 Roadmap `_. + +* Added support for HTTPS proxies contacting HTTPS servers (Pull #1923, Pull #1806) + +* Deprecated negotiating TLSv1 and TLSv1.1 by default. Users that + still wish to use TLS earlier than 1.2 without a deprecation warning + should opt-in explicitly by setting ``ssl_version=ssl.PROTOCOL_TLSv1_1`` (Pull #2002) + **Starting in urllib3 v2.0: Connections that receive a ``DeprecationWarning`` will fail** + +* Deprecated ``Retry`` options ``Retry.DEFAULT_METHOD_WHITELIST``, ``Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST`` + and ``Retry(method_whitelist=...)`` in favor of ``Retry.DEFAULT_ALLOWED_METHODS``, + ``Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT``, and ``Retry(allowed_methods=...)`` + (Pull #2000) **Starting in urllib3 v2.0: Deprecated options will be removed** + +* Added default ``User-Agent`` header to every request (Pull #1750) + +* Added ``urllib3.util.SKIP_HEADER`` for skipping ``User-Agent``, ``Accept-Encoding``, + and ``Host`` headers from being automatically emitted with requests (Pull #2018) + +* Collapse ``transfer-encoding: chunked`` request data and framing into + the same ``socket.send()`` call (Pull #1906) + +* Send ``http/1.1`` ALPN identifier with every TLS handshake by default (Pull #1894) + +* Properly terminate SecureTransport connections when CA verification fails (Pull #1977) + +* Don't emit an ``SNIMissingWarning`` when passing ``server_hostname=None`` + to SecureTransport (Pull #1903) + +* Disabled requesting TLSv1.2 session tickets as they weren't being used by urllib3 (Pull #1970) + +* Suppress ``BrokenPipeError`` when writing request body after the server + has closed the socket (Pull #1524) + +* Wrap ``ssl.SSLError`` that can be raised from reading a socket (e.g. "bad MAC") + into an ``urllib3.exceptions.SSLError`` (Pull #1939) + + +1.25.11 (2020-10-19) +-------------------- + +* Fix retry backoff time parsed from ``Retry-After`` header when given + in the HTTP date format. The HTTP date was parsed as the local timezone + rather than accounting for the timezone in the HTTP date (typically + UTC) (Pull #1932, Pull #1935, Pull #1938, Pull #1949) + +* Fix issue where an error would be raised when the ``SSLKEYLOGFILE`` + environment variable was set to the empty string. Now ``SSLContext.keylog_file`` + is not set in this situation (Pull #2016) + + +1.25.10 (2020-07-22) +-------------------- + +* Added support for ``SSLKEYLOGFILE`` environment variable for + logging TLS session keys with use with programs like + Wireshark for decrypting captured web traffic (Pull #1867) + +* Fixed loading of SecureTransport libraries on macOS Big Sur + due to the new dynamic linker cache (Pull #1905) + +* Collapse chunked request bodies data and framing into one + call to ``send()`` to reduce the number of TCP packets by 2-4x (Pull #1906) + +* Don't insert ``None`` into ``ConnectionPool`` if the pool + was empty when requesting a connection (Pull #1866) + +* Avoid ``hasattr`` call in ``BrotliDecoder.decompress()`` (Pull #1858) + + +1.25.9 (2020-04-16) +------------------- + +* Added ``InvalidProxyConfigurationWarning`` which is raised when + erroneously specifying an HTTPS proxy URL. urllib3 doesn't currently + support connecting to HTTPS proxies but will soon be able to + and we would like users to migrate properly without much breakage. + + See `this GitHub issue `_ + for more information on how to fix your proxy config. (Pull #1851) + +* Drain connection after ``PoolManager`` redirect (Pull #1817) + +* Ensure ``load_verify_locations`` raises ``SSLError`` for all backends (Pull #1812) + +* Rename ``VerifiedHTTPSConnection`` to ``HTTPSConnection`` (Pull #1805) + +* Allow the CA certificate data to be passed as a string (Pull #1804) + +* Raise ``ValueError`` if method contains control characters (Pull #1800) + +* Add ``__repr__`` to ``Timeout`` (Pull #1795) + + +1.25.8 (2020-01-20) +------------------- + +* Drop support for EOL Python 3.4 (Pull #1774) + +* Optimize _encode_invalid_chars (Pull #1787) + + +1.25.7 (2019-11-11) +------------------- + +* Preserve ``chunked`` parameter on retries (Pull #1715, Pull #1734) + +* Allow unset ``SERVER_SOFTWARE`` in App Engine (Pull #1704, Issue #1470) + +* Fix issue where URL fragment was sent within the request target. (Pull #1732) + +* Fix issue where an empty query section in a URL would fail to parse. (Pull #1732) + +* Remove TLS 1.3 support in SecureTransport due to Apple removing support (Pull #1703) + + +1.25.6 (2019-09-24) +------------------- + +* Fix issue where tilde (``~``) characters were incorrectly + percent-encoded in the path. (Pull #1692) + + +1.25.5 (2019-09-19) +------------------- + +* Add mitigation for BPO-37428 affecting Python <3.7.4 and OpenSSL 1.1.1+ which + caused certificate verification to be enabled when using ``cert_reqs=CERT_NONE``. + (Issue #1682) + + +1.25.4 (2019-09-19) +------------------- + +* Propagate Retry-After header settings to subsequent retries. (Pull #1607) + +* Fix edge case where Retry-After header was still respected even when + explicitly opted out of. (Pull #1607) + +* Remove dependency on ``rfc3986`` for URL parsing. + +* Fix issue where URLs containing invalid characters within ``Url.auth`` would + raise an exception instead of percent-encoding those characters. + +* Add support for ``HTTPResponse.auto_close = False`` which makes HTTP responses + work well with BufferedReaders and other ``io`` module features. (Pull #1652) + +* Percent-encode invalid characters in URL for ``HTTPConnectionPool.request()`` (Pull #1673) + + +1.25.3 (2019-05-23) +------------------- + +* Change ``HTTPSConnection`` to load system CA certificates + when ``ca_certs``, ``ca_cert_dir``, and ``ssl_context`` are + unspecified. (Pull #1608, Issue #1603) + +* Upgrade bundled rfc3986 to v1.3.2. (Pull #1609, Issue #1605) + + +1.25.2 (2019-04-28) +------------------- + +* Change ``is_ipaddress`` to not detect IPvFuture addresses. (Pull #1583) + +* Change ``parse_url`` to percent-encode invalid characters within the + path, query, and target components. (Pull #1586) + + +1.25.1 (2019-04-24) +------------------- + +* Add support for Google's ``Brotli`` package. (Pull #1572, Pull #1579) + +* Upgrade bundled rfc3986 to v1.3.1 (Pull #1578) + + +1.25 (2019-04-22) +----------------- + +* Require and validate certificates by default when using HTTPS (Pull #1507) + +* Upgraded ``urllib3.utils.parse_url()`` to be RFC 3986 compliant. (Pull #1487) + +* Added support for ``key_password`` for ``HTTPSConnectionPool`` to use + encrypted ``key_file`` without creating your own ``SSLContext`` object. (Pull #1489) + +* Add TLSv1.3 support to CPython, pyOpenSSL, and SecureTransport ``SSLContext`` + implementations. (Pull #1496) + +* Switched the default multipart header encoder from RFC 2231 to HTML 5 working draft. (Issue #303, Pull #1492) + +* Fixed issue where OpenSSL would block if an encrypted client private key was + given and no password was given. Instead an ``SSLError`` is raised. (Pull #1489) + +* Added support for Brotli content encoding. It is enabled automatically if + ``brotlipy`` package is installed which can be requested with + ``urllib3[brotli]`` extra. (Pull #1532) + +* Drop ciphers using DSS key exchange from default TLS cipher suites. + Improve default ciphers when using SecureTransport. (Pull #1496) + +* Implemented a more efficient ``HTTPResponse.__iter__()`` method. (Issue #1483) + +1.24.3 (2019-05-01) +------------------- + +* Apply fix for CVE-2019-9740. (Pull #1591) + +1.24.2 (2019-04-17) +------------------- + +* Don't load system certificates by default when any other ``ca_certs``, ``ca_certs_dir`` or + ``ssl_context`` parameters are specified. + +* Remove Authorization header regardless of case when redirecting to cross-site. (Issue #1510) + +* Add support for IPv6 addresses in subjectAltName section of certificates. (Issue #1269) + + +1.24.1 (2018-11-02) +------------------- + +* Remove quadratic behavior within ``GzipDecoder.decompress()`` (Issue #1467) + +* Restored functionality of ``ciphers`` parameter for ``create_urllib3_context()``. (Issue #1462) + + +1.24 (2018-10-16) +----------------- + +* Allow key_server_hostname to be specified when initializing a PoolManager to allow custom SNI to be overridden. (Pull #1449) + +* Test against Python 3.7 on AppVeyor. (Pull #1453) + +* Early-out ipv6 checks when running on App Engine. (Pull #1450) + +* Change ambiguous description of backoff_factor (Pull #1436) + +* Add ability to handle multiple Content-Encodings (Issue #1441 and Pull #1442) + +* Skip DNS names that can't be idna-decoded when using pyOpenSSL (Issue #1405). + +* Add a server_hostname parameter to HTTPSConnection which allows for + overriding the SNI hostname sent in the handshake. (Pull #1397) + +* Drop support for EOL Python 2.6 (Pull #1429 and Pull #1430) + +* Fixed bug where responses with header Content-Type: message/* erroneously + raised HeaderParsingError, resulting in a warning being logged. (Pull #1439) + +* Move urllib3 to src/urllib3 (Pull #1409) + + +1.23 (2018-06-04) +----------------- + +* Allow providing a list of headers to strip from requests when redirecting + to a different host. Defaults to the ``Authorization`` header. Different + headers can be set via ``Retry.remove_headers_on_redirect``. (Issue #1316) + +* Fix ``util.selectors._fileobj_to_fd`` to accept ``long`` (Issue #1247). + +* Dropped Python 3.3 support. (Pull #1242) + +* Put the connection back in the pool when calling stream() or read_chunked() on + a chunked HEAD response. (Issue #1234) + +* Fixed pyOpenSSL-specific ssl client authentication issue when clients + attempted to auth via certificate + chain (Issue #1060) + +* Add the port to the connectionpool connect print (Pull #1251) + +* Don't use the ``uuid`` module to create multipart data boundaries. (Pull #1380) + +* ``read_chunked()`` on a closed response returns no chunks. (Issue #1088) + +* Add Python 2.6 support to ``contrib.securetransport`` (Pull #1359) + +* Added support for auth info in url for SOCKS proxy (Pull #1363) + + +1.22 (2017-07-20) +----------------- + +* Fixed missing brackets in ``HTTP CONNECT`` when connecting to IPv6 address via + IPv6 proxy. (Issue #1222) + +* Made the connection pool retry on ``SSLError``. The original ``SSLError`` + is available on ``MaxRetryError.reason``. (Issue #1112) + +* Drain and release connection before recursing on retry/redirect. Fixes + deadlocks with a blocking connectionpool. (Issue #1167) + +* Fixed compatibility for cookiejar. (Issue #1229) + +* pyopenssl: Use vendored version of ``six``. (Issue #1231) + + +1.21.1 (2017-05-02) +------------------- + +* Fixed SecureTransport issue that would cause long delays in response body + delivery. (Pull #1154) + +* Fixed regression in 1.21 that threw exceptions when users passed the + ``socket_options`` flag to the ``PoolManager``. (Issue #1165) + +* Fixed regression in 1.21 that threw exceptions when users passed the + ``assert_hostname`` or ``assert_fingerprint`` flag to the ``PoolManager``. + (Pull #1157) + + +1.21 (2017-04-25) +----------------- + +* Improved performance of certain selector system calls on Python 3.5 and + later. (Pull #1095) + +* Resolved issue where the PyOpenSSL backend would not wrap SysCallError + exceptions appropriately when sending data. (Pull #1125) + +* Selectors now detects a monkey-patched select module after import for modules + that patch the select module like eventlet, greenlet. (Pull #1128) + +* Reduced memory consumption when streaming zlib-compressed responses + (as opposed to raw deflate streams). (Pull #1129) + +* Connection pools now use the entire request context when constructing the + pool key. (Pull #1016) + +* ``PoolManager.connection_from_*`` methods now accept a new keyword argument, + ``pool_kwargs``, which are merged with the existing ``connection_pool_kw``. + (Pull #1016) + +* Add retry counter for ``status_forcelist``. (Issue #1147) + +* Added ``contrib`` module for using SecureTransport on macOS: + ``urllib3.contrib.securetransport``. (Pull #1122) + +* urllib3 now only normalizes the case of ``http://`` and ``https://`` schemes: + for schemes it does not recognise, it assumes they are case-sensitive and + leaves them unchanged. + (Issue #1080) + + +1.20 (2017-01-19) +----------------- + +* Added support for waiting for I/O using selectors other than select, + improving urllib3's behaviour with large numbers of concurrent connections. + (Pull #1001) + +* Updated the date for the system clock check. (Issue #1005) + +* ConnectionPools now correctly consider hostnames to be case-insensitive. + (Issue #1032) + +* Outdated versions of PyOpenSSL now cause the PyOpenSSL contrib module + to fail when it is injected, rather than at first use. (Pull #1063) + +* Outdated versions of cryptography now cause the PyOpenSSL contrib module + to fail when it is injected, rather than at first use. (Issue #1044) + +* Automatically attempt to rewind a file-like body object when a request is + retried or redirected. (Pull #1039) + +* Fix some bugs that occur when modules incautiously patch the queue module. + (Pull #1061) + +* Prevent retries from occurring on read timeouts for which the request method + was not in the method whitelist. (Issue #1059) + +* Changed the PyOpenSSL contrib module to lazily load idna to avoid + unnecessarily bloating the memory of programs that don't need it. (Pull + #1076) + +* Add support for IPv6 literals with zone identifiers. (Pull #1013) + +* Added support for socks5h:// and socks4a:// schemes when working with SOCKS + proxies, and controlled remote DNS appropriately. (Issue #1035) + + +1.19.1 (2016-11-16) +------------------- + +* Fixed AppEngine import that didn't function on Python 3.5. (Pull #1025) + + +1.19 (2016-11-03) +----------------- + +* urllib3 now respects Retry-After headers on 413, 429, and 503 responses when + using the default retry logic. (Pull #955) + +* Remove markers from setup.py to assist ancient setuptools versions. (Issue + #986) + +* Disallow superscripts and other integerish things in URL ports. (Issue #989) + +* Allow urllib3's HTTPResponse.stream() method to continue to work with + non-httplib underlying FPs. (Pull #990) + +* Empty filenames in multipart headers are now emitted as such, rather than + being suppressed. (Issue #1015) + +* Prefer user-supplied Host headers on chunked uploads. (Issue #1009) + + +1.18.1 (2016-10-27) +------------------- + +* CVE-2016-9015. Users who are using urllib3 version 1.17 or 1.18 along with + PyOpenSSL injection and OpenSSL 1.1.0 *must* upgrade to this version. This + release fixes a vulnerability whereby urllib3 in the above configuration + would silently fail to validate TLS certificates due to erroneously setting + invalid flags in OpenSSL's ``SSL_CTX_set_verify`` function. These erroneous + flags do not cause a problem in OpenSSL versions before 1.1.0, which + interprets the presence of any flag as requesting certificate validation. + + There is no PR for this patch, as it was prepared for simultaneous disclosure + and release. The master branch received the same fix in Pull #1010. + + +1.18 (2016-09-26) +----------------- + +* Fixed incorrect message for IncompleteRead exception. (Pull #973) + +* Accept ``iPAddress`` subject alternative name fields in TLS certificates. + (Issue #258) + +* Fixed consistency of ``HTTPResponse.closed`` between Python 2 and 3. + (Issue #977) + +* Fixed handling of wildcard certificates when using PyOpenSSL. (Issue #979) + + +1.17 (2016-09-06) +----------------- + +* Accept ``SSLContext`` objects for use in SSL/TLS negotiation. (Issue #835) + +* ConnectionPool debug log now includes scheme, host, and port. (Issue #897) + +* Substantially refactored documentation. (Issue #887) + +* Used URLFetch default timeout on AppEngine, rather than hardcoding our own. + (Issue #858) + +* Normalize the scheme and host in the URL parser (Issue #833) + +* ``HTTPResponse`` contains the last ``Retry`` object, which now also + contains retries history. (Issue #848) + +* Timeout can no longer be set as boolean, and must be greater than zero. + (Pull #924) + +* Removed pyasn1 and ndg-httpsclient from dependencies used for PyOpenSSL. We + now use cryptography and idna, both of which are already dependencies of + PyOpenSSL. (Pull #930) + +* Fixed infinite loop in ``stream`` when amt=None. (Issue #928) + +* Try to use the operating system's certificates when we are using an + ``SSLContext``. (Pull #941) + +* Updated cipher suite list to allow ChaCha20+Poly1305. AES-GCM is preferred to + ChaCha20, but ChaCha20 is then preferred to everything else. (Pull #947) + +* Updated cipher suite list to remove 3DES-based cipher suites. (Pull #958) + +* Removed the cipher suite fallback to allow HIGH ciphers. (Pull #958) + +* Implemented ``length_remaining`` to determine remaining content + to be read. (Pull #949) + +* Implemented ``enforce_content_length`` to enable exceptions when + incomplete data chunks are received. (Pull #949) + +* Dropped connection start, dropped connection reset, redirect, forced retry, + and new HTTPS connection log levels to DEBUG, from INFO. (Pull #967) + + +1.16 (2016-06-11) +----------------- + +* Disable IPv6 DNS when IPv6 connections are not possible. (Issue #840) + +* Provide ``key_fn_by_scheme`` pool keying mechanism that can be + overridden. (Issue #830) + +* Normalize scheme and host to lowercase for pool keys, and include + ``source_address``. (Issue #830) + +* Cleaner exception chain in Python 3 for ``_make_request``. + (Issue #861) + +* Fixed installing ``urllib3[socks]`` extra. (Issue #864) + +* Fixed signature of ``ConnectionPool.close`` so it can actually safely be + called by subclasses. (Issue #873) + +* Retain ``release_conn`` state across retries. (Issues #651, #866) + +* Add customizable ``HTTPConnectionPool.ResponseCls``, which defaults to + ``HTTPResponse`` but can be replaced with a subclass. (Issue #879) + + +1.15.1 (2016-04-11) +------------------- + +* Fix packaging to include backports module. (Issue #841) + + +1.15 (2016-04-06) +----------------- + +* Added Retry(raise_on_status=False). (Issue #720) + +* Always use setuptools, no more distutils fallback. (Issue #785) + +* Dropped support for Python 3.2. (Issue #786) + +* Chunked transfer encoding when requesting with ``chunked=True``. + (Issue #790) + +* Fixed regression with IPv6 port parsing. (Issue #801) + +* Append SNIMissingWarning messages to allow users to specify it in + the PYTHONWARNINGS environment variable. (Issue #816) + +* Handle unicode headers in Py2. (Issue #818) + +* Log certificate when there is a hostname mismatch. (Issue #820) + +* Preserve order of request/response headers. (Issue #821) + + +1.14 (2015-12-29) +----------------- + +* contrib: SOCKS proxy support! (Issue #762) + +* Fixed AppEngine handling of transfer-encoding header and bug + in Timeout defaults checking. (Issue #763) + + +1.13.1 (2015-12-18) +------------------- + +* Fixed regression in IPv6 + SSL for match_hostname. (Issue #761) + + +1.13 (2015-12-14) +----------------- + +* Fixed ``pip install urllib3[secure]`` on modern pip. (Issue #706) + +* pyopenssl: Fixed SSL3_WRITE_PENDING error. (Issue #717) + +* pyopenssl: Support for TLSv1.1 and TLSv1.2. (Issue #696) + +* Close connections more defensively on exception. (Issue #734) + +* Adjusted ``read_chunked`` to handle gzipped, chunk-encoded bodies without + repeatedly flushing the decoder, to function better on Jython. (Issue #743) + +* Accept ``ca_cert_dir`` for SSL-related PoolManager configuration. (Issue #758) + + +1.12 (2015-09-03) +----------------- + +* Rely on ``six`` for importing ``httplib`` to work around + conflicts with other Python 3 shims. (Issue #688) + +* Add support for directories of certificate authorities, as supported by + OpenSSL. (Issue #701) + +* New exception: ``NewConnectionError``, raised when we fail to establish + a new connection, usually ``ECONNREFUSED`` socket error. + + +1.11 (2015-07-21) +----------------- + +* When ``ca_certs`` is given, ``cert_reqs`` defaults to + ``'CERT_REQUIRED'``. (Issue #650) + +* ``pip install urllib3[secure]`` will install Certifi and + PyOpenSSL as dependencies. (Issue #678) + +* Made ``HTTPHeaderDict`` usable as a ``headers`` input value + (Issues #632, #679) + +* Added `urllib3.contrib.appengine `_ + which has an ``AppEngineManager`` for using ``URLFetch`` in a + Google AppEngine environment. (Issue #664) + +* Dev: Added test suite for AppEngine. (Issue #631) + +* Fix performance regression when using PyOpenSSL. (Issue #626) + +* Passing incorrect scheme (e.g. ``foo://``) will raise + ``ValueError`` instead of ``AssertionError`` (backwards + compatible for now, but please migrate). (Issue #640) + +* Fix pools not getting replenished when an error occurs during a + request using ``release_conn=False``. (Issue #644) + +* Fix pool-default headers not applying for url-encoded requests + like GET. (Issue #657) + +* log.warning in Python 3 when headers are skipped due to parsing + errors. (Issue #642) + +* Close and discard connections if an error occurs during read. + (Issue #660) + +* Fix host parsing for IPv6 proxies. (Issue #668) + +* Separate warning type SubjectAltNameWarning, now issued once + per host. (Issue #671) + +* Fix ``httplib.IncompleteRead`` not getting converted to + ``ProtocolError`` when using ``HTTPResponse.stream()`` + (Issue #674) + +1.10.4 (2015-05-03) +------------------- + +* Migrate tests to Tornado 4. (Issue #594) + +* Append default warning configuration rather than overwrite. + (Issue #603) + +* Fix streaming decoding regression. (Issue #595) + +* Fix chunked requests losing state across keep-alive connections. + (Issue #599) + +* Fix hanging when chunked HEAD response has no body. (Issue #605) + + +1.10.3 (2015-04-21) +------------------- + +* Emit ``InsecurePlatformWarning`` when SSLContext object is missing. + (Issue #558) + +* Fix regression of duplicate header keys being discarded. + (Issue #563) + +* ``Response.stream()`` returns a generator for chunked responses. + (Issue #560) + +* Set upper-bound timeout when waiting for a socket in PyOpenSSL. + (Issue #585) + +* Work on platforms without `ssl` module for plain HTTP requests. + (Issue #587) + +* Stop relying on the stdlib's default cipher list. (Issue #588) + + +1.10.2 (2015-02-25) +------------------- + +* Fix file descriptor leakage on retries. (Issue #548) + +* Removed RC4 from default cipher list. (Issue #551) + +* Header performance improvements. (Issue #544) + +* Fix PoolManager not obeying redirect retry settings. (Issue #553) + + +1.10.1 (2015-02-10) +------------------- + +* Pools can be used as context managers. (Issue #545) + +* Don't re-use connections which experienced an SSLError. (Issue #529) + +* Don't fail when gzip decoding an empty stream. (Issue #535) + +* Add sha256 support for fingerprint verification. (Issue #540) + +* Fixed handling of header values containing commas. (Issue #533) + + +1.10 (2014-12-14) +----------------- + +* Disabled SSLv3. (Issue #473) + +* Add ``Url.url`` property to return the composed url string. (Issue #394) + +* Fixed PyOpenSSL + gevent ``WantWriteError``. (Issue #412) + +* ``MaxRetryError.reason`` will always be an exception, not string. + (Issue #481) + +* Fixed SSL-related timeouts not being detected as timeouts. (Issue #492) + +* Py3: Use ``ssl.create_default_context()`` when available. (Issue #473) + +* Emit ``InsecureRequestWarning`` for *every* insecure HTTPS request. + (Issue #496) + +* Emit ``SecurityWarning`` when certificate has no ``subjectAltName``. + (Issue #499) + +* Close and discard sockets which experienced SSL-related errors. + (Issue #501) + +* Handle ``body`` param in ``.request(...)``. (Issue #513) + +* Respect timeout with HTTPS proxy. (Issue #505) + +* PyOpenSSL: Handle ZeroReturnError exception. (Issue #520) + + +1.9.1 (2014-09-13) +------------------ + +* Apply socket arguments before binding. (Issue #427) + +* More careful checks if fp-like object is closed. (Issue #435) + +* Fixed packaging issues of some development-related files not + getting included. (Issue #440) + +* Allow performing *only* fingerprint verification. (Issue #444) + +* Emit ``SecurityWarning`` if system clock is waaay off. (Issue #445) + +* Fixed PyOpenSSL compatibility with PyPy. (Issue #450) + +* Fixed ``BrokenPipeError`` and ``ConnectionError`` handling in Py3. + (Issue #443) + + + +1.9 (2014-07-04) +---------------- + +* Shuffled around development-related files. If you're maintaining a distro + package of urllib3, you may need to tweak things. (Issue #415) + +* Unverified HTTPS requests will trigger a warning on the first request. See + our new `security documentation + `_ for details. + (Issue #426) + +* New retry logic and ``urllib3.util.retry.Retry`` configuration object. + (Issue #326) + +* All raised exceptions should now wrapped in a + ``urllib3.exceptions.HTTPException``-extending exception. (Issue #326) + +* All errors during a retry-enabled request should be wrapped in + ``urllib3.exceptions.MaxRetryError``, including timeout-related exceptions + which were previously exempt. Underlying error is accessible from the + ``.reason`` property. (Issue #326) + +* ``urllib3.exceptions.ConnectionError`` renamed to + ``urllib3.exceptions.ProtocolError``. (Issue #326) + +* Errors during response read (such as IncompleteRead) are now wrapped in + ``urllib3.exceptions.ProtocolError``. (Issue #418) + +* Requesting an empty host will raise ``urllib3.exceptions.LocationValueError``. + (Issue #417) + +* Catch read timeouts over SSL connections as + ``urllib3.exceptions.ReadTimeoutError``. (Issue #419) + +* Apply socket arguments before connecting. (Issue #427) + + +1.8.3 (2014-06-23) +------------------ + +* Fix TLS verification when using a proxy in Python 3.4.1. (Issue #385) + +* Add ``disable_cache`` option to ``urllib3.util.make_headers``. (Issue #393) + +* Wrap ``socket.timeout`` exception with + ``urllib3.exceptions.ReadTimeoutError``. (Issue #399) + +* Fixed proxy-related bug where connections were being reused incorrectly. + (Issues #366, #369) + +* Added ``socket_options`` keyword parameter which allows to define + ``setsockopt`` configuration of new sockets. (Issue #397) + +* Removed ``HTTPConnection.tcp_nodelay`` in favor of + ``HTTPConnection.default_socket_options``. (Issue #397) + +* Fixed ``TypeError`` bug in Python 2.6.4. (Issue #411) + + +1.8.2 (2014-04-17) +------------------ + +* Fix ``urllib3.util`` not being included in the package. + + +1.8.1 (2014-04-17) +------------------ + +* Fix AppEngine bug of HTTPS requests going out as HTTP. (Issue #356) + +* Don't install ``dummyserver`` into ``site-packages`` as it's only needed + for the test suite. (Issue #362) + +* Added support for specifying ``source_address``. (Issue #352) + + +1.8 (2014-03-04) +---------------- + +* Improved url parsing in ``urllib3.util.parse_url`` (properly parse '@' in + username, and blank ports like 'hostname:'). + +* New ``urllib3.connection`` module which contains all the HTTPConnection + objects. + +* Several ``urllib3.util.Timeout``-related fixes. Also changed constructor + signature to a more sensible order. [Backwards incompatible] + (Issues #252, #262, #263) + +* Use ``backports.ssl_match_hostname`` if it's installed. (Issue #274) + +* Added ``.tell()`` method to ``urllib3.response.HTTPResponse`` which + returns the number of bytes read so far. (Issue #277) + +* Support for platforms without threading. (Issue #289) + +* Expand default-port comparison in ``HTTPConnectionPool.is_same_host`` + to allow a pool with no specified port to be considered equal to to an + HTTP/HTTPS url with port 80/443 explicitly provided. (Issue #305) + +* Improved default SSL/TLS settings to avoid vulnerabilities. + (Issue #309) + +* Fixed ``urllib3.poolmanager.ProxyManager`` not retrying on connect errors. + (Issue #310) + +* Disable Nagle's Algorithm on the socket for non-proxies. A subset of requests + will send the entire HTTP request ~200 milliseconds faster; however, some of + the resulting TCP packets will be smaller. (Issue #254) + +* Increased maximum number of SubjectAltNames in ``urllib3.contrib.pyopenssl`` + from the default 64 to 1024 in a single certificate. (Issue #318) + +* Headers are now passed and stored as a custom + ``urllib3.collections_.HTTPHeaderDict`` object rather than a plain ``dict``. + (Issue #329, #333) + +* Headers no longer lose their case on Python 3. (Issue #236) + +* ``urllib3.contrib.pyopenssl`` now uses the operating system's default CA + certificates on inject. (Issue #332) + +* Requests with ``retries=False`` will immediately raise any exceptions without + wrapping them in ``MaxRetryError``. (Issue #348) + +* Fixed open socket leak with SSL-related failures. (Issue #344, #348) + + +1.7.1 (2013-09-25) +------------------ + +* Added granular timeout support with new ``urllib3.util.Timeout`` class. + (Issue #231) + +* Fixed Python 3.4 support. (Issue #238) + + +1.7 (2013-08-14) +---------------- + +* More exceptions are now pickle-able, with tests. (Issue #174) + +* Fixed redirecting with relative URLs in Location header. (Issue #178) + +* Support for relative urls in ``Location: ...`` header. (Issue #179) + +* ``urllib3.response.HTTPResponse`` now inherits from ``io.IOBase`` for bonus + file-like functionality. (Issue #187) + +* Passing ``assert_hostname=False`` when creating a HTTPSConnectionPool will + skip hostname verification for SSL connections. (Issue #194) + +* New method ``urllib3.response.HTTPResponse.stream(...)`` which acts as a + generator wrapped around ``.read(...)``. (Issue #198) + +* IPv6 url parsing enforces brackets around the hostname. (Issue #199) + +* Fixed thread race condition in + ``urllib3.poolmanager.PoolManager.connection_from_host(...)`` (Issue #204) + +* ``ProxyManager`` requests now include non-default port in ``Host: ...`` + header. (Issue #217) + +* Added HTTPS proxy support in ``ProxyManager``. (Issue #170 #139) + +* New ``RequestField`` object can be passed to the ``fields=...`` param which + can specify headers. (Issue #220) + +* Raise ``urllib3.exceptions.ProxyError`` when connecting to proxy fails. + (Issue #221) + +* Use international headers when posting file names. (Issue #119) + +* Improved IPv6 support. (Issue #203) + + +1.6 (2013-04-25) +---------------- + +* Contrib: Optional SNI support for Py2 using PyOpenSSL. (Issue #156) + +* ``ProxyManager`` automatically adds ``Host: ...`` header if not given. + +* Improved SSL-related code. ``cert_req`` now optionally takes a string like + "REQUIRED" or "NONE". Same with ``ssl_version`` takes strings like "SSLv23" + The string values reflect the suffix of the respective constant variable. + (Issue #130) + +* Vendored ``socksipy`` now based on Anorov's fork which handles unexpectedly + closed proxy connections and larger read buffers. (Issue #135) + +* Ensure the connection is closed if no data is received, fixes connection leak + on some platforms. (Issue #133) + +* Added SNI support for SSL/TLS connections on Py32+. (Issue #89) + +* Tests fixed to be compatible with Py26 again. (Issue #125) + +* Added ability to choose SSL version by passing an ``ssl.PROTOCOL_*`` constant + to the ``ssl_version`` parameter of ``HTTPSConnectionPool``. (Issue #109) + +* Allow an explicit content type to be specified when encoding file fields. + (Issue #126) + +* Exceptions are now pickleable, with tests. (Issue #101) + +* Fixed default headers not getting passed in some cases. (Issue #99) + +* Treat "content-encoding" header value as case-insensitive, per RFC 2616 + Section 3.5. (Issue #110) + +* "Connection Refused" SocketErrors will get retried rather than raised. + (Issue #92) + +* Updated vendored ``six``, no longer overrides the global ``six`` module + namespace. (Issue #113) + +* ``urllib3.exceptions.MaxRetryError`` contains a ``reason`` property holding + the exception that prompted the final retry. If ``reason is None`` then it + was due to a redirect. (Issue #92, #114) + +* Fixed ``PoolManager.urlopen()`` from not redirecting more than once. + (Issue #149) + +* Don't assume ``Content-Type: text/plain`` for multi-part encoding parameters + that are not files. (Issue #111) + +* Pass `strict` param down to ``httplib.HTTPConnection``. (Issue #122) + +* Added mechanism to verify SSL certificates by fingerprint (md5, sha1) or + against an arbitrary hostname (when connecting by IP or for misconfigured + servers). (Issue #140) + +* Streaming decompression support. (Issue #159) + + +1.5 (2012-08-02) +---------------- + +* Added ``urllib3.add_stderr_logger()`` for quickly enabling STDERR debug + logging in urllib3. + +* Native full URL parsing (including auth, path, query, fragment) available in + ``urllib3.util.parse_url(url)``. + +* Built-in redirect will switch method to 'GET' if status code is 303. + (Issue #11) + +* ``urllib3.PoolManager`` strips the scheme and host before sending the request + uri. (Issue #8) + +* New ``urllib3.exceptions.DecodeError`` exception for when automatic decoding, + based on the Content-Type header, fails. + +* Fixed bug with pool depletion and leaking connections (Issue #76). Added + explicit connection closing on pool eviction. Added + ``urllib3.PoolManager.clear()``. + +* 99% -> 100% unit test coverage. + + +1.4 (2012-06-16) +---------------- + +* Minor AppEngine-related fixes. + +* Switched from ``mimetools.choose_boundary`` to ``uuid.uuid4()``. + +* Improved url parsing. (Issue #73) + +* IPv6 url support. (Issue #72) + + +1.3 (2012-03-25) +---------------- + +* Removed pre-1.0 deprecated API. + +* Refactored helpers into a ``urllib3.util`` submodule. + +* Fixed multipart encoding to support list-of-tuples for keys with multiple + values. (Issue #48) + +* Fixed multiple Set-Cookie headers in response not getting merged properly in + Python 3. (Issue #53) + +* AppEngine support with Py27. (Issue #61) + +* Minor ``encode_multipart_formdata`` fixes related to Python 3 strings vs + bytes. + + +1.2.2 (2012-02-06) +------------------ + +* Fixed packaging bug of not shipping ``test-requirements.txt``. (Issue #47) + + +1.2.1 (2012-02-05) +------------------ + +* Fixed another bug related to when ``ssl`` module is not available. (Issue #41) + +* Location parsing errors now raise ``urllib3.exceptions.LocationParseError`` + which inherits from ``ValueError``. + + +1.2 (2012-01-29) +---------------- + +* Added Python 3 support (tested on 3.2.2) + +* Dropped Python 2.5 support (tested on 2.6.7, 2.7.2) + +* Use ``select.poll`` instead of ``select.select`` for platforms that support + it. + +* Use ``Queue.LifoQueue`` instead of ``Queue.Queue`` for more aggressive + connection reusing. Configurable by overriding ``ConnectionPool.QueueCls``. + +* Fixed ``ImportError`` during install when ``ssl`` module is not available. + (Issue #41) + +* Fixed ``PoolManager`` redirects between schemes (such as HTTP -> HTTPS) not + completing properly. (Issue #28, uncovered by Issue #10 in v1.1) + +* Ported ``dummyserver`` to use ``tornado`` instead of ``webob`` + + ``eventlet``. Removed extraneous unsupported dummyserver testing backends. + Added socket-level tests. + +* More tests. Achievement Unlocked: 99% Coverage. + + +1.1 (2012-01-07) +---------------- + +* Refactored ``dummyserver`` to its own root namespace module (used for + testing). + +* Added hostname verification for ``VerifiedHTTPSConnection`` by vendoring in + Py32's ``ssl_match_hostname``. (Issue #25) + +* Fixed cross-host HTTP redirects when using ``PoolManager``. (Issue #10) + +* Fixed ``decode_content`` being ignored when set through ``urlopen``. (Issue + #27) + +* Fixed timeout-related bugs. (Issues #17, #23) + + +1.0.2 (2011-11-04) +------------------ + +* Fixed typo in ``VerifiedHTTPSConnection`` which would only present as a bug if + you're using the object manually. (Thanks pyos) + +* Made RecentlyUsedContainer (and consequently PoolManager) more thread-safe by + wrapping the access log in a mutex. (Thanks @christer) + +* Made RecentlyUsedContainer more dict-like (corrected ``__delitem__`` and + ``__getitem__`` behaviour), with tests. Shouldn't affect core urllib3 code. + + +1.0.1 (2011-10-10) +------------------ + +* Fixed a bug where the same connection would get returned into the pool twice, + causing extraneous "HttpConnectionPool is full" log warnings. + + +1.0 (2011-10-08) +---------------- + +* Added ``PoolManager`` with LRU expiration of connections (tested and + documented). +* Added ``ProxyManager`` (needs tests, docs, and confirmation that it works + with HTTPS proxies). +* Added optional partial-read support for responses when + ``preload_content=False``. You can now make requests and just read the headers + without loading the content. +* Made response decoding optional (default on, same as before). +* Added optional explicit boundary string for ``encode_multipart_formdata``. +* Convenience request methods are now inherited from ``RequestMethods``. Old + helpers like ``get_url`` and ``post_url`` should be abandoned in favour of + the new ``request(method, url, ...)``. +* Refactored code to be even more decoupled, reusable, and extendable. +* License header added to ``.py`` files. +* Embiggened the documentation: Lots of Sphinx-friendly docstrings in the code + and docs in ``docs/`` and on https://urllib3.readthedocs.io/. +* Embettered all the things! +* Started writing this file. + + +0.4.1 (2011-07-17) +------------------ + +* Minor bug fixes, code cleanup. + + +0.4 (2011-03-01) +---------------- + +* Better unicode support. +* Added ``VerifiedHTTPSConnection``. +* Added ``NTLMConnectionPool`` in contrib. +* Minor improvements. + + +0.3.1 (2010-07-13) +------------------ + +* Added ``assert_host_name`` optional parameter. Now compatible with proxies. + + +0.3 (2009-12-10) +---------------- + +* Added HTTPS support. +* Minor bug fixes. +* Refactored, broken backwards compatibility with 0.2. +* API to be treated as stable from this version forward. + + +0.2 (2008-11-17) +---------------- + +* Added unit tests. +* Bug fixes. + + +0.1 (2008-11-16) +---------------- + +* First release. diff --git a/lib/urllib3-1.26.19.dist-info/RECORD b/lib/urllib3-1.26.19.dist-info/RECORD new file mode 100644 index 0000000..8f7b80a --- /dev/null +++ b/lib/urllib3-1.26.19.dist-info/RECORD @@ -0,0 +1,84 @@ +urllib3-1.26.19.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +urllib3-1.26.19.dist-info/LICENSE.txt,sha256=w3vxhuJ8-dvpYZ5V7f486nswCRzrPaY8fay-Dm13kHs,1115 +urllib3-1.26.19.dist-info/METADATA,sha256=fN47QaPlzYaOHFTgs3BT3gWa8_y7CUMMBW8wX2qcKF0,49320 +urllib3-1.26.19.dist-info/RECORD,, +urllib3-1.26.19.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110 +urllib3-1.26.19.dist-info/top_level.txt,sha256=EMiXL2sKrTcmrMxIHTqdc3ET54pQI2Y072LexFEemvo,8 +urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333 +urllib3/__pycache__/__init__.cpython-312.pyc,, +urllib3/__pycache__/_collections.cpython-312.pyc,, +urllib3/__pycache__/_version.cpython-312.pyc,, +urllib3/__pycache__/connection.cpython-312.pyc,, +urllib3/__pycache__/connectionpool.cpython-312.pyc,, +urllib3/__pycache__/exceptions.cpython-312.pyc,, +urllib3/__pycache__/fields.cpython-312.pyc,, +urllib3/__pycache__/filepost.cpython-312.pyc,, +urllib3/__pycache__/poolmanager.cpython-312.pyc,, +urllib3/__pycache__/request.cpython-312.pyc,, +urllib3/__pycache__/response.cpython-312.pyc,, +urllib3/_collections.py,sha256=pyASJJhW7wdOpqJj9QJA8FyGRfr8E8uUUhqUvhF0728,11372 +urllib3/_version.py,sha256=DzRbt_FE1wm1jK-g1kN7opFo60AktFn3BMEB8zPRRpU,64 +urllib3/connection.py,sha256=ttIA909BrbTUzwkqEe_TzZVh4JOOj7g61Ysei2mrwGg,20314 +urllib3/connectionpool.py,sha256=WO2zcNzxrf7dbYXBUKWrMSVTayJYfNxu3RmSR074vUk,40362 +urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +urllib3/contrib/__pycache__/__init__.cpython-312.pyc,, +urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc,, +urllib3/contrib/__pycache__/appengine.cpython-312.pyc,, +urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc,, +urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc,, +urllib3/contrib/__pycache__/securetransport.cpython-312.pyc,, +urllib3/contrib/__pycache__/socks.cpython-312.pyc,, +urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957 +urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc,, +urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc,, +urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc,, +urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632 +urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922 +urllib3/contrib/appengine.py,sha256=6IBW6lPOoVUxASPwtn6IH1AATe5DK3lLJCfwyWlLKAE,11012 +urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528 +urllib3/contrib/pyopenssl.py,sha256=4AJAlo9NmjWofY4dJwRa4kbZuRuHfNJxu8Pv6yQk1ss,17055 +urllib3/contrib/securetransport.py,sha256=0YMMfoHyEc0TBwCkIgtCfygWGm3o4MXztlxn6zbav_U,34431 +urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097 +urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217 +urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579 +urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440 +urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +urllib3/packages/__pycache__/__init__.cpython-312.pyc,, +urllib3/packages/__pycache__/six.cpython-312.pyc,, +urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc,, +urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc,, +urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc,, +urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417 +urllib3/packages/backports/weakref_finalize.py,sha256=tRCal5OAhNSRyb0DhHp-38AtIlCsRP8BxF3NX-6rqIA,5343 +urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665 +urllib3/poolmanager.py,sha256=aWyhXRtNO4JUnCSVVqKTKQd8EXTvUm1VN9pgs2bcONo,19990 +urllib3/request.py,sha256=YTWFNr7QIwh7E1W9dde9LM77v2VWTJ5V78XuTTw7D1A,6691 +urllib3/response.py,sha256=UPgLmnHj4z71ZnH8ivYOyncATifTOw9FQukUqDnckCc,30761 +urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155 +urllib3/util/__pycache__/__init__.cpython-312.pyc,, +urllib3/util/__pycache__/connection.cpython-312.pyc,, +urllib3/util/__pycache__/proxy.cpython-312.pyc,, +urllib3/util/__pycache__/queue.cpython-312.pyc,, +urllib3/util/__pycache__/request.cpython-312.pyc,, +urllib3/util/__pycache__/response.cpython-312.pyc,, +urllib3/util/__pycache__/retry.cpython-312.pyc,, +urllib3/util/__pycache__/ssl_.cpython-312.pyc,, +urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc,, +urllib3/util/__pycache__/ssltransport.cpython-312.pyc,, +urllib3/util/__pycache__/timeout.cpython-312.pyc,, +urllib3/util/__pycache__/url.cpython-312.pyc,, +urllib3/util/__pycache__/wait.cpython-312.pyc,, +urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901 +urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605 +urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498 +urllib3/util/request.py,sha256=fWiAaa8pwdLLIqoTLBxCC2e4ed80muzKU3e3HWWTzFQ,4225 +urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510 +urllib3/util/retry.py,sha256=6ENvOZ8PBDzh8kgixpql9lIrb2dxH-k7ZmBanJF2Ng4,22050 +urllib3/util/ssl_.py,sha256=c0sYiSC6272r6uPkxQpo5rYPP9QC1eR6oI7004gYqZo,17165 +urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758 +urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895 +urllib3/util/timeout.py,sha256=cwq4dMk87mJHSBktK1miYJ-85G-3T3RmT20v7SFCpno,10168 +urllib3/util/url.py,sha256=kMxL1k0d-aQm_iZDw_zMmnyYyjrIA_DbsMy3cm3V55M,14279 +urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403 diff --git a/lib/urllib3-1.26.19.dist-info/WHEEL b/lib/urllib3-1.26.19.dist-info/WHEEL new file mode 100644 index 0000000..832be11 --- /dev/null +++ b/lib/urllib3-1.26.19.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.43.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/lib/urllib3-1.26.19.dist-info/top_level.txt b/lib/urllib3-1.26.19.dist-info/top_level.txt new file mode 100644 index 0000000..a42590b --- /dev/null +++ b/lib/urllib3-1.26.19.dist-info/top_level.txt @@ -0,0 +1 @@ +urllib3 diff --git a/lib/urllib3/__init__.py b/lib/urllib3/__init__.py new file mode 100644 index 0000000..c6fa382 --- /dev/null +++ b/lib/urllib3/__init__.py @@ -0,0 +1,102 @@ +""" +Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more +""" +from __future__ import absolute_import + +# Set default logging handler to avoid "No handler found" warnings. +import logging +import warnings +from logging import NullHandler + +from . import exceptions +from ._version import __version__ +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url +from .filepost import encode_multipart_formdata +from .poolmanager import PoolManager, ProxyManager, proxy_from_url +from .response import HTTPResponse +from .util.request import make_headers +from .util.retry import Retry +from .util.timeout import Timeout +from .util.url import get_host + +# === NOTE TO REPACKAGERS AND VENDORS === +# Please delete this block, this logic is only +# for urllib3 being distributed via PyPI. +# See: https://github.com/urllib3/urllib3/issues/2680 +try: + import urllib3_secure_extra # type: ignore # noqa: F401 +except ImportError: + pass +else: + warnings.warn( + "'urllib3[secure]' extra is deprecated and will be removed " + "in a future release of urllib3 2.x. Read more in this issue: " + "https://github.com/urllib3/urllib3/issues/2680", + category=DeprecationWarning, + stacklevel=2, + ) + +__author__ = "Andrey Petrov (andrey.petrov@shazow.net)" +__license__ = "MIT" +__version__ = __version__ + +__all__ = ( + "HTTPConnectionPool", + "HTTPSConnectionPool", + "PoolManager", + "ProxyManager", + "HTTPResponse", + "Retry", + "Timeout", + "add_stderr_logger", + "connection_from_url", + "disable_warnings", + "encode_multipart_formdata", + "get_host", + "make_headers", + "proxy_from_url", +) + +logging.getLogger(__name__).addHandler(NullHandler()) + + +def add_stderr_logger(level=logging.DEBUG): + """ + Helper for quickly adding a StreamHandler to the logger. Useful for + debugging. + + Returns the handler after adding it. + """ + # This method needs to be in this __init__.py to get the __name__ correct + # even if urllib3 is vendored within another package. + logger = logging.getLogger(__name__) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s")) + logger.addHandler(handler) + logger.setLevel(level) + logger.debug("Added a stderr logging handler to logger: %s", __name__) + return handler + + +# ... Clean up. +del NullHandler + + +# All warning filters *must* be appended unless you're really certain that they +# shouldn't be: otherwise, it's very hard for users to use most Python +# mechanisms to silence them. +# SecurityWarning's always go off by default. +warnings.simplefilter("always", exceptions.SecurityWarning, append=True) +# SubjectAltNameWarning's should go off once per host +warnings.simplefilter("default", exceptions.SubjectAltNameWarning, append=True) +# InsecurePlatformWarning's don't vary between requests, so we keep it default. +warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True) +# SNIMissingWarnings should go off only once. +warnings.simplefilter("default", exceptions.SNIMissingWarning, append=True) + + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter("ignore", category) diff --git a/lib/urllib3/__pycache__/__init__.cpython-312.pyc b/lib/urllib3/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a69874f07a8b4524c5ea80732142d3b4fcc4bbaf GIT binary patch literal 3395 zcmb7G-ESMm5#J+^-y$hdq9t0ke6l53Ol`_d-69p7xU%I$b|qQ0l-9YZJ)C$;^5i|< zW$(@sRU4pzqJHUv9}1)e0@Ov(hr;k?$Z$jVvH_mC6DpghR=BpEVta*p#Ua?%)~q@Chq-R#Uu%65 ztnd0Z-T50>%Uvs<`v%slzD;*NY7O!Ith?rOke6Y|%cWZI9Kxexhz14p4*FGN18oN1 zK^sE;)E15})tri1mF8AfmL#IDQI*!D4c)0oPK9DsyJ)K=EEUaa6&D>HHd>}h^lJHn zRMH6s$#x{$wJei57bMrlR4P#&S2a?*AgNVNGE9o&FIYr*!Aq-awn zAWjUPdkpm+Rw|G+2p8ng9qiB=Fp(AAz^3Z}8!cl;sX*4Y{&*hZfsB9WT^ko&ihp`u z!kZ3NCEb=ZY*AcP9jx&rZs>$aYgnS#FzKyucq7T8o|njN~=(THcc>_enxs3 zNdYN#AO%=JW%w~z+8+Y#`^Y(1TW5zlHXPAc_;B-3IAjs_SG%(hPY(kR0_*Hd$HpOR z-XxALYl8nBe-_XKVVz~<*mw{)vV*1T*m!`B>|nV(HnhN@^L0)S-wQ0Gd~oZRaS6s8 zCKh|XCY9cEb-3Z01UCVRhFV*801J%HE0r7*3JOc@%PB~2+qmQsX2|_$c+D-B!LAVJ zGCTs8R&8!lX}@zxEjjS1j(goH@QqvJP*Z&?3Vze+h0Hnh?Rz#^9#&0?k5XHiHO>o(D>EK3QW613)0T zQ4~rx#au(o{bus%+>UsWPQpU|+g?ObG_wfx6jzisGAjyYC#J)U6c}Mi@DOEC0tMLV zX*9ybRJT{L273r6Irc?avt_-OW1g2_dyICMIs~K)0KF*fG$f9zUXSbOq(Jd|E(U9c zlU}@|g5Jbox3h=6JLpku5RURakWP-T-asd@O1o7lyis`~%cYl@?KCTB&_8KIvzNHZ z`}++_P0BK&y6`81LUy2+6TOI`UxENRQwf1Qor19FX+}m_fT7tN*WP}sUENbmkzQsU zQg>>;|Ln56whn(tW{9&0&)8QF-UP?2mo5?20X#DNg}&v*n+wp@piX>Mf;I1s!0-A` zh~Fi@{Fl)yhN-y(zd>(70IVwPD?nR8K@k2O2ngbrVI-X22a^5_rT5U8f1#m0H2OKZ z+dy~s(A4MXS_56%LudEU#2z{gOM7Uf)sqmypNVH$P(_*g+~b8u3#~vP_Wf2EWyW^< z2fj>%L*Z60O1)N(@22|eiQQDLo@j~bM4%pNokc>X9%-V!2I_k<`5X;5(L@7H{Ql>E zc({$e3qDSd{chp63;QT7^tUEZsJE3u!ijpciLwopeNuTEZ%We*Y5JqfJ8147D0{G? zKRwwTooS5Dd@{C!ZhvLvdSmqZC$l@~M_*Zay)pXwN7@ehA$?6}BnpN9 pwiW^?+W#LU2(iD3QI@sXOPh7~Kc5n3ucD8yhHgZHe+dgf{|CxUY0m%v literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/_collections.cpython-312.pyc b/lib/urllib3/__pycache__/_collections.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d41e172c4d9e9549fd6888b131b5aaa9a2b803af GIT binary patch literal 16478 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 literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/_version.cpython-312.pyc b/lib/urllib3/__pycache__/_version.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4be28d981855b8a22a46d631e3fbedbf102ee353 GIT binary patch literal 208 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

)^Dw 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 literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/connectionpool.cpython-312.pyc b/lib/urllib3/__pycache__/connectionpool.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..735e11f0270ae94201bf99d19b43849952520c1f GIT binary patch literal 36481 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 H)`9;6*0?5e literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/fields.cpython-312.pyc b/lib/urllib3/__pycache__/fields.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5b3e767a15d91cd3c3f1d54f09ae9ddd0b1d803 GIT binary patch literal 10399 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 Q5)8CeQHTF+`wJ}pU!|f$zyJUM literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/filepost.cpython-312.pyc b/lib/urllib3/__pycache__/filepost.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..10f838e0bd15867674e2026273e743a43956b9c7 GIT binary patch literal 4008 zcmbVP>u(#!5#QtU_>d@)w)~JEm&jI4Tcm0`jV;v=xRH&>k?f{UftFA}op?*@q$7{s zU0S9<6>4BKRAp2Q8q^A4pbiosF^mBH*ngnthXRFIDzJKy0T)q$8vWv0`B3{)XYY8V zq{^+^1#WkCZ+3QWXXZC^e`sm(BWP~d`e-kA`N&xycB?x_3X;oTo3du;(5eq%$%rU_T$)i-)3Jj;zY+fhq z60CW@S7ewDTzv?2mB0feMNKo>ZIYac0++e9FRg(i z_Kp0cZo5QX@cJ+usULF*{LHU{*HR|u(%5iup_XU)R8S6{EHzx5Bs{u|K!)hql%++? zX?QHzhM*d5i{x<&K|!{0?g-zQGGCxh3@dq7?xy3QJJdexHr6% zjiszS0lvbVei|D#u1c(}oG+-k?+Svw4!1qUVcE`;7Ng#WZK?I;N)N5&4y76>)OL+ze$ z=^nc0G#rU<8^VMkT&L?D^ttcURh+{&^5o3azUFt+#3_vGo@%J~*&6q)_rlSQ4)=emO*%msIl#Mv&}~qf#9-yWse6j=YN{LP z`hZogExb~GyCU4WPz`iFBm5p?F2Z>Tk4H1=39k)e0@(|Ll|rmQ4y?Nz(hV=;oPl=` zzB`-Y`{z*ar^i1#{qgDFwAVUME`@p*#ooUJx)!c41-cepU8Eg$q#MW$6Q0EQ9j#r0 z)%5{s2NO5!jGu8Hvo+R*W?(iE9MJoB;114`W1LIg)S8&D2qj?(Fyekab&pm7H4@3AT1kdBE4YNe!4zyI9y>ExB04rW^Ssz<5$MTghch+q8>crrE~15jVAl zq>h*VqQ*G_%7wSS!KN+(+M1(TCP8lez3T;B>n!1Xp(PqOptv^jOhfh^@7VOgFtu;L zbsiKA z{2Qk{@%Ta7;-@^0Tl`ZZpT^@rZFP0uZK!ejAdR&Wj*@1}}gjeK-$D)l^ zf^!Pg4P%g*pmc?z1WaH8mElx#41OROsn;kB-(V?L%wt1@3ii6J6>!XBq8EvBk*-l) zDU$vC%%glBOzSxY<+!=WED|iUStz#)n{JY7ctDDq+&ujx>^=(*{X2AkdF?0|o$HfTd!FN?u>|E&MRqm|^{lhy6rwP<`vOstBn zWi}UlAnvY;yBEImprfbS(NpUiViHGH@hIHnUMIYWP#BOaUqYoJtW6$b|nU86F;5X-fDXfZq7a0sUtpnKvJ z1mPj-`Wl74LM>k*-$T^?S0p_|yB?yBN51xQ`~2S7y_LzDZ~tAP>U(v@^VH)Nwmsbz U7LGqX6cWDm&4ErKW`6O%0E%*;yZ`_I literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/poolmanager.cpython-312.pyc b/lib/urllib3/__pycache__/poolmanager.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ca31f8ce96bafa849202bb9cc85daf2386fb09c GIT binary patch literal 20462 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 IHnueX7xB7`i~s-t literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/request.cpython-312.pyc b/lib/urllib3/__pycache__/request.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40ad036ab6b36ea7031ad05ca0d950c17bd97ba7 GIT binary patch literal 7284 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 C8}TLp literal 0 HcmV?d00001 diff --git a/lib/urllib3/__pycache__/response.cpython-312.pyc b/lib/urllib3/__pycache__/response.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ed01d0e8809a240f087c19bef49fc2545467791 GIT binary patch literal 34138 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 self._maxsize: + _key, evicted_value = self._container.popitem(last=False) + + if self.dispose_func and evicted_value is not _Null: + self.dispose_func(evicted_value) + + def __delitem__(self, key): + with self.lock: + value = self._container.pop(key) + + if self.dispose_func: + self.dispose_func(value) + + def __len__(self): + with self.lock: + return len(self._container) + + def __iter__(self): + raise NotImplementedError( + "Iteration over this class is unlikely to be threadsafe." + ) + + def clear(self): + with self.lock: + # Copy pointers to all values, then wipe the mapping + values = list(itervalues(self._container)) + self._container.clear() + + if self.dispose_func: + for value in values: + self.dispose_func(value) + + def keys(self): + with self.lock: + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + """ + + def __init__(self, headers=None, **kwargs): + super(HTTPHeaderDict, self).__init__() + self._container = OrderedDict() + if headers is not None: + if isinstance(headers, HTTPHeaderDict): + self._copy_from(headers) + else: + self.extend(headers) + if kwargs: + self.extend(kwargs) + + def __setitem__(self, key, val): + self._container[key.lower()] = [key, val] + return self._container[key.lower()] + + def __getitem__(self, key): + val = self._container[key.lower()] + return ", ".join(val[1:]) + + def __delitem__(self, key): + del self._container[key.lower()] + + def __contains__(self, key): + return key.lower() in self._container + + def __eq__(self, other): + if not isinstance(other, Mapping) and not hasattr(other, "keys"): + return False + if not isinstance(other, type(self)): + other = type(self)(other) + return dict((k.lower(), v) for k, v in self.itermerged()) == dict( + (k.lower(), v) for k, v in other.itermerged() + ) + + def __ne__(self, other): + return not self.__eq__(other) + + if six.PY2: # Python 2 + iterkeys = MutableMapping.iterkeys + itervalues = MutableMapping.itervalues + + __marker = object() + + def __len__(self): + return len(self._container) + + def __iter__(self): + # Only provide the originally cased names + for vals in self._container.values(): + yield vals[0] + + def pop(self, key, default=__marker): + """D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + """ + # Using the MutableMapping function directly fails due to the private marker. + # Using ordinary dict.pop would expose the internal structures. + # So let's reinvent the wheel. + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def discard(self, key): + try: + del self[key] + except KeyError: + pass + + def add(self, key, val): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + key_lower = key.lower() + new_vals = [key, val] + # Keep the common case aka no item present as fast as possible + vals = self._container.setdefault(key_lower, new_vals) + if new_vals is not vals: + vals.append(val) + + def extend(self, *args, **kwargs): + """Generic import function for any type of header-like object. + Adapted version of MutableMapping.update in order to insert items + with self.add instead of self.__setitem__ + """ + if len(args) > 1: + raise TypeError( + "extend() takes at most 1 positional " + "arguments ({0} given)".format(len(args)) + ) + other = args[0] if len(args) >= 1 else () + + if isinstance(other, HTTPHeaderDict): + for key, val in other.iteritems(): + self.add(key, val) + elif isinstance(other, Mapping): + for key in other: + self.add(key, other[key]) + elif hasattr(other, "keys"): + for key in other.keys(): + self.add(key, other[key]) + else: + for key, value in other: + self.add(key, value) + + for key, value in kwargs.items(): + self.add(key, value) + + def getlist(self, key, default=__marker): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + try: + vals = self._container[key.lower()] + except KeyError: + if default is self.__marker: + return [] + return default + else: + return vals[1:] + + def _prepare_for_method_change(self): + """ + Remove content-specific header fields before changing the request + method to GET or HEAD according to RFC 9110, Section 15.4. + """ + content_specific_headers = [ + "Content-Encoding", + "Content-Language", + "Content-Location", + "Content-Type", + "Content-Length", + "Digest", + "Last-Modified", + ] + for header in content_specific_headers: + self.discard(header) + return self + + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist + iget = getlist + + # Backwards compatibility for http.cookiejar + get_all = getlist + + def __repr__(self): + return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) + + def _copy_from(self, other): + for key in other: + val = other.getlist(key) + if isinstance(val, list): + # Don't need to convert tuples + val = list(val) + self._container[key.lower()] = [key] + val + + def copy(self): + clone = type(self)() + clone._copy_from(self) + return clone + + def iteritems(self): + """Iterate over all header lines, including duplicate ones.""" + for key in self: + vals = self._container[key.lower()] + for val in vals[1:]: + yield vals[0], val + + def itermerged(self): + """Iterate over all headers, merging duplicate ones together.""" + for key in self: + val = self._container[key.lower()] + yield val[0], ", ".join(val[1:]) + + def items(self): + return list(self.iteritems()) + + @classmethod + def from_httplib(cls, message): # Python 2 + """Read headers from a Python 2 httplib message object.""" + # python2.7 does not expose a proper API for exporting multiheaders + # efficiently. This function re-reads raw lines from the message + # object and extracts the multiheaders properly. + obs_fold_continued_leaders = (" ", "\t") + headers = [] + + for line in message.headers: + if line.startswith(obs_fold_continued_leaders): + if not headers: + # We received a header line that starts with OWS as described + # in RFC-7230 S3.2.4. This indicates a multiline header, but + # there exists no previous header to which we can attach it. + raise InvalidHeader( + "Header continuation with no previous header: %s" % line + ) + else: + key, value = headers[-1] + headers[-1] = (key, value + " " + line.strip()) + continue + + key, value = line.split(":", 1) + headers.append((key, value.strip())) + + return cls(headers) diff --git a/lib/urllib3/_version.py b/lib/urllib3/_version.py new file mode 100644 index 0000000..c40db86 --- /dev/null +++ b/lib/urllib3/_version.py @@ -0,0 +1,2 @@ +# This file is protected via CODEOWNERS +__version__ = "1.26.19" diff --git a/lib/urllib3/connection.py b/lib/urllib3/connection.py new file mode 100644 index 0000000..de35b63 --- /dev/null +++ b/lib/urllib3/connection.py @@ -0,0 +1,572 @@ +from __future__ import absolute_import + +import datetime +import logging +import os +import re +import socket +import warnings +from socket import error as SocketError +from socket import timeout as SocketTimeout + +from .packages import six +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection +from .packages.six.moves.http_client import HTTPException # noqa: F401 +from .util.proxy import create_proxy_ssl_context + +try: # Compiled with SSL? + import ssl + + BaseSSLError = ssl.SSLError +except (ImportError, AttributeError): # Platform-specific: No SSL. + ssl = None + + class BaseSSLError(BaseException): + pass + + +try: + # Python 3: not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: + # Python 2 + class ConnectionError(Exception): + pass + + +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + BrokenPipeError = BrokenPipeError +except NameError: # Python 2: + + class BrokenPipeError(Exception): + pass + + +from ._collections import HTTPHeaderDict # noqa (historical, removed in v2) +from ._version import __version__ +from .exceptions import ( + ConnectTimeoutError, + NewConnectionError, + SubjectAltNameWarning, + SystemTimeWarning, +) +from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection +from .util.ssl_ import ( + assert_fingerprint, + create_urllib3_context, + is_ipaddress, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .util.ssl_match_hostname import CertificateError, match_hostname + +log = logging.getLogger(__name__) + +port_by_scheme = {"http": 80, "https": 443} + +# When it comes time to update this value as a part of regular maintenance +# (ie test_recent_date is failing) update it to ~6 months before the current date. +RECENT_DATE = datetime.date(2024, 1, 1) + +_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") + + +class HTTPConnection(_HTTPConnection, object): + """ + Based on :class:`http.client.HTTPConnection` but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass: + + .. code-block:: python + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + + default_port = port_by_scheme["http"] + + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + #: Whether this proxy connection (if used) verifies the proxy host's + #: certificate. + proxy_is_verified = None + + def __init__(self, *args, **kw): + if not six.PY2: + kw.pop("strict", None) + + # Pre-set source_address. + self.source_address = kw.get("source_address") + + #: The socket options provided by the user. If no options are + #: provided, we use the default options. + self.socket_options = kw.pop("socket_options", self.default_socket_options) + + # Proxy options provided by the user. + self.proxy = kw.pop("proxy", None) + self.proxy_config = kw.pop("proxy_config", None) + + _HTTPConnection.__init__(self, *args, **kw) + + @property + def host(self): + """ + Getter method to remove any trailing dots that indicate the hostname is an FQDN. + + In general, SSL certificates don't include the trailing dot indicating a + fully-qualified domain name, and thus, they don't validate properly when + checked against a domain name that includes the dot. In addition, some + servers may not expect to receive the trailing dot when provided. + + However, the hostname with trailing dot is critical to DNS resolution; doing a + lookup with the trailing dot will properly only resolve the appropriate FQDN, + whereas a lookup without a trailing dot will search the system's search domain + list. Thus, it's important to keep the original host around for use only in + those cases where it's appropriate (i.e., when doing DNS lookup to establish the + actual TCP connection across which we're going to send HTTP requests). + """ + return self._dns_host.rstrip(".") + + @host.setter + def host(self, value): + """ + Setter for the `host` property. + + We assume that only urllib3 uses the _dns_host attribute; httplib itself + only uses `host`, and it seems reasonable that other libraries follow suit. + """ + self._dns_host = value + + def _new_conn(self): + """Establish a socket connection and set nodelay settings on it. + + :return: New socket connection. + """ + extra_kw = {} + if self.source_address: + extra_kw["source_address"] = self.source_address + + if self.socket_options: + extra_kw["socket_options"] = self.socket_options + + try: + conn = connection.create_connection( + (self._dns_host, self.port), self.timeout, **extra_kw + ) + + except SocketTimeout: + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" + % (self.host, self.timeout), + ) + + except SocketError as e: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e + ) + + return conn + + def _is_using_tunnel(self): + # Google App Engine's httplib does not define _tunnel_host + return getattr(self, "_tunnel_host", None) + + def _prepare_conn(self, conn): + self.sock = conn + if self._is_using_tunnel(): + # TODO: Fix tunnel so it doesn't depend on self.sock state. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + def putrequest(self, method, url, *args, **kwargs): + """ """ + # Empty docstring because the indentation of CPython's implementation + # is broken but we don't want this method in our documentation. + match = _CONTAINS_CONTROL_CHAR_RE.search(method) + if match: + raise ValueError( + "Method cannot contain non-token characters %r (found at least %r)" + % (method, match.group()) + ) + + return _HTTPConnection.putrequest(self, method, url, *args, **kwargs) + + def putheader(self, header, *values): + """ """ + if not any(isinstance(v, str) and v == SKIP_HEADER for v in values): + _HTTPConnection.putheader(self, header, *values) + elif six.ensure_str(header.lower()) not in SKIPPABLE_HEADERS: + raise ValueError( + "urllib3.util.SKIP_HEADER only supports '%s'" + % ("', '".join(map(str.title, sorted(SKIPPABLE_HEADERS))),) + ) + + def request(self, method, url, body=None, headers=None): + # Update the inner socket's timeout value to send the request. + # This only triggers if the connection is re-used. + if getattr(self, "sock", None) is not None: + self.sock.settimeout(self.timeout) + + if headers is None: + headers = {} + else: + # Avoid modifying the headers passed into .request() + headers = headers.copy() + if "user-agent" not in (six.ensure_str(k.lower()) for k in headers): + headers["User-Agent"] = _get_default_user_agent() + super(HTTPConnection, self).request(method, url, body=body, headers=headers) + + def request_chunked(self, method, url, body=None, headers=None): + """ + Alternative to the common request method, which sends the + body with chunked encoding and not as one block + """ + headers = headers or {} + header_keys = set([six.ensure_str(k.lower()) for k in headers]) + skip_accept_encoding = "accept-encoding" in header_keys + skip_host = "host" in header_keys + self.putrequest( + method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host + ) + if "user-agent" not in header_keys: + self.putheader("User-Agent", _get_default_user_agent()) + for header, value in headers.items(): + self.putheader(header, value) + if "transfer-encoding" not in header_keys: + self.putheader("Transfer-Encoding", "chunked") + self.endheaders() + + if body is not None: + stringish_types = six.string_types + (bytes,) + if isinstance(body, stringish_types): + body = (body,) + for chunk in body: + if not chunk: + continue + if not isinstance(chunk, bytes): + chunk = chunk.encode("utf8") + len_str = hex(len(chunk))[2:] + to_send = bytearray(len_str.encode()) + to_send += b"\r\n" + to_send += chunk + to_send += b"\r\n" + self.send(to_send) + + # After the if clause, to always have a closed body + self.send(b"0\r\n\r\n") + + +class HTTPSConnection(HTTPConnection): + """ + Many of the parameters to this constructor are passed to the underlying SSL + socket by means of :py:func:`urllib3.util.ssl_wrap_socket`. + """ + + default_port = port_by_scheme["https"] + + cert_reqs = None + ca_certs = None + ca_cert_dir = None + ca_cert_data = None + ssl_version = None + assert_fingerprint = None + tls_in_tls_required = False + + def __init__( + self, + host, + port=None, + key_file=None, + cert_file=None, + key_password=None, + strict=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, + server_hostname=None, + **kw + ): + + HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw) + + self.key_file = key_file + self.cert_file = cert_file + self.key_password = key_password + self.ssl_context = ssl_context + self.server_hostname = server_hostname + + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = "https" + + def set_cert( + self, + key_file=None, + cert_file=None, + cert_reqs=None, + key_password=None, + ca_certs=None, + assert_hostname=None, + assert_fingerprint=None, + ca_cert_dir=None, + ca_cert_data=None, + ): + """ + This method should only be called once, before the connection is used. + """ + # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also + # have an SSLContext object in which case we'll use its verify_mode. + if cert_reqs is None: + if self.ssl_context is not None: + cert_reqs = self.ssl_context.verify_mode + else: + cert_reqs = resolve_cert_reqs(None) + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.key_password = key_password + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + self.ca_certs = ca_certs and os.path.expanduser(ca_certs) + self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) + self.ca_cert_data = ca_cert_data + + def connect(self): + # Add certificate verification + self.sock = conn = self._new_conn() + hostname = self.host + tls_in_tls = False + + if self._is_using_tunnel(): + if self.tls_in_tls_required: + self.sock = conn = self._connect_tls_proxy(hostname, conn) + tls_in_tls = True + + # Calls self._set_hostport(), so self.host is + # self._tunnel_host below. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + server_hostname = hostname + if self.server_hostname is not None: + server_hostname = self.server_hostname + + is_time_off = datetime.date.today() < RECENT_DATE + if is_time_off: + warnings.warn( + ( + "System time is way off (before {0}). This will probably " + "lead to SSL verification errors" + ).format(RECENT_DATE), + SystemTimeWarning, + ) + + # Wrap socket using verification with the root certs in + # trusted_root_certs + default_ssl_context = False + if self.ssl_context is None: + default_ssl_context = True + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(self.ssl_version), + cert_reqs=resolve_cert_reqs(self.cert_reqs), + ) + + context = self.ssl_context + context.verify_mode = resolve_cert_reqs(self.cert_reqs) + + # Try to load OS default certs if none are given. + # Works well on Windows (requires Python3.4+) + if ( + not self.ca_certs + and not self.ca_cert_dir + and not self.ca_cert_data + and default_ssl_context + and hasattr(context, "load_default_certs") + ): + context.load_default_certs() + + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + key_password=self.key_password, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + ca_cert_data=self.ca_cert_data, + server_hostname=server_hostname, + ssl_context=context, + tls_in_tls=tls_in_tls, + ) + + # If we're using all defaults and the connection + # is TLSv1 or TLSv1.1 we throw a DeprecationWarning + # for the host. + if ( + default_ssl_context + and self.ssl_version is None + and hasattr(self.sock, "version") + and self.sock.version() in {"TLSv1", "TLSv1.1"} + ): # Defensive: + warnings.warn( + "Negotiating TLSv1/TLSv1.1 by default is deprecated " + "and will be disabled in urllib3 v2.0.0. Connecting to " + "'%s' with '%s' can be enabled by explicitly opting-in " + "with 'ssl_version'" % (self.host, self.sock.version()), + DeprecationWarning, + ) + + if self.assert_fingerprint: + assert_fingerprint( + self.sock.getpeercert(binary_form=True), self.assert_fingerprint + ) + elif ( + context.verify_mode != ssl.CERT_NONE + and not getattr(context, "check_hostname", False) + and self.assert_hostname is not False + ): + # While urllib3 attempts to always turn off hostname matching from + # the TLS library, this cannot always be done. So we check whether + # the TLS Library still thinks it's matching hostnames. + cert = self.sock.getpeercert() + if not cert.get("subjectAltName", ()): + warnings.warn( + ( + "Certificate for {0} has no `subjectAltName`, falling back to check for a " + "`commonName` for now. This feature is being removed by major browsers and " + "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 " + "for details.)".format(hostname) + ), + SubjectAltNameWarning, + ) + _match_hostname(cert, self.assert_hostname or server_hostname) + + self.is_verified = ( + context.verify_mode == ssl.CERT_REQUIRED + or self.assert_fingerprint is not None + ) + + def _connect_tls_proxy(self, hostname, conn): + """ + Establish a TLS connection to the proxy using the provided SSL context. + """ + proxy_config = self.proxy_config + ssl_context = proxy_config.ssl_context + if ssl_context: + # If the user provided a proxy context, we assume CA and client + # certificates have already been set + return ssl_wrap_socket( + sock=conn, + server_hostname=hostname, + ssl_context=ssl_context, + ) + + ssl_context = create_proxy_ssl_context( + self.ssl_version, + self.cert_reqs, + self.ca_certs, + self.ca_cert_dir, + self.ca_cert_data, + ) + + # If no cert was provided, use only the default options for server + # certificate validation + socket = ssl_wrap_socket( + sock=conn, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + ca_cert_data=self.ca_cert_data, + server_hostname=hostname, + ssl_context=ssl_context, + ) + + if ssl_context.verify_mode != ssl.CERT_NONE and not getattr( + ssl_context, "check_hostname", False + ): + # While urllib3 attempts to always turn off hostname matching from + # the TLS library, this cannot always be done. So we check whether + # the TLS Library still thinks it's matching hostnames. + cert = socket.getpeercert() + if not cert.get("subjectAltName", ()): + warnings.warn( + ( + "Certificate for {0} has no `subjectAltName`, falling back to check for a " + "`commonName` for now. This feature is being removed by major browsers and " + "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 " + "for details.)".format(hostname) + ), + SubjectAltNameWarning, + ) + _match_hostname(cert, hostname) + + self.proxy_is_verified = ssl_context.verify_mode == ssl.CERT_REQUIRED + return socket + + +def _match_hostname(cert, asserted_hostname): + # Our upstream implementation of ssl.match_hostname() + # only applies this normalization to IP addresses so it doesn't + # match DNS SANs so we do the same thing! + stripped_hostname = asserted_hostname.strip("u[]") + if is_ipaddress(stripped_hostname): + asserted_hostname = stripped_hostname + + try: + match_hostname(cert, asserted_hostname) + except CertificateError as e: + log.warning( + "Certificate did not match expected hostname: %s. Certificate: %s", + asserted_hostname, + cert, + ) + # Add cert to exception and reraise so client code can inspect + # the cert when catching the exception, if they want to + e._peer_cert = cert + raise + + +def _get_default_user_agent(): + return "python-urllib3/%s" % __version__ + + +class DummyConnection(object): + """Used to detect a failed ConnectionCls import.""" + + pass + + +if not ssl: + HTTPSConnection = DummyConnection # noqa: F811 + + +VerifiedHTTPSConnection = HTTPSConnection diff --git a/lib/urllib3/connectionpool.py b/lib/urllib3/connectionpool.py new file mode 100644 index 0000000..402bf67 --- /dev/null +++ b/lib/urllib3/connectionpool.py @@ -0,0 +1,1139 @@ +from __future__ import absolute_import + +import errno +import logging +import re +import socket +import sys +import warnings +from socket import error as SocketError +from socket import timeout as SocketTimeout + +from ._collections import HTTPHeaderDict +from .connection import ( + BaseSSLError, + BrokenPipeError, + DummyConnection, + HTTPConnection, + HTTPException, + HTTPSConnection, + VerifiedHTTPSConnection, + port_by_scheme, +) +from .exceptions import ( + ClosedPoolError, + EmptyPoolError, + HeaderParsingError, + HostChangedError, + InsecureRequestWarning, + LocationValueError, + MaxRetryError, + NewConnectionError, + ProtocolError, + ProxyError, + ReadTimeoutError, + SSLError, + TimeoutError, +) +from .packages import six +from .packages.six.moves import queue +from .request import RequestMethods +from .response import HTTPResponse +from .util.connection import is_connection_dropped +from .util.proxy import connection_requires_http_tunnel +from .util.queue import LifoQueue +from .util.request import set_file_position +from .util.response import assert_header_parsing +from .util.retry import Retry +from .util.ssl_match_hostname import CertificateError +from .util.timeout import Timeout +from .util.url import Url, _encode_target +from .util.url import _normalize_host as normalize_host +from .util.url import get_host, parse_url + +try: # Platform-specific: Python 3 + import weakref + + weakref_finalize = weakref.finalize +except AttributeError: # Platform-specific: Python 2 + from .packages.backports.weakref_finalize import weakref_finalize + +xrange = six.moves.xrange + +log = logging.getLogger(__name__) + +_Default = object() + + +# Pool objects +class ConnectionPool(object): + """ + Base class for all connection pools, such as + :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + + .. note:: + ConnectionPool.urlopen() does not normalize or percent-encode target URIs + which is useful if your target server doesn't support percent-encoded + target URIs. + """ + + scheme = None + QueueCls = LifoQueue + + def __init__(self, host, port=None): + if not host: + raise LocationValueError("No host specified.") + + self.host = _normalize_host(host, scheme=self.scheme) + self._proxy_host = host.lower() + self.port = port + + def __str__(self): + return "%s(host=%r, port=%r)" % (type(self).__name__, self.host, self.port) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + # Return False to re-raise any potential exceptions + return False + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + pass + + +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 +_blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK} + + +class HTTPConnectionPool(ConnectionPool, RequestMethods): + """ + Thread-safe connection pool for one host. + + :param host: + Host used for this HTTP Connection (e.g. "localhost"), passed into + :class:`http.client.HTTPConnection`. + + :param port: + Port used for this HTTP Connection (None is equivalent to 80), passed + into :class:`http.client.HTTPConnection`. + + :param strict: + Causes BadStatusLine to be raised if the status line can't be parsed + as a valid HTTP/1.0 or 1.1 status line, passed into + :class:`http.client.HTTPConnection`. + + .. note:: + Only works in Python 2. This parameter is ignored in Python 3. + + :param timeout: + Socket timeout in seconds for each individual connection. This can + be a float or integer, which sets the timeout for the HTTP request, + or an instance of :class:`urllib3.util.Timeout` which gives you more + fine-grained control over request timeouts. After the constructor has + been parsed, this is always a `urllib3.util.Timeout` object. + + :param maxsize: + Number of connections to save that can be reused. More than 1 is useful + in multithreaded situations. If ``block`` is set to False, more + connections will be created but they will not be saved once they've + been used. + + :param block: + If set to True, no more than ``maxsize`` connections will be used at + a time. When no free connections are available, the call will block + until a connection has been released. This is a useful side effect for + particular multithreaded situations where one does not want to use more + than maxsize connections per host to prevent flooding. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param retries: + Retry configuration to use by default with requests in this pool. + + :param _proxy: + Parsed proxy URL, should not be used directly, instead, see + :class:`urllib3.ProxyManager` + + :param _proxy_headers: + A dictionary with proxy headers, should not be used directly, + instead, see :class:`urllib3.ProxyManager` + + :param \\**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. + """ + + scheme = "http" + ConnectionCls = HTTPConnection + ResponseCls = HTTPResponse + + def __init__( + self, + host, + port=None, + strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, + maxsize=1, + block=False, + headers=None, + retries=None, + _proxy=None, + _proxy_headers=None, + _proxy_config=None, + **conn_kw + ): + ConnectionPool.__init__(self, host, port) + RequestMethods.__init__(self, headers) + + self.strict = strict + + if not isinstance(timeout, Timeout): + timeout = Timeout.from_float(timeout) + + if retries is None: + retries = Retry.DEFAULT + + self.timeout = timeout + self.retries = retries + + self.pool = self.QueueCls(maxsize) + self.block = block + + self.proxy = _proxy + self.proxy_headers = _proxy_headers or {} + self.proxy_config = _proxy_config + + # Fill the queue up so that doing get() on it will block properly + for _ in xrange(maxsize): + self.pool.put(None) + + # These are mostly for testing and debugging purposes. + self.num_connections = 0 + self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. + # We cannot know if the user has added default socket options, so we cannot replace the + # list. + self.conn_kw.setdefault("socket_options", []) + + self.conn_kw["proxy"] = self.proxy + self.conn_kw["proxy_config"] = self.proxy_config + + # Do not pass 'self' as callback to 'finalize'. + # Then the 'finalize' would keep an endless living (leak) to self. + # By just passing a reference to the pool allows the garbage collector + # to free self if nobody else has a reference to it. + pool = self.pool + + # Close all the HTTPConnections in the pool before the + # HTTPConnectionPool object is garbage collected. + weakref_finalize(self, _close_pool_connections, pool) + + def _new_conn(self): + """ + Return a fresh :class:`HTTPConnection`. + """ + self.num_connections += 1 + log.debug( + "Starting new HTTP connection (%d): %s:%s", + self.num_connections, + self.host, + self.port or "80", + ) + + conn = self.ConnectionCls( + host=self.host, + port=self.port, + timeout=self.timeout.connect_timeout, + strict=self.strict, + **self.conn_kw + ) + return conn + + def _get_conn(self, timeout=None): + """ + Get a connection. Will return a pooled connection if one is available. + + If no connections are available and :prop:`.block` is ``False``, then a + fresh connection is returned. + + :param timeout: + Seconds to wait before giving up and raising + :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and + :prop:`.block` is ``True``. + """ + conn = None + try: + conn = self.pool.get(block=self.block, timeout=timeout) + + except AttributeError: # self.pool is None + raise ClosedPoolError(self, "Pool is closed.") + + except queue.Empty: + if self.block: + raise EmptyPoolError( + self, + "Pool reached maximum size and no more connections are allowed.", + ) + pass # Oh well, we'll create a new connection then + + # If this is a persistent connection, check if it got disconnected + if conn and is_connection_dropped(conn): + log.debug("Resetting dropped connection: %s", self.host) + conn.close() + if getattr(conn, "auto_open", 1) == 0: + # This is a proxied connection that has been mutated by + # http.client._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None + + return conn or self._new_conn() + + def _put_conn(self, conn): + """ + Put a connection back into the pool. + + :param conn: + Connection object for the current host and port as returned by + :meth:`._new_conn` or :meth:`._get_conn`. + + If the pool is already full, the connection is closed and discarded + because we exceeded maxsize. If connections are discarded frequently, + then maxsize should be increased. + + If the pool is closed, then the connection will be closed and discarded. + """ + try: + self.pool.put(conn, block=False) + return # Everything is dandy, done. + except AttributeError: + # self.pool is None. + pass + except queue.Full: + # This should never happen if self.block == True + log.warning( + "Connection pool is full, discarding connection: %s. Connection pool size: %s", + self.host, + self.pool.qsize(), + ) + # Connection never got put back into the pool, close it. + if conn: + conn.close() + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + + def _get_timeout(self, timeout): + """Helper that always returns a :class:`urllib3.util.Timeout`""" + if timeout is _Default: + return self.timeout.clone() + + if isinstance(timeout, Timeout): + return timeout.clone() + else: + # User passed us an int/float. This is for backwards compatibility, + # can be removed later + return Timeout.from_float(timeout) + + def _raise_timeout(self, err, url, timeout_value): + """Is the error actually a timeout? Will raise a ReadTimeout or pass""" + + if isinstance(err, SocketTimeout): + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % timeout_value + ) + + # See the above comment about EAGAIN in Python 3. In Python 2 we have + # to specifically catch it and throw the timeout error + if hasattr(err, "errno") and err.errno in _blocking_errnos: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % timeout_value + ) + + # Catch possible read timeouts thrown as SSL errors. If not the + # case, rethrow the original. We need to do this because of: + # http://bugs.python.org/issue10272 + if "timed out" in str(err) or "did not complete (read)" in str( + err + ): # Python < 2.7.4 + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % timeout_value + ) + + def _make_request( + self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw + ): + """ + Perform a request on a given urllib connection object taken from our + pool. + + :param conn: + a connection from one of our connection pools + + :param timeout: + Socket timeout in seconds for the request. This can be a + float or integer, which will set the same timeout value for + the socket connect and the socket read, or an instance of + :class:`urllib3.util.Timeout`, which gives you more fine-grained + control over your timeouts. + """ + self.num_requests += 1 + + timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = Timeout.resolve_default_timeout(timeout_obj.connect_timeout) + + # Trigger any extra validation we need to do. + try: + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls http.client.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + try: + if chunked: + conn.request_chunked(method, url, **httplib_request_kw) + else: + conn.request(method, url, **httplib_request_kw) + + # We are swallowing BrokenPipeError (errno.EPIPE) since the server is + # legitimately able to close the connection after sending a valid response. + # With this behaviour, the received response is still readable. + except BrokenPipeError: + # Python 3 + pass + except IOError as e: + # Python 2 and macOS/Linux + # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS + # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/ + if e.errno not in { + errno.EPIPE, + errno.ESHUTDOWN, + errno.EPROTOTYPE, + }: + raise + + # Reset the timeout for the recv() on the socket + read_timeout = timeout_obj.read_timeout + + # App Engine doesn't have a sock attr + if getattr(conn, "sock", None): + # In Python 3 socket.py will catch EAGAIN and return None when you + # try and read into the file pointer created by http.client, which + # instead raises a BadStatusLine exception. Instead of catching + # the exception and assuming all BadStatusLine exceptions are read + # timeouts, check for a zero timeout before making the request. + if read_timeout == 0: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % read_timeout + ) + if read_timeout is Timeout.DEFAULT_TIMEOUT: + conn.sock.settimeout(socket.getdefaulttimeout()) + else: # None or a value + conn.sock.settimeout(read_timeout) + + # Receive the response from the server + try: + try: + # Python 2.7, use buffering of HTTP responses + httplib_response = conn.getresponse(buffering=True) + except TypeError: + # Python 3 + try: + httplib_response = conn.getresponse() + except BaseException as e: + # Remove the TypeError from the exception chain in + # Python 3 (including for exceptions like SystemExit). + # Otherwise it looks like a bug in the code. + six.raise_from(e, None) + except (SocketTimeout, BaseSSLError, SocketError) as e: + self._raise_timeout(err=e, url=url, timeout_value=read_timeout) + raise + + # AppEngine doesn't have a version attr. + http_version = getattr(conn, "_http_vsn_str", "HTTP/?") + log.debug( + '%s://%s:%s "%s %s %s" %s %s', + self.scheme, + self.host, + self.port, + method, + url, + http_version, + httplib_response.status, + httplib_response.length, + ) + + try: + assert_header_parsing(httplib_response.msg) + except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 + log.warning( + "Failed to parse headers (url=%s): %s", + self._absolute_url(url), + hpe, + exc_info=True, + ) + + return httplib_response + + def _absolute_url(self, path): + return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + if self.pool is None: + return + # Disable access to the pool + old_pool, self.pool = self.pool, None + + # Close all the HTTPConnections in the pool. + _close_pool_connections(old_pool) + + def is_same_host(self, url): + """ + Check if the given ``url`` is a member of the same host as this + connection pool. + """ + if url.startswith("/"): + return True + + # TODO: Add optional support for socket.gethostbyname checking. + scheme, host, port = get_host(url) + if host is not None: + host = _normalize_host(host, scheme=scheme) + + # Use explicit default port for comparison when none is given + if self.port and not port: + port = port_by_scheme.get(scheme) + elif not self.port and port == port_by_scheme.get(scheme): + port = None + + return (scheme, host, port) == (self.scheme, self.host, self.port) + + def urlopen( + self, + method, + url, + body=None, + headers=None, + retries=None, + redirect=True, + assert_same_host=True, + timeout=_Default, + pool_timeout=None, + release_conn=None, + chunked=False, + body_pos=None, + **response_kw + ): + """ + Get a connection from the pool and perform an HTTP request. This is the + lowest level call for making a request, so you'll need to specify all + the raw details. + + .. note:: + + More commonly, it's appropriate to use a convenience method provided + by :class:`.RequestMethods`, such as :meth:`request`. + + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param url: + The URL to perform the request on. + + :param body: + Data to send in the request body, either :class:`str`, :class:`bytes`, + an iterable of :class:`str`/:class:`bytes`, or a file-like object. + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. If None, pool headers are used. If provided, + these headers completely replace any pool-specific headers. + + :param retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. + + :param redirect: + If True, automatically handle redirects (status codes 301, 302, + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. + + :param assert_same_host: + If ``True``, will make sure that the host of the pool requests is + consistent else will raise HostChangedError. When ``False``, you can + use the pool on an HTTP proxy and request foreign hosts. + + :param timeout: + If specified, overrides the default timeout for this one + request. It may be a float (in seconds) or an instance of + :class:`urllib3.util.Timeout`. + + :param pool_timeout: + If set and the pool is set to block=True, then this method will + block for ``pool_timeout`` seconds and raise EmptyPoolError if no + connection is available within the time period. + + :param release_conn: + If False, then the urlopen call will not release the connection + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of + ``response_kw.get('preload_content', True)``. + + :param chunked: + If True, urllib3 will send the body using chunked transfer + encoding. Otherwise, urllib3 will send the body using the standard + content-length form. Defaults to False. + + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: + Additional parameters are passed to + :meth:`urllib3.response.HTTPResponse.from_httplib` + """ + + parsed_url = parse_url(url) + destination_scheme = parsed_url.scheme + + if headers is None: + headers = self.headers + + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if release_conn is None: + release_conn = response_kw.get("preload_content", True) + + # Check host + if assert_same_host and not self.is_same_host(url): + raise HostChangedError(self, url, retries) + + # Ensure that the URL we're connecting to is properly encoded + if url.startswith("/"): + url = six.ensure_str(_encode_target(url)) + else: + url = six.ensure_str(parsed_url.url) + + conn = None + + # Track whether `conn` needs to be released before + # returning/raising/recursing. Update this variable if necessary, and + # leave `release_conn` constant throughout the function. That way, if + # the function recurses, the original value of `release_conn` will be + # passed down into the recursive call, and its value will be respected. + # + # See issue #651 [1] for details. + # + # [1] + release_this_conn = release_conn + + http_tunnel_required = connection_requires_http_tunnel( + self.proxy, self.proxy_config, destination_scheme + ) + + # Merge the proxy headers. Only done when not using HTTP CONNECT. We + # have to copy the headers dict so we can safely change it without those + # changes being reflected in anyone else's copy. + if not http_tunnel_required: + headers = headers.copy() + headers.update(self.proxy_headers) + + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + + # Keep track of whether we cleanly exited the except block. This + # ensures we do proper cleanup in finally. + clean_exit = False + + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + + try: + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) + conn = self._get_conn(timeout=pool_timeout) + + conn.timeout = timeout_obj.connect_timeout + + is_new_proxy_conn = self.proxy is not None and not getattr( + conn, "sock", None + ) + if is_new_proxy_conn and http_tunnel_required: + self._prepare_proxy(conn) + + # Make the request on the httplib connection object. + httplib_response = self._make_request( + conn, + method, + url, + timeout=timeout_obj, + body=body, + headers=headers, + chunked=chunked, + ) + + # If we're going to release the connection in ``finally:``, then + # the response doesn't need to know about the connection. Otherwise + # it will also try to release it and we'll have a double-release + # mess. + response_conn = conn if not release_conn else None + + # Pass method to Response for length checking + response_kw["request_method"] = method + + # Import httplib's response into our own wrapper object + response = self.ResponseCls.from_httplib( + httplib_response, + pool=self, + connection=response_conn, + retries=retries, + **response_kw + ) + + # Everything went great! + clean_exit = True + + except EmptyPoolError: + # Didn't get a connection from the pool, no need to clean up + clean_exit = True + release_this_conn = False + raise + + except ( + TimeoutError, + HTTPException, + SocketError, + ProtocolError, + BaseSSLError, + SSLError, + CertificateError, + ) as e: + # Discard the connection for these exceptions. It will be + # replaced during the next _get_conn() call. + clean_exit = False + + def _is_ssl_error_message_from_http_proxy(ssl_error): + # We're trying to detect the message 'WRONG_VERSION_NUMBER' but + # SSLErrors are kinda all over the place when it comes to the message, + # so we try to cover our bases here! + message = " ".join(re.split("[^a-z]", str(ssl_error).lower())) + return ( + "wrong version number" in message + or "unknown protocol" in message + or "record layer failure" in message + ) + + # Try to detect a common user error with proxies which is to + # set an HTTP proxy to be HTTPS when it should be 'http://' + # (ie {'http': 'http://proxy', 'https': 'https://proxy'}) + # Instead we add a nice error message and point to a URL. + if ( + isinstance(e, BaseSSLError) + and self.proxy + and _is_ssl_error_message_from_http_proxy(e) + and conn.proxy + and conn.proxy.scheme == "https" + ): + e = ProxyError( + "Your proxy appears to only use HTTP and not HTTPS, " + "try changing your proxy URL to be HTTP. See: " + "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" + "#https-proxy-error-http-proxy", + SSLError(e), + ) + elif isinstance(e, (BaseSSLError, CertificateError)): + e = SSLError(e) + elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: + e = ProxyError("Cannot connect to proxy.", e) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError("Connection aborted.", e) + + retries = retries.increment( + method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] + ) + retries.sleep() + + # Keep track of the error for the retry warning. + err = e + + finally: + if not clean_exit: + # We hit some kind of exception, handled or otherwise. We need + # to throw the connection away unless explicitly told not to. + # Close the connection, set the variable to None, and make sure + # we put the None back in the pool to avoid leaking it. + conn = conn and conn.close() + release_this_conn = True + + if release_this_conn: + # Put the connection back to be reused. If the connection is + # expired then it will be None, which will get replaced with a + # fresh connection during _get_conn. + self._put_conn(conn) + + if not conn: + # Try again + log.warning( + "Retrying (%r) after connection broken by '%r': %s", retries, err, url + ) + return self.urlopen( + method, + url, + body, + headers, + retries, + redirect, + assert_same_host, + timeout=timeout, + pool_timeout=pool_timeout, + release_conn=release_conn, + chunked=chunked, + body_pos=body_pos, + **response_kw + ) + + # Handle redirect? + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: + # Change the method according to RFC 9110, Section 15.4.4. + method = "GET" + # And lose the body not to transfer anything sensitive. + body = None + headers = HTTPHeaderDict(headers)._prepare_for_method_change() + + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + response.drain_conn() + raise + return response + + response.drain_conn() + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( + method, + redirect_location, + body, + headers, + retries=retries, + redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, + pool_timeout=pool_timeout, + release_conn=release_conn, + chunked=chunked, + body_pos=body_pos, + **response_kw + ) + + # Check if we should retry the HTTP response. + has_retry_after = bool(response.headers.get("Retry-After")) + if retries.is_retry(method, response.status, has_retry_after): + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_status: + response.drain_conn() + raise + return response + + response.drain_conn() + retries.sleep(response) + log.debug("Retry: %s", url) + return self.urlopen( + method, + url, + body, + headers, + retries=retries, + redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, + pool_timeout=pool_timeout, + release_conn=release_conn, + chunked=chunked, + body_pos=body_pos, + **response_kw + ) + + return response + + +class HTTPSConnectionPool(HTTPConnectionPool): + """ + Same as :class:`.HTTPConnectionPool`, but HTTPS. + + :class:`.HTTPSConnection` uses one of ``assert_fingerprint``, + ``assert_hostname`` and ``host`` in this order to verify connections. + If ``assert_hostname`` is False, no verification is done. + + The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, + ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl` + is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade + the connection socket into an SSL socket. + """ + + scheme = "https" + ConnectionCls = HTTPSConnection + + def __init__( + self, + host, + port=None, + strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, + maxsize=1, + block=False, + headers=None, + retries=None, + _proxy=None, + _proxy_headers=None, + key_file=None, + cert_file=None, + cert_reqs=None, + key_password=None, + ca_certs=None, + ssl_version=None, + assert_hostname=None, + assert_fingerprint=None, + ca_cert_dir=None, + **conn_kw + ): + + HTTPConnectionPool.__init__( + self, + host, + port, + strict, + timeout, + maxsize, + block, + headers, + retries, + _proxy, + _proxy_headers, + **conn_kw + ) + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.key_password = key_password + self.ca_certs = ca_certs + self.ca_cert_dir = ca_cert_dir + self.ssl_version = ssl_version + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + + def _prepare_conn(self, conn): + """ + Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` + and establish the tunnel if proxy is used. + """ + + if isinstance(conn, VerifiedHTTPSConnection): + conn.set_cert( + key_file=self.key_file, + key_password=self.key_password, + cert_file=self.cert_file, + cert_reqs=self.cert_reqs, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint, + ) + conn.ssl_version = self.ssl_version + return conn + + def _prepare_proxy(self, conn): + """ + Establishes a tunnel connection through HTTP CONNECT. + + Tunnel connection is established early because otherwise httplib would + improperly set Host: header to proxy's IP:port. + """ + + conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers) + + if self.proxy.scheme == "https": + conn.tls_in_tls_required = True + + conn.connect() + + def _new_conn(self): + """ + Return a fresh :class:`http.client.HTTPSConnection`. + """ + self.num_connections += 1 + log.debug( + "Starting new HTTPS connection (%d): %s:%s", + self.num_connections, + self.host, + self.port or "443", + ) + + if not self.ConnectionCls or self.ConnectionCls is DummyConnection: + raise SSLError( + "Can't connect to HTTPS URL because the SSL module is not available." + ) + + actual_host = self.host + actual_port = self.port + if self.proxy is not None: + actual_host = self.proxy.host + actual_port = self.proxy.port + + conn = self.ConnectionCls( + host=actual_host, + port=actual_port, + timeout=self.timeout.connect_timeout, + strict=self.strict, + cert_file=self.cert_file, + key_file=self.key_file, + key_password=self.key_password, + **self.conn_kw + ) + + return self._prepare_conn(conn) + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + super(HTTPSConnectionPool, self)._validate_conn(conn) + + # Force connect early to allow us to validate the connection. + if not getattr(conn, "sock", None): # AppEngine might not have `.sock` + conn.connect() + + if not conn.is_verified: + warnings.warn( + ( + "Unverified HTTPS request is being made to host '%s'. " + "Adding certificate verification is strongly advised. See: " + "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" + "#ssl-warnings" % conn.host + ), + InsecureRequestWarning, + ) + + if getattr(conn, "proxy_is_verified", None) is False: + warnings.warn( + ( + "Unverified HTTPS connection done to an HTTPS proxy. " + "Adding certificate verification is strongly advised. See: " + "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" + "#ssl-warnings" + ), + InsecureRequestWarning, + ) + + +def connection_from_url(url, **kw): + """ + Given a url, return an :class:`.ConnectionPool` instance of its host. + + This is a shortcut for not having to parse out the scheme, host, and port + of the url before creating an :class:`.ConnectionPool` instance. + + :param url: + Absolute URL string that must include the scheme. Port is optional. + + :param \\**kw: + Passes additional parameters to the constructor of the appropriate + :class:`.ConnectionPool`. Useful for specifying things like + timeout, maxsize, headers, etc. + + Example:: + + >>> conn = connection_from_url('http://google.com/') + >>> r = conn.request('GET', '/') + """ + scheme, host, port = get_host(url) + port = port or port_by_scheme.get(scheme, 80) + if scheme == "https": + return HTTPSConnectionPool(host, port=port, **kw) + else: + return HTTPConnectionPool(host, port=port, **kw) + + +def _normalize_host(host, scheme): + """ + Normalize hosts for comparisons and use with sockets. + """ + + host = normalize_host(host, scheme) + + # httplib doesn't like it when we include brackets in IPv6 addresses + # Specifically, if we include brackets but also pass the port then + # httplib crazily doubles up the square brackets on the Host header. + # Instead, we need to make sure we never pass ``None`` as the port. + # However, for backward compatibility reasons we can't actually + # *assert* that. See http://bugs.python.org/issue28539 + if host.startswith("[") and host.endswith("]"): + host = host[1:-1] + return host + + +def _close_pool_connections(pool): + """Drains a queue of connections and closes each one.""" + try: + while True: + conn = pool.get(block=False) + if conn: + conn.close() + except queue.Empty: + pass # Done. diff --git a/lib/urllib3/contrib/__init__.py b/lib/urllib3/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/urllib3/contrib/__pycache__/__init__.cpython-312.pyc b/lib/urllib3/contrib/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..39cba95d89b6fd235fd435902edb5a7934af3654 GIT binary patch literal 188 zcmX@j%ge<81gtFWX(0MBh(HIQS%4zb87dhx8U0o=6fpsLpFwJVMLS!?gche37037_ z0tv^00++;+#2BCaKd+=HGf6)_J~J<~BtBlRpz;@oO>TZlX-=wL5i8IxMj$Q*F+MUgGBOr1 G16csAbTUl< literal 0 HcmV?d00001 diff --git a/lib/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc b/lib/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83cfe63b6a464b7f2c8d1f7ad9990be50f0f3bc7 GIT binary patch literal 1838 zcmdT_&ube;6rS1DuS#+fxyB@>RmU-{tKewCEjENS;MQ^ocGVy|Ef~SF-Wf?NuXdN2 zkz)DeLZO9TdUFefQYe(*Q=pJjq4!>#IES$GQ0O7#mfAh#)HkaiacuVw=!1PbJ8$;Q zH{bi-?(ZWbX#^IJeOdceN9Zs0Ffgq@I4Z(m7g4m1D5jc=*D=+pSE2_0`7Ml%HWwdElu2ewA{&e>1OX{|b;o0bc^!xQ zUW<9Mn0}@JlZ#} zka_D-X72IS`v+5V`>{EmguvOfEJ0)!oka^D2U-RtMa>v2JYf`Hf*Go9zKamhrCU?L zZiNLtmx4I8s8oQGKvj9$^Bk{E950%!Ib29mXCC90bbOBp%cC3qRxzC>U~5og!GHpK zd=2D~P75SqaYjH34bK5q-7XQ*ab1<#8swQF8*ND(8D&$VYTFIsG66uC0A6kBbl40L zem}p;()HU!H2k(py=h52#;8)A-C*`6srekT6{B>5G18DS5Z4UDcKtRj)_uS3vZC#` zjA2m>>f6E)63%6DY7DSP8N%Gc?c1gD&0FP?S-DeQyY+D?O!ewNJ73VFdWM=W!eqbX zJOMmMMdYf^;n?x=n|<#1c?f0U5(L~1`sW2GG4&!o6qBp$rBy2zAgF<_1V)ICa*lW_%bP4yZ=;y?(}~QsxPx zvAuqmf~ewUo`HCHezjEjv{W%yKUrG)Y@t#L(ROx`b(rf1s`rh1F+Kw8_&K#$hwci~ zKt2fZt|J>K_~YuRksF7Bm;<+io@DYrUHgi2YV;6OCLEFwOvVb$&l8hFYdRSfs6po+z^qQ?s zOYn=3KiMW-dfK7LsAoG@%zwv!@UBt&BRQCxYmF>fI9uf04T0`w`vX6A)E; s6a{e4b&T=fnucRXDTLF935@3tQ%Ssn565&od6?Dl^ifvBxoG!)0XhVko&W#< literal 0 HcmV?d00001 diff --git a/lib/urllib3/contrib/__pycache__/appengine.cpython-312.pyc b/lib/urllib3/contrib/__pycache__/appengine.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cc054c5a2d2bb1bebcff8d8128ee26fbc220570 GIT binary patch literal 11530 zcmb_CTWlLwc6a!GiWEgjl&r_dk}T1dD8J%$RNIN4vSL~GM#?4;4A3LaP@+8KXlI7D zrKM6g4N#}A*ysW_(g0P_0QJK8$Y=W1Eb@`;ZqbsK0kX3SU|@p+`zPB9c9Hz_oI4Lv zGLv|VUR%RE_i@g-=bn3BcYYHL`Un)KanN7qjFWfpPSKTh&$zRm8Bf+b znFd;Si=k|ICQR!du`wH&iO{-NY|2JwqO|T4o3kx5El~IK0kJh3n~5>RixdRKwru-M zJ40+la4Z})Nw5A2o%exyEHhm;GDi4@cL*O6JooKJYd38TLu;epwpv-*8iCd(A#Anw z2(g7z`n=lb%uZ-OQ`=&|?uGWVb=v!&{gpcH{m?#9r+wFwy_X0(`iSfV9@uBv-z0y# zbd6lMze%n!@hErFMTl>DKBKT%iO-7yyC_RnGrXX%9J?qO7~ic?CMg zBxw!?9$#E!Pv_<`IblHYU4HG=i8F$lnrEj3`D!L5ut(-qbx|1|8A*v!o=?otNr{w{ z9pM%i1v+npmr}~e;*vTqhrNs(z29gVVszm zJ-}wNi;}Fe7lFp}I*HGW0c<%{&deq(jOHw$T_@d`I>cs_q%|t3a5;Wfx~^l*r0aGL z#z!eaB&-*iu?3*cDXVorVJ!w7zc|j$3iFv94?GoEB_-qp#R7#~V~;)qZ!k_r2%;j? zqODoIj*(*(DRo6qhehG4AhOSes|E<5p?G8<0Vzqy!cX&pq7Dv>ot_>TVh7Akt=Y~2 zm@_>u$O6m3-(@kA&8VE3k#fraSq4UWFH)gM{x~nG9PCVvPg1xFNC&G*lyMeA6+_}+ z6q`{&V3*jOqymq9$lqBYpH0n6D3fVPW|ySA%)(ZSnG~fm!B&Y^=Vd`)rA3{39GzD( zxjCOHb5ibE;Ro5=mtfzN@@$IB;U=)7DUnl@(aYBE8$x!Oy_QkuEkQ_FHIOgldP-8% zVIiFsQflU^z-DrI_LkUGMo#6kipu3ucq$cElyYxrzN^Y z27)1w4pzy7*n&(ci$W@sUZS#Bn?DX`-iSZNcC_A9ad11ikJCI<<(+Hm)9V%-q zijARH*)yVWJp+J!&&|NJF=GT+GejYqQi*2)g^1^5-e-#FmJLVgl=3QY6ogL7r89GR znH~`q4g%#4$PBDEBTKogkW*P}-3j0C(e%U_EyT?#l9*S8q^_SQe{aJMm*&OQpO$4w z*8Es~os)CGUoCi^yZ)-6%1e4*@S-fKQc4o_SI^YcgkB3wXR-oNN8bRE8)SAt%H*Kh z@T#t)&I>?4uRu!xF}x}$iy(gjygMldoMk}yJsNg+kJKoAV`b3l0oc?QrEpbdF?<2? zGypAkh(Kl-@M~;KOx&i$th0VmZzp!hbWHQHPg=A9mC6l_9g?b>F{Ar#O z^`2jlr-!tfLDK{gi zHhfT^JFwPeKF(pK!|KHLEf_7Yk%yithk0hk?ggI>|A80hc!vRx(fJMmf6)a`7jL8g z?1FnC3=_ANw3Bzk3@`72u|D1lPe1R2XJE+|4`^X)C5D#f{C4n&@cf>Xayit+p!Go! zQzr;b!ZYpQ9bnzJ(Fo{c`ZWLAEcved5rpMIhtdPxv zWC@__z%0Xt4^hPjdSA)UF2G#WU>4XKor#75ytx#(K`=R!qf{Xcux?Y$fE$*_1FawS z%V^8#u;#)-2c5s=z{pP3M6u-5k(0Q((ZTny#1X%sa6EJLjR1!1bVy zku%7H4K-=VQr!o1g9i?)x^QuN{KDjvA%rJ{C5d{Q5&%eX;KPHzyJbfVhrrMttblsj zpnP&VWu8ksSq}Jv145oYgvTAC!c#AbU&VG>c;>#LE#GETYxV+!8rutRQ$1$eeKZwN z7^3?18X*g)Y`2vHDKOQs1$%)c-R6*j1Kuo%1>1E-f%s63nEeZ=1Gg2JVc}aMar@+Q z!a7OY1rGfIDpECeFtPlZ$v7CUTX73OJ(tl^7&WKe@JPTL-QuCJ^)!P8TmetV^vDeo zz+>llINumrB{I^8kQ>>T*ncQ-eMA=0aInFN#83-EC@VagSF>Uw9*~hsR9kDFYr1(> zGzZpn%Yj>g#w?S|s9?aNS2;1mgHB4O1X<0b(VrHyFaW2vGbw{r&j^a#fYaQkPM!C>*^LB!sVk6rLkP;BV2k*N{sgV*IYOI;YsI$=_Sc0`$l z#|`pz0}030BZHOj%TMjLriKk-3pQ+eh_~^*;Jd*Mn=SY{v*{wi{!Opb>)UJ~-qy0G zyX5I!b*#=k^du^Mhi^I_dU`7CUi|HR)Y|o+b>zeTe;xkk;hT=X3sB3JGQ9yn2?A@J z2^8=w#Kt=W{gBBsI#LHks(FO#sieBJC}?i1!G38j+BB=+9OSM}5^O3sny{&LIjnd6 zIn1D&a)UeyMRjtlg9d$ggz)ca6u5v)Sg2(YbYLks3oi5Mt~kA<;JVJpoeZ=u7>8dU zr$2e-%8v+v5s>hh;(-2w z7kYzRd+@E`Hq{yQqd0FXAKC94xL15OTseyJwo>q=8QxcLW|)HKL+0<9l>l8kD5pYT zVb8X~@Os~9S_u|{^859vmfL_UL(k5YgKD?g3d+*P`^_}e+YDe!n0?h>K5zwSmTi1+ zg@IjhF6^uJnKj^}tq>@Xj~eb9JF((~kq6BF>Te-n@(Wb&L9=}U_HujSLjW^qQU{}7 zG)K^OLnc-lC|5_#zUnW~)Bro|NIOun3T{69fnDeC6j6_w<6zCl%zE{A;dr%f*7!z~ za`Sg31ZzBL_E&!ab6rjrLgs4ZpFBSwe}GGog3UZN^dy|F(qYzWdHy}zvZe7vnA~dm zz-e-;5SSvpM72zGJy#l%h>a_LwaLOs3VxHWw;>o>@xSH2#?-*5V{8FNd+ zH+g-P$N?3D2U>V%Ep!#F04>mJXqLJ-F}~PV0OuaS>G}?w4O>r3!T*t!%mw%5dGWH_ zkix6Muj-0CwJWN_ubp*agn{R17isx{)uZX$R)C5qK&VpTEilWl&-G|A6T=`07@g4q z^Sh|j{mGgpWqT7$p$Rh{os{uFpNYFQ_ae6>N*u4bbjMZR4IPj?z^qFWk|R0vC3r2Y z=V8E=(A^+K^YGv;KuSuWp2D(Ml_XZgaCrHGfW z@QmB3&xND)^=WQZPqHlgX~JaqcpChaWiNd}?C7-3O8gStF5O`}0vjizrj7SPN(0go zmfwdxnp1@cP^6xv=A?ch_3pH0I@C%Q8F=ZYYR#vNJwAOsB?!F0)0j|3v#o{3bJXnw zUeQ*~4w*(h!+<7O3!aj$t`R);PBMh9^}iiQYG?SZ~mp_4VuAOp1`T!R&$7NWSx9dC^Zk& zc$hkXGTL6v4us2S|LX0U<~NB?Ub!Y8!ck~uHAc{aTi4cTN=bEH0jmj6XrXz?)Ke;w z9LkM?$r$u8Ym4s8zY0Ce)ts5>%mWl$-d{qm@&>rJH^@eeG_{r^y`@O+>e#(E)*^>) zx;GrVy$zM_fd}1F_r}UYM@mCSK4nTn$Kn0cxzDq|%oYP3>#f~)-n#u(CEQerbyQkA zE3xkPgRA>1Y=5Pvzua@E)N|-T&$;5CovXBUmfH@L+75g?w$^r}(jPDPA1n1A+idj4 z8g8E5m}W@Zaptb09DBJGd$|&bKDOK1e3h>L4f-2DNZ)S;H+-bC|3Sy(z0Pucq7cob?Xhx#6b`tG%s<0l@(Ppr4}uAaKrTO2vL)^e&CKJ}=HEjJC6ng;G2 zc+ixnbnd)$X2aobj028x*GQ>rq!Q~|wcpErdT_%|y7xXMw(gc&V;f=87%PVdO5uTf z!H3~P>*1z5-rL?{``(Xxi$6O1Fg(8Ay=zq|4joPQ6}i z8CYw1O?pp`%9Jzg@5^jNA+i-fL z4I3`f(hfU^|J!=t2^2zWm^5_(g-|2jV8ccW33nDf9e>=++92*LhlWd`;U|Rg4z5SK z?y9RlUW*JA0|VcF6>2Sq21=oUC&caTt%TY?NUiq#W4aXTTW=ZKurbX?9z~m|ruSdGKPSUAy zdK(}h1uTtwAB7tM3r3}mV8geY0ZQ|pQfLp-+_fHQzq{`r_7nr1I?mmt&~C(u(<|Xa zpR|<1FMZlr4Qs#MutVp!n+Xy_+CXetyUMM5AGGdW@7irP zEVM%I$O;h6U`HMq_2gSp};ICuwz z{BpsuV1=4hQh28|7K0%)AKMD=Fh{`syK@28zpWH381-r7?Py9>D=_6fYRCjp&rJs? zR=&#|2LYwQZRoAzme^;7hJsCqyRE4-pS=K zUUz^E9ftIl#N)M+n-|iUFJEp{WiF>c=BuVJHJ{I25%_PIp}2!uM$Mj8=5+IT9#9*t z)dsCmk~8q711Exk(`~(;XbEVIV0z(`3BG!fq)(d$IADz-Rj;DYn3b*yngcJaWZXy1 zmXS2~3Cs_VU(nnJ`I=A9g(ZO+&98e1Nm!5&ck2nA;1(Z5egh$yYlozgv36_8)h4gm zsmLjqL=#JfS=KG`E6}=p@Y!_K7KC`4_Kef>HNxuw;krS-@^?J+cY)ewhiffH@x^m% z-4kGyABDPCUwjZ6sziIr(Re8uFYZ24j2?Z|5ifV_D|PHEcf3&Qc%gV`e68aZFrNS@ z(7Eb;;Ez{g@p5dW6dU>2z7{)pbG#C0E(bbFfsVUxq8)kh$iK(_E%s@A?Zt_k=gWbf zQlO`}^Mz92&{rLU8^qJ;gLGdcdZ+z%``z<8rnScXm2hV{JXi`3TGUj~6c3e}h8_oD z&PD?XwLcC)4M^FHl5occafN;BjZNDDnX9qpSGq0M+LmC{6+isC);^O zwK85N4u}SsdWvTX+TlRjCYSl|j%DWHJi=8Ld{Csv8muCyDjZq3laS$?704t*hyuYF z4IJ?18BQ{n7u9MEXG~1Qy)x=SEo9`DlhfnpPhWU#TJvS#s}22w2?&5NAr5J4IAeI5 zC+~zQaxXqm4azUWBW}~(Wej5!+#e$^DxZM*@~&r31-kj$W0y8K0t%i;NZ9%#Kc6eN z442@)f4I`ry6$hjHTS`_hyH;|sO7ztcUOv`LDP3F4xL>O$L<7gLu#67KEr$!9olq* z2Li$q-ErsW?W4s23$t!E=;DLoVivTDRDAviDz)|$1j7Y6aGC+bYfF@ZQc43lu(%A3}LEgBqwnM8z(0GF;wcJd=p~WCd2J z-)MO7Yc#kEQS~4ibvVkG=0HG{!fm1k;Wl0cRKsQk_YSnMu7O{Im*vj-vSzGd7mC;v zjJrYBLv42lK78R}D8AmZ<4*2&ZuRw#uYVE!uZ~}JJZ$;N&9O)R$a^pS^-Fi>{z-ga zyf;@)9D9&BwjPM0!;OCEIP+C_5abLTXmCMW4e5$ICMTz-<3Sm%zKj_fHNeKjVx(aoL>B;O;j>uoM2{s8&7ddD^(hI6I&4_MJ}Ole3K9+4{5{ z9`uY*B=G_HXMh4fxk%?#_{0aOM}Eum*y@JR8tnNT-6G8gmm-4x(U**8N=E%Dqqirc z#+1>k)6);#i(KjodazYE#e%q);Yv0T-9kmFwV!lGG@nd)-q~#g^CYimORkm&JH=ZNH3oF z{F1O64m%V5(lHD=&>g!mS9Z0QT&;IKYp$Lf_DvVVc<=sflfciW2kUPd^;tX9dh4xC zg1;M+ZW7*E4kb#V#0`jln7 wJ5hrFq~(trc{lMiK}g0#;r8wAv$&4vHwr4HU;11p3Hgk;Px|bic^P>AFBZRN8UO$Q literal 0 HcmV?d00001 diff --git a/lib/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc b/lib/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d671e86f21b7d1a5525c02bbb253842cbaf52695 GIT binary patch literal 5709 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 YnPq45tbN^?peVM`-1QwI1B2#20Xa-TA^-pY literal 0 HcmV?d00001 diff --git a/lib/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc b/lib/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6acb3f363a81f992bb643ec92813287cda0d20f7 GIT binary patch literal 24407 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 Kv7hxa(Ecx%HF$;q literal 0 HcmV?d00001 diff --git a/lib/urllib3/contrib/_appengine_environ.py b/lib/urllib3/contrib/_appengine_environ.py new file mode 100644 index 0000000..8765b90 --- /dev/null +++ b/lib/urllib3/contrib/_appengine_environ.py @@ -0,0 +1,36 @@ +""" +This module provides means to detect the App Engine environment. +""" + +import os + + +def is_appengine(): + return is_local_appengine() or is_prod_appengine() + + +def is_appengine_sandbox(): + """Reports if the app is running in the first generation sandbox. + + The second generation runtimes are technically still in a sandbox, but it + is much less restrictive, so generally you shouldn't need to check for it. + see https://cloud.google.com/appengine/docs/standard/runtimes + """ + return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27" + + +def is_local_appengine(): + return "APPENGINE_RUNTIME" in os.environ and os.environ.get( + "SERVER_SOFTWARE", "" + ).startswith("Development/") + + +def is_prod_appengine(): + return "APPENGINE_RUNTIME" in os.environ and os.environ.get( + "SERVER_SOFTWARE", "" + ).startswith("Google App Engine/") + + +def is_prod_appengine_mvms(): + """Deprecated.""" + return False diff --git a/lib/urllib3/contrib/_securetransport/__init__.py b/lib/urllib3/contrib/_securetransport/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc b/lib/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..301ac53039075297f1995823c2505748c2dfdd28 GIT binary patch literal 205 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 JTNduH|6kp0)2aXf literal 0 HcmV?d00001 diff --git a/lib/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc b/lib/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5f7dd86167d2b9143861f74e3cd334ec587c6710 GIT binary patch literal 14791 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 + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +""" +from __future__ import absolute_import + +import platform +from ctypes import ( + CDLL, + CFUNCTYPE, + POINTER, + c_bool, + c_byte, + c_char_p, + c_int32, + c_long, + c_size_t, + c_uint32, + c_ulong, + c_void_p, +) +from ctypes.util import find_library + +from ...packages.six import raise_from + +if platform.system() != "Darwin": + raise ImportError("Only macOS is supported") + +version = platform.mac_ver()[0] +version_info = tuple(map(int, version.split("."))) +if version_info < (10, 8): + raise OSError( + "Only OS X 10.8 and newer are supported, not %s.%s" + % (version_info[0], version_info[1]) + ) + + +def load_cdll(name, macos10_16_path): + """Loads a CDLL by name, falling back to known path on 10.16+""" + try: + # Big Sur is technically 11 but we use 10.16 due to the Big Sur + # beta being labeled as 10.16. + if version_info >= (10, 16): + path = macos10_16_path + else: + path = find_library(name) + if not path: + raise OSError # Caught and reraised as 'ImportError' + return CDLL(path, use_errno=True) + except OSError: + raise_from(ImportError("The library %s failed to load" % name), None) + + +Security = load_cdll( + "Security", "/System/Library/Frameworks/Security.framework/Security" +) +CoreFoundation = load_cdll( + "CoreFoundation", + "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", +) + + +Boolean = c_bool +CFIndex = c_long +CFStringEncoding = c_uint32 +CFData = c_void_p +CFString = c_void_p +CFArray = c_void_p +CFMutableArray = c_void_p +CFDictionary = c_void_p +CFError = c_void_p +CFType = c_void_p +CFTypeID = c_ulong + +CFTypeRef = POINTER(CFType) +CFAllocatorRef = c_void_p + +OSStatus = c_int32 + +CFDataRef = POINTER(CFData) +CFStringRef = POINTER(CFString) +CFArrayRef = POINTER(CFArray) +CFMutableArrayRef = POINTER(CFMutableArray) +CFDictionaryRef = POINTER(CFDictionary) +CFArrayCallBacks = c_void_p +CFDictionaryKeyCallBacks = c_void_p +CFDictionaryValueCallBacks = c_void_p + +SecCertificateRef = POINTER(c_void_p) +SecExternalFormat = c_uint32 +SecExternalItemType = c_uint32 +SecIdentityRef = POINTER(c_void_p) +SecItemImportExportFlags = c_uint32 +SecItemImportExportKeyParameters = c_void_p +SecKeychainRef = POINTER(c_void_p) +SSLProtocol = c_uint32 +SSLCipherSuite = c_uint32 +SSLContextRef = POINTER(c_void_p) +SecTrustRef = POINTER(c_void_p) +SSLConnectionRef = c_uint32 +SecTrustResultType = c_uint32 +SecTrustOptionFlags = c_uint32 +SSLProtocolSide = c_uint32 +SSLConnectionType = c_uint32 +SSLSessionOption = c_uint32 + + +try: + Security.SecItemImport.argtypes = [ + CFDataRef, + CFStringRef, + POINTER(SecExternalFormat), + POINTER(SecExternalItemType), + SecItemImportExportFlags, + POINTER(SecItemImportExportKeyParameters), + SecKeychainRef, + POINTER(CFArrayRef), + ] + Security.SecItemImport.restype = OSStatus + + Security.SecCertificateGetTypeID.argtypes = [] + Security.SecCertificateGetTypeID.restype = CFTypeID + + Security.SecIdentityGetTypeID.argtypes = [] + Security.SecIdentityGetTypeID.restype = CFTypeID + + Security.SecKeyGetTypeID.argtypes = [] + Security.SecKeyGetTypeID.restype = CFTypeID + + Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef] + Security.SecCertificateCreateWithData.restype = SecCertificateRef + + Security.SecCertificateCopyData.argtypes = [SecCertificateRef] + Security.SecCertificateCopyData.restype = CFDataRef + + Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SecIdentityCreateWithCertificate.argtypes = [ + CFTypeRef, + SecCertificateRef, + POINTER(SecIdentityRef), + ] + Security.SecIdentityCreateWithCertificate.restype = OSStatus + + Security.SecKeychainCreate.argtypes = [ + c_char_p, + c_uint32, + c_void_p, + Boolean, + c_void_p, + POINTER(SecKeychainRef), + ] + Security.SecKeychainCreate.restype = OSStatus + + Security.SecKeychainDelete.argtypes = [SecKeychainRef] + Security.SecKeychainDelete.restype = OSStatus + + Security.SecPKCS12Import.argtypes = [ + CFDataRef, + CFDictionaryRef, + POINTER(CFArrayRef), + ] + Security.SecPKCS12Import.restype = OSStatus + + SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) + SSLWriteFunc = CFUNCTYPE( + OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t) + ) + + Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc] + Security.SSLSetIOFuncs.restype = OSStatus + + Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t] + Security.SSLSetPeerID.restype = OSStatus + + Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef] + Security.SSLSetCertificate.restype = OSStatus + + Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean] + Security.SSLSetCertificateAuthorities.restype = OSStatus + + Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef] + Security.SSLSetConnection.restype = OSStatus + + Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t] + Security.SSLSetPeerDomainName.restype = OSStatus + + Security.SSLHandshake.argtypes = [SSLContextRef] + Security.SSLHandshake.restype = OSStatus + + Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] + Security.SSLRead.restype = OSStatus + + Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] + Security.SSLWrite.restype = OSStatus + + Security.SSLClose.argtypes = [SSLContextRef] + Security.SSLClose.restype = OSStatus + + Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)] + Security.SSLGetNumberSupportedCiphers.restype = OSStatus + + Security.SSLGetSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t), + ] + Security.SSLGetSupportedCiphers.restype = OSStatus + + Security.SSLSetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + c_size_t, + ] + Security.SSLSetEnabledCiphers.restype = OSStatus + + Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)] + Security.SSLGetNumberEnabledCiphers.restype = OSStatus + + Security.SSLGetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t), + ] + Security.SSLGetEnabledCiphers.restype = OSStatus + + Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)] + Security.SSLGetNegotiatedCipher.restype = OSStatus + + Security.SSLGetNegotiatedProtocolVersion.argtypes = [ + SSLContextRef, + POINTER(SSLProtocol), + ] + Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus + + Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)] + Security.SSLCopyPeerTrust.restype = OSStatus + + Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef] + Security.SecTrustSetAnchorCertificates.restype = OSStatus + + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean] + Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus + + Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)] + Security.SecTrustEvaluate.restype = OSStatus + + Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef] + Security.SecTrustGetCertificateCount.restype = CFIndex + + Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex] + Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef + + Security.SSLCreateContext.argtypes = [ + CFAllocatorRef, + SSLProtocolSide, + SSLConnectionType, + ] + Security.SSLCreateContext.restype = SSLContextRef + + Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean] + Security.SSLSetSessionOption.restype = OSStatus + + Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol] + Security.SSLSetProtocolVersionMin.restype = OSStatus + + Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol] + Security.SSLSetProtocolVersionMax.restype = OSStatus + + try: + Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef] + Security.SSLSetALPNProtocols.restype = OSStatus + except AttributeError: + # Supported only in 10.12+ + pass + + Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SSLReadFunc = SSLReadFunc + Security.SSLWriteFunc = SSLWriteFunc + Security.SSLContextRef = SSLContextRef + Security.SSLProtocol = SSLProtocol + Security.SSLCipherSuite = SSLCipherSuite + Security.SecIdentityRef = SecIdentityRef + Security.SecKeychainRef = SecKeychainRef + Security.SecTrustRef = SecTrustRef + Security.SecTrustResultType = SecTrustResultType + Security.SecExternalFormat = SecExternalFormat + Security.OSStatus = OSStatus + + Security.kSecImportExportPassphrase = CFStringRef.in_dll( + Security, "kSecImportExportPassphrase" + ) + Security.kSecImportItemIdentity = CFStringRef.in_dll( + Security, "kSecImportItemIdentity" + ) + + # CoreFoundation time! + CoreFoundation.CFRetain.argtypes = [CFTypeRef] + CoreFoundation.CFRetain.restype = CFTypeRef + + CoreFoundation.CFRelease.argtypes = [CFTypeRef] + CoreFoundation.CFRelease.restype = None + + CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef] + CoreFoundation.CFGetTypeID.restype = CFTypeID + + CoreFoundation.CFStringCreateWithCString.argtypes = [ + CFAllocatorRef, + c_char_p, + CFStringEncoding, + ] + CoreFoundation.CFStringCreateWithCString.restype = CFStringRef + + CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding] + CoreFoundation.CFStringGetCStringPtr.restype = c_char_p + + CoreFoundation.CFStringGetCString.argtypes = [ + CFStringRef, + c_char_p, + CFIndex, + CFStringEncoding, + ] + CoreFoundation.CFStringGetCString.restype = c_bool + + CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex] + CoreFoundation.CFDataCreate.restype = CFDataRef + + CoreFoundation.CFDataGetLength.argtypes = [CFDataRef] + CoreFoundation.CFDataGetLength.restype = CFIndex + + CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef] + CoreFoundation.CFDataGetBytePtr.restype = c_void_p + + CoreFoundation.CFDictionaryCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + POINTER(CFTypeRef), + CFIndex, + CFDictionaryKeyCallBacks, + CFDictionaryValueCallBacks, + ] + CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef + + CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef] + CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef + + CoreFoundation.CFArrayCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreate.restype = CFArrayRef + + CoreFoundation.CFArrayCreateMutable.argtypes = [ + CFAllocatorRef, + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef + + CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p] + CoreFoundation.CFArrayAppendValue.restype = None + + CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef] + CoreFoundation.CFArrayGetCount.restype = CFIndex + + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex] + CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p + + CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( + CoreFoundation, "kCFAllocatorDefault" + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll( + CoreFoundation, "kCFTypeArrayCallBacks" + ) + CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( + CoreFoundation, "kCFTypeDictionaryKeyCallBacks" + ) + CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( + CoreFoundation, "kCFTypeDictionaryValueCallBacks" + ) + + CoreFoundation.CFTypeRef = CFTypeRef + CoreFoundation.CFArrayRef = CFArrayRef + CoreFoundation.CFStringRef = CFStringRef + CoreFoundation.CFDictionaryRef = CFDictionaryRef + +except (AttributeError): + raise ImportError("Error initializing ctypes") + + +class CFConst(object): + """ + A class object that acts as essentially a namespace for CoreFoundation + constants. + """ + + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) + + +class SecurityConst(object): + """ + A class object that acts as essentially a namespace for Security constants. + """ + + kSSLSessionOptionBreakOnServerAuth = 0 + + kSSLProtocol2 = 1 + kSSLProtocol3 = 2 + kTLSProtocol1 = 4 + kTLSProtocol11 = 7 + kTLSProtocol12 = 8 + # SecureTransport does not support TLS 1.3 even if there's a constant for it + kTLSProtocol13 = 10 + kTLSProtocolMaxSupported = 999 + + kSSLClientSide = 1 + kSSLStreamType = 0 + + kSecFormatPEMSequence = 10 + + kSecTrustResultInvalid = 0 + kSecTrustResultProceed = 1 + # This gap is present on purpose: this was kSecTrustResultConfirm, which + # is deprecated. + kSecTrustResultDeny = 3 + kSecTrustResultUnspecified = 4 + kSecTrustResultRecoverableTrustFailure = 5 + kSecTrustResultFatalTrustFailure = 6 + kSecTrustResultOtherError = 7 + + errSSLProtocol = -9800 + errSSLWouldBlock = -9803 + errSSLClosedGraceful = -9805 + errSSLClosedNoNotify = -9816 + errSSLClosedAbort = -9806 + + errSSLXCertChainInvalid = -9807 + errSSLCrypto = -9809 + errSSLInternal = -9810 + errSSLCertExpired = -9814 + errSSLCertNotYetValid = -9815 + errSSLUnknownRootCert = -9812 + errSSLNoRootCert = -9813 + errSSLHostNameMismatch = -9843 + errSSLPeerHandshakeFail = -9824 + errSSLPeerUserCancelled = -9839 + errSSLWeakPeerEphemeralDHKey = -9850 + errSSLServerAuthCompleted = -9841 + errSSLRecordOverflow = -9847 + + errSecVerifyFailed = -67808 + errSecNoTrustSettings = -25263 + errSecItemNotFound = -25300 + errSecInvalidTrustSettings = -25262 + + # Cipher suites. We only pick the ones our default cipher string allows. + # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F + TLS_AES_128_GCM_SHA256 = 0x1301 + TLS_AES_256_GCM_SHA384 = 0x1302 + TLS_AES_128_CCM_8_SHA256 = 0x1305 + TLS_AES_128_CCM_SHA256 = 0x1304 diff --git a/lib/urllib3/contrib/_securetransport/low_level.py b/lib/urllib3/contrib/_securetransport/low_level.py new file mode 100644 index 0000000..fa0b245 --- /dev/null +++ b/lib/urllib3/contrib/_securetransport/low_level.py @@ -0,0 +1,397 @@ +""" +Low-level helpers for the SecureTransport bindings. + +These are Python functions that are not directly related to the high-level APIs +but are necessary to get them to work. They include a whole bunch of low-level +CoreFoundation messing about and memory management. The concerns in this module +are almost entirely about trying to avoid memory leaks and providing +appropriate and useful assistance to the higher-level code. +""" +import base64 +import ctypes +import itertools +import os +import re +import ssl +import struct +import tempfile + +from .bindings import CFConst, CoreFoundation, Security + +# This regular expression is used to grab PEM data out of a PEM bundle. +_PEM_CERTS_RE = re.compile( + b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL +) + + +def _cf_data_from_bytes(bytestring): + """ + Given a bytestring, create a CFData object from it. This CFData object must + be CFReleased by the caller. + """ + return CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) + ) + + +def _cf_dictionary_from_tuples(tuples): + """ + Given a list of Python tuples, create an associated CFDictionary. + """ + dictionary_size = len(tuples) + + # We need to get the dictionary keys and values out in the same order. + keys = (t[0] for t in tuples) + values = (t[1] for t in tuples) + cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) + cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) + + return CoreFoundation.CFDictionaryCreate( + CoreFoundation.kCFAllocatorDefault, + cf_keys, + cf_values, + dictionary_size, + CoreFoundation.kCFTypeDictionaryKeyCallBacks, + CoreFoundation.kCFTypeDictionaryValueCallBacks, + ) + + +def _cfstr(py_bstr): + """ + Given a Python binary data, create a CFString. + The string must be CFReleased by the caller. + """ + c_str = ctypes.c_char_p(py_bstr) + cf_str = CoreFoundation.CFStringCreateWithCString( + CoreFoundation.kCFAllocatorDefault, + c_str, + CFConst.kCFStringEncodingUTF8, + ) + return cf_str + + +def _create_cfstring_array(lst): + """ + Given a list of Python binary data, create an associated CFMutableArray. + The array must be CFReleased by the caller. + + Raises an ssl.SSLError on failure. + """ + cf_arr = None + try: + cf_arr = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + if not cf_arr: + raise MemoryError("Unable to allocate memory!") + for item in lst: + cf_str = _cfstr(item) + if not cf_str: + raise MemoryError("Unable to allocate memory!") + try: + CoreFoundation.CFArrayAppendValue(cf_arr, cf_str) + finally: + CoreFoundation.CFRelease(cf_str) + except BaseException as e: + if cf_arr: + CoreFoundation.CFRelease(cf_arr) + raise ssl.SSLError("Unable to allocate array: %s" % (e,)) + return cf_arr + + +def _cf_string_to_unicode(value): + """ + Creates a Unicode string from a CFString object. Used entirely for error + reporting. + + Yes, it annoys me quite a lot that this function is this complex. + """ + value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) + + string = CoreFoundation.CFStringGetCStringPtr( + value_as_void_p, CFConst.kCFStringEncodingUTF8 + ) + if string is None: + buffer = ctypes.create_string_buffer(1024) + result = CoreFoundation.CFStringGetCString( + value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8 + ) + if not result: + raise OSError("Error copying C string from CFStringRef") + string = buffer.value + if string is not None: + string = string.decode("utf-8") + return string + + +def _assert_no_error(error, exception_class=None): + """ + Checks the return code and throws an exception if there is an error to + report + """ + if error == 0: + return + + cf_error_string = Security.SecCopyErrorMessageString(error, None) + output = _cf_string_to_unicode(cf_error_string) + CoreFoundation.CFRelease(cf_error_string) + + if output is None or output == u"": + output = u"OSStatus %s" % error + + if exception_class is None: + exception_class = ssl.SSLError + + raise exception_class(output) + + +def _cert_array_from_pem(pem_bundle): + """ + Given a bundle of certs in PEM format, turns them into a CFArray of certs + that can be used to validate a cert chain. + """ + # Normalize the PEM bundle's line endings. + pem_bundle = pem_bundle.replace(b"\r\n", b"\n") + + der_certs = [ + base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle) + ] + if not der_certs: + raise ssl.SSLError("No root certificates specified") + + cert_array = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + if not cert_array: + raise ssl.SSLError("Unable to allocate memory!") + + try: + for der_bytes in der_certs: + certdata = _cf_data_from_bytes(der_bytes) + if not certdata: + raise ssl.SSLError("Unable to allocate memory!") + cert = Security.SecCertificateCreateWithData( + CoreFoundation.kCFAllocatorDefault, certdata + ) + CoreFoundation.CFRelease(certdata) + if not cert: + raise ssl.SSLError("Unable to build cert object!") + + CoreFoundation.CFArrayAppendValue(cert_array, cert) + CoreFoundation.CFRelease(cert) + except Exception: + # We need to free the array before the exception bubbles further. + # We only want to do that if an error occurs: otherwise, the caller + # should free. + CoreFoundation.CFRelease(cert_array) + raise + + return cert_array + + +def _is_cert(item): + """ + Returns True if a given CFTypeRef is a certificate. + """ + expected = Security.SecCertificateGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _is_identity(item): + """ + Returns True if a given CFTypeRef is an identity. + """ + expected = Security.SecIdentityGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _temporary_keychain(): + """ + This function creates a temporary Mac keychain that we can use to work with + credentials. This keychain uses a one-time password and a temporary file to + store the data. We expect to have one keychain per socket. The returned + SecKeychainRef must be freed by the caller, including calling + SecKeychainDelete. + + Returns a tuple of the SecKeychainRef and the path to the temporary + directory that contains it. + """ + # Unfortunately, SecKeychainCreate requires a path to a keychain. This + # means we cannot use mkstemp to use a generic temporary file. Instead, + # we're going to create a temporary directory and a filename to use there. + # This filename will be 8 random bytes expanded into base64. We also need + # some random bytes to password-protect the keychain we're creating, so we + # ask for 40 random bytes. + random_bytes = os.urandom(40) + filename = base64.b16encode(random_bytes[:8]).decode("utf-8") + password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 + tempdirectory = tempfile.mkdtemp() + + keychain_path = os.path.join(tempdirectory, filename).encode("utf-8") + + # We now want to create the keychain itself. + keychain = Security.SecKeychainRef() + status = Security.SecKeychainCreate( + keychain_path, len(password), password, False, None, ctypes.byref(keychain) + ) + _assert_no_error(status) + + # Having created the keychain, we want to pass it off to the caller. + return keychain, tempdirectory + + +def _load_items_from_file(keychain, path): + """ + Given a single file, loads all the trust objects from it into arrays and + the keychain. + Returns a tuple of lists: the first list is a list of identities, the + second a list of certs. + """ + certificates = [] + identities = [] + result_array = None + + with open(path, "rb") as f: + raw_filedata = f.read() + + try: + filedata = CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata) + ) + result_array = CoreFoundation.CFArrayRef() + result = Security.SecItemImport( + filedata, # cert data + None, # Filename, leaving it out for now + None, # What the type of the file is, we don't care + None, # what's in the file, we don't care + 0, # import flags + None, # key params, can include passphrase in the future + keychain, # The keychain to insert into + ctypes.byref(result_array), # Results + ) + _assert_no_error(result) + + # A CFArray is not very useful to us as an intermediary + # representation, so we are going to extract the objects we want + # and then free the array. We don't need to keep hold of keys: the + # keychain already has them! + result_count = CoreFoundation.CFArrayGetCount(result_array) + for index in range(result_count): + item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index) + item = ctypes.cast(item, CoreFoundation.CFTypeRef) + + if _is_cert(item): + CoreFoundation.CFRetain(item) + certificates.append(item) + elif _is_identity(item): + CoreFoundation.CFRetain(item) + identities.append(item) + finally: + if result_array: + CoreFoundation.CFRelease(result_array) + + CoreFoundation.CFRelease(filedata) + + return (identities, certificates) + + +def _load_client_cert_chain(keychain, *paths): + """ + Load certificates and maybe keys from a number of files. Has the end goal + of returning a CFArray containing one SecIdentityRef, and then zero or more + SecCertificateRef objects, suitable for use as a client certificate trust + chain. + """ + # Ok, the strategy. + # + # This relies on knowing that macOS will not give you a SecIdentityRef + # unless you have imported a key into a keychain. This is a somewhat + # artificial limitation of macOS (for example, it doesn't necessarily + # affect iOS), but there is nothing inside Security.framework that lets you + # get a SecIdentityRef without having a key in a keychain. + # + # So the policy here is we take all the files and iterate them in order. + # Each one will use SecItemImport to have one or more objects loaded from + # it. We will also point at a keychain that macOS can use to work with the + # private key. + # + # Once we have all the objects, we'll check what we actually have. If we + # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, + # we'll take the first certificate (which we assume to be our leaf) and + # ask the keychain to give us a SecIdentityRef with that cert's associated + # key. + # + # We'll then return a CFArray containing the trust chain: one + # SecIdentityRef and then zero-or-more SecCertificateRef objects. The + # responsibility for freeing this CFArray will be with the caller. This + # CFArray must remain alive for the entire connection, so in practice it + # will be stored with a single SSLSocket, along with the reference to the + # keychain. + certificates = [] + identities = [] + + # Filter out bad paths. + paths = (path for path in paths if path) + + try: + for file_path in paths: + new_identities, new_certs = _load_items_from_file(keychain, file_path) + identities.extend(new_identities) + certificates.extend(new_certs) + + # Ok, we have everything. The question is: do we have an identity? If + # not, we want to grab one from the first cert we have. + if not identities: + new_identity = Security.SecIdentityRef() + status = Security.SecIdentityCreateWithCertificate( + keychain, certificates[0], ctypes.byref(new_identity) + ) + _assert_no_error(status) + identities.append(new_identity) + + # We now want to release the original certificate, as we no longer + # need it. + CoreFoundation.CFRelease(certificates.pop(0)) + + # We now need to build a new CFArray that holds the trust chain. + trust_chain = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + for item in itertools.chain(identities, certificates): + # ArrayAppendValue does a CFRetain on the item. That's fine, + # because the finally block will release our other refs to them. + CoreFoundation.CFArrayAppendValue(trust_chain, item) + + return trust_chain + finally: + for obj in itertools.chain(identities, certificates): + CoreFoundation.CFRelease(obj) + + +TLS_PROTOCOL_VERSIONS = { + "SSLv2": (0, 2), + "SSLv3": (3, 0), + "TLSv1": (3, 1), + "TLSv1.1": (3, 2), + "TLSv1.2": (3, 3), +} + + +def _build_tls_unknown_ca_alert(version): + """ + Builds a TLS alert record for an unknown CA. + """ + ver_maj, ver_min = TLS_PROTOCOL_VERSIONS[version] + severity_fatal = 0x02 + description_unknown_ca = 0x30 + msg = struct.pack(">BB", severity_fatal, description_unknown_ca) + msg_len = len(msg) + record_type_alert = 0x15 + record = struct.pack(">BBBH", record_type_alert, ver_maj, ver_min, msg_len) + msg + return record diff --git a/lib/urllib3/contrib/appengine.py b/lib/urllib3/contrib/appengine.py new file mode 100644 index 0000000..a5a6d91 --- /dev/null +++ b/lib/urllib3/contrib/appengine.py @@ -0,0 +1,314 @@ +""" +This module provides a pool manager that uses Google App Engine's +`URLFetch Service `_. + +Example usage:: + + from urllib3 import PoolManager + from urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox + + if is_appengine_sandbox(): + # AppEngineManager uses AppEngine's URLFetch API behind the scenes + http = AppEngineManager() + else: + # PoolManager uses a socket-level API behind the scenes + http = PoolManager() + + r = http.request('GET', 'https://google.com/') + +There are `limitations `_ to the URLFetch service and it may not be +the best choice for your application. There are three options for using +urllib3 on Google App Engine: + +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is + cost-effective in many circumstances as long as your usage is within the + limitations. +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. + Sockets also have `limitations and restrictions + `_ and have a lower free quota than URLFetch. + To use sockets, be sure to specify the following in your ``app.yaml``:: + + env_variables: + GAE_USE_SOCKETS_HTTPLIB : 'true' + +3. If you are using `App Engine Flexible +`_, you can use the standard +:class:`PoolManager` without any configuration or special environment variables. +""" + +from __future__ import absolute_import + +import io +import logging +import warnings + +from ..exceptions import ( + HTTPError, + HTTPWarning, + MaxRetryError, + ProtocolError, + SSLError, + TimeoutError, +) +from ..packages.six.moves.urllib.parse import urljoin +from ..request import RequestMethods +from ..response import HTTPResponse +from ..util.retry import Retry +from ..util.timeout import Timeout +from . import _appengine_environ + +try: + from google.appengine.api import urlfetch +except ImportError: + urlfetch = None + + +log = logging.getLogger(__name__) + + +class AppEnginePlatformWarning(HTTPWarning): + pass + + +class AppEnginePlatformError(HTTPError): + pass + + +class AppEngineManager(RequestMethods): + """ + Connection manager for Google App Engine sandbox applications. + + This manager uses the URLFetch service directly instead of using the + emulated httplib, and is subject to URLFetch limitations as described in + the App Engine documentation `here + `_. + + Notably it will raise an :class:`AppEnginePlatformError` if: + * URLFetch is not available. + * If you attempt to use this on App Engine Flexible, as full socket + support is available. + * If a request size is more than 10 megabytes. + * If a response size is more than 32 megabytes. + * If you use an unsupported request method such as OPTIONS. + + Beyond those cases, it will raise normal urllib3 errors. + """ + + def __init__( + self, + headers=None, + retries=None, + validate_certificate=True, + urlfetch_retries=True, + ): + if not urlfetch: + raise AppEnginePlatformError( + "URLFetch is not available in this environment." + ) + + warnings.warn( + "urllib3 is using URLFetch on Google App Engine sandbox instead " + "of sockets. To use sockets directly instead of URLFetch see " + "https://urllib3.readthedocs.io/en/1.26.x/reference/urllib3.contrib.html.", + AppEnginePlatformWarning, + ) + + RequestMethods.__init__(self, headers) + self.validate_certificate = validate_certificate + self.urlfetch_retries = urlfetch_retries + + self.retries = retries or Retry.DEFAULT + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + # Return False to re-raise any potential exceptions + return False + + def urlopen( + self, + method, + url, + body=None, + headers=None, + retries=None, + redirect=True, + timeout=Timeout.DEFAULT_TIMEOUT, + **response_kw + ): + + retries = self._get_retries(retries, redirect) + + try: + follow_redirects = redirect and retries.redirect != 0 and retries.total + response = urlfetch.fetch( + url, + payload=body, + method=method, + headers=headers or {}, + allow_truncated=False, + follow_redirects=self.urlfetch_retries and follow_redirects, + deadline=self._get_absolute_timeout(timeout), + validate_certificate=self.validate_certificate, + ) + except urlfetch.DeadlineExceededError as e: + raise TimeoutError(self, e) + + except urlfetch.InvalidURLError as e: + if "too large" in str(e): + raise AppEnginePlatformError( + "URLFetch request too large, URLFetch only " + "supports requests up to 10mb in size.", + e, + ) + raise ProtocolError(e) + + except urlfetch.DownloadError as e: + if "Too many redirects" in str(e): + raise MaxRetryError(self, url, reason=e) + raise ProtocolError(e) + + except urlfetch.ResponseTooLargeError as e: + raise AppEnginePlatformError( + "URLFetch response too large, URLFetch only supports" + "responses up to 32mb in size.", + e, + ) + + except urlfetch.SSLCertificateError as e: + raise SSLError(e) + + except urlfetch.InvalidMethodError as e: + raise AppEnginePlatformError( + "URLFetch does not support method: %s" % method, e + ) + + http_response = self._urlfetch_response_to_http_response( + response, retries=retries, **response_kw + ) + + # Handle redirect? + redirect_location = redirect and http_response.get_redirect_location() + if redirect_location: + # Check for redirect response + if self.urlfetch_retries and retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + else: + if http_response.status == 303: + method = "GET" + + try: + retries = retries.increment( + method, url, response=http_response, _pool=self + ) + except MaxRetryError: + if retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + return http_response + + retries.sleep_for_retry(http_response) + log.debug("Redirecting %s -> %s", url, redirect_location) + redirect_url = urljoin(url, redirect_location) + return self.urlopen( + method, + redirect_url, + body, + headers, + retries=retries, + redirect=redirect, + timeout=timeout, + **response_kw + ) + + # Check if we should retry the HTTP response. + has_retry_after = bool(http_response.headers.get("Retry-After")) + if retries.is_retry(method, http_response.status, has_retry_after): + retries = retries.increment(method, url, response=http_response, _pool=self) + log.debug("Retry: %s", url) + retries.sleep(http_response) + return self.urlopen( + method, + url, + body=body, + headers=headers, + retries=retries, + redirect=redirect, + timeout=timeout, + **response_kw + ) + + return http_response + + def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): + + if is_prod_appengine(): + # Production GAE handles deflate encoding automatically, but does + # not remove the encoding header. + content_encoding = urlfetch_resp.headers.get("content-encoding") + + if content_encoding == "deflate": + del urlfetch_resp.headers["content-encoding"] + + transfer_encoding = urlfetch_resp.headers.get("transfer-encoding") + # We have a full response's content, + # so let's make sure we don't report ourselves as chunked data. + if transfer_encoding == "chunked": + encodings = transfer_encoding.split(",") + encodings.remove("chunked") + urlfetch_resp.headers["transfer-encoding"] = ",".join(encodings) + + original_response = HTTPResponse( + # In order for decoding to work, we must present the content as + # a file-like object. + body=io.BytesIO(urlfetch_resp.content), + msg=urlfetch_resp.header_msg, + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + **response_kw + ) + + return HTTPResponse( + body=io.BytesIO(urlfetch_resp.content), + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + original_response=original_response, + **response_kw + ) + + def _get_absolute_timeout(self, timeout): + if timeout is Timeout.DEFAULT_TIMEOUT: + return None # Defer to URLFetch's default. + if isinstance(timeout, Timeout): + if timeout._read is not None or timeout._connect is not None: + warnings.warn( + "URLFetch does not support granular timeout settings, " + "reverting to total or default URLFetch timeout.", + AppEnginePlatformWarning, + ) + return timeout.total + return timeout + + def _get_retries(self, retries, redirect): + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if retries.connect or retries.read or retries.redirect: + warnings.warn( + "URLFetch only supports total retries and does not " + "recognize connect, read, or redirect retry parameters.", + AppEnginePlatformWarning, + ) + + return retries + + +# Alias methods from _appengine_environ to maintain public API interface. + +is_appengine = _appengine_environ.is_appengine +is_appengine_sandbox = _appengine_environ.is_appengine_sandbox +is_local_appengine = _appengine_environ.is_local_appengine +is_prod_appengine = _appengine_environ.is_prod_appengine +is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms diff --git a/lib/urllib3/contrib/ntlmpool.py b/lib/urllib3/contrib/ntlmpool.py new file mode 100644 index 0000000..4716657 --- /dev/null +++ b/lib/urllib3/contrib/ntlmpool.py @@ -0,0 +1,130 @@ +""" +NTLM authenticating pool, contributed by erikcederstran + +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 +""" +from __future__ import absolute_import + +import warnings +from logging import getLogger + +from ntlm import ntlm + +from .. import HTTPSConnectionPool +from ..packages.six.moves.http_client import HTTPSConnection + +warnings.warn( + "The 'urllib3.contrib.ntlmpool' module is deprecated and will be removed " + "in urllib3 v2.0 release, urllib3 is not able to support it properly due " + "to reasons listed in issue: https://github.com/urllib3/urllib3/issues/2282. " + "If you are a user of this module please comment in the mentioned issue.", + DeprecationWarning, +) + +log = getLogger(__name__) + + +class NTLMConnectionPool(HTTPSConnectionPool): + """ + Implements an NTLM authentication version of an urllib3 connection pool + """ + + scheme = "https" + + def __init__(self, user, pw, authurl, *args, **kwargs): + """ + authurl is a random URL on the server that is protected by NTLM. + user is the Windows user, probably in the DOMAIN\\username format. + pw is the password for the user. + """ + super(NTLMConnectionPool, self).__init__(*args, **kwargs) + self.authurl = authurl + self.rawuser = user + user_parts = user.split("\\", 1) + self.domain = user_parts[0].upper() + self.user = user_parts[1] + self.pw = pw + + def _new_conn(self): + # Performs the NTLM handshake that secures the connection. The socket + # must be kept open while requests are performed. + self.num_connections += 1 + log.debug( + "Starting NTLM HTTPS connection no. %d: https://%s%s", + self.num_connections, + self.host, + self.authurl, + ) + + headers = {"Connection": "Keep-Alive"} + req_header = "Authorization" + resp_header = "www-authenticate" + + conn = HTTPSConnection(host=self.host, port=self.port) + + # Send negotiation message + headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE( + self.rawuser + ) + log.debug("Request headers: %s", headers) + conn.request("GET", self.authurl, None, headers) + res = conn.getresponse() + reshdr = dict(res.headers) + log.debug("Response status: %s %s", res.status, res.reason) + log.debug("Response headers: %s", reshdr) + log.debug("Response data: %s [...]", res.read(100)) + + # Remove the reference to the socket, so that it can not be closed by + # the response object (we want to keep the socket open) + res.fp = None + + # Server should respond with a challenge message + auth_header_values = reshdr[resp_header].split(", ") + auth_header_value = None + for s in auth_header_values: + if s[:5] == "NTLM ": + auth_header_value = s[5:] + if auth_header_value is None: + raise Exception( + "Unexpected %s response header: %s" % (resp_header, reshdr[resp_header]) + ) + + # Send authentication message + ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE( + auth_header_value + ) + auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE( + ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags + ) + headers[req_header] = "NTLM %s" % auth_msg + log.debug("Request headers: %s", headers) + conn.request("GET", self.authurl, None, headers) + res = conn.getresponse() + log.debug("Response status: %s %s", res.status, res.reason) + log.debug("Response headers: %s", dict(res.headers)) + log.debug("Response data: %s [...]", res.read()[:100]) + if res.status != 200: + if res.status == 401: + raise Exception("Server rejected request: wrong username or password") + raise Exception("Wrong server response: %s %s" % (res.status, res.reason)) + + res.fp = None + log.debug("Connection established") + return conn + + def urlopen( + self, + method, + url, + body=None, + headers=None, + retries=3, + redirect=True, + assert_same_host=True, + ): + if headers is None: + headers = {} + headers["Connection"] = "Keep-Alive" + return super(NTLMConnectionPool, self).urlopen( + method, url, body, headers, retries, redirect, assert_same_host + ) diff --git a/lib/urllib3/contrib/pyopenssl.py b/lib/urllib3/contrib/pyopenssl.py new file mode 100644 index 0000000..1ed214b --- /dev/null +++ b/lib/urllib3/contrib/pyopenssl.py @@ -0,0 +1,518 @@ +""" +TLS with SNI_-support for Python 2. Follow these instructions if you would +like to verify TLS certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. + +This needs the following packages installed: + +* `pyOpenSSL`_ (tested with 16.0.0) +* `cryptography`_ (minimum 1.3.4, from pyopenssl) +* `idna`_ (minimum 2.0, from cryptography) + +However, pyopenssl depends on cryptography, which depends on idna, so while we +use all three directly here we end up having relatively few packages required. + +You can install them with the following command: + +.. code-block:: bash + + $ python -m pip install pyopenssl cryptography idna + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this: + +.. code-block:: python + + try: + import urllib3.contrib.pyopenssl + urllib3.contrib.pyopenssl.inject_into_urllib3() + except ImportError: + pass + +Now you can use :mod:`urllib3` as you normally would, and it will support SNI +when the required modules are installed. + +Activating this module also has the positive side effect of disabling SSL/TLS +compression in Python 2 (see `CRIME attack`_). + +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) +.. _pyopenssl: https://www.pyopenssl.org +.. _cryptography: https://cryptography.io +.. _idna: https://github.com/kjd/idna +""" +from __future__ import absolute_import + +import OpenSSL.crypto +import OpenSSL.SSL +from cryptography import x509 +from cryptography.hazmat.backends.openssl import backend as openssl_backend + +try: + from cryptography.x509 import UnsupportedExtension +except ImportError: + # UnsupportedExtension is gone in cryptography >= 2.1.0 + class UnsupportedExtension(Exception): + pass + + +from io import BytesIO +from socket import error as SocketError +from socket import timeout + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +import logging +import ssl +import sys +import warnings + +from .. import util +from ..packages import six +from ..util.ssl_ import PROTOCOL_TLS_CLIENT + +warnings.warn( + "'urllib3.contrib.pyopenssl' module is deprecated and will be removed " + "in a future release of urllib3 2.x. Read more in this issue: " + "https://github.com/urllib3/urllib3/issues/2680", + category=DeprecationWarning, + stacklevel=2, +) + +__all__ = ["inject_into_urllib3", "extract_from_urllib3"] + +# SNI always works. +HAS_SNI = True + +# Map from urllib3 to PyOpenSSL compatible parameter-values. +_openssl_versions = { + util.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD, + PROTOCOL_TLS_CLIENT: OpenSSL.SSL.SSLv23_METHOD, + ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, +} + +if hasattr(ssl, "PROTOCOL_SSLv3") and hasattr(OpenSSL.SSL, "SSLv3_METHOD"): + _openssl_versions[ssl.PROTOCOL_SSLv3] = OpenSSL.SSL.SSLv3_METHOD + +if hasattr(ssl, "PROTOCOL_TLSv1_1") and hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"): + _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD + +if hasattr(ssl, "PROTOCOL_TLSv1_2") and hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"): + _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD + + +_stdlib_to_openssl_verify = { + ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, + ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, + ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER + + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, +} +_openssl_to_stdlib_verify = dict((v, k) for k, v in _stdlib_to_openssl_verify.items()) + +# OpenSSL will only write 16K at a time +SSL_WRITE_BLOCKSIZE = 16384 + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + + +log = logging.getLogger(__name__) + + +def inject_into_urllib3(): + "Monkey-patch urllib3 with PyOpenSSL-backed SSL-support." + + _validate_dependencies_met() + + util.SSLContext = PyOpenSSLContext + util.ssl_.SSLContext = PyOpenSSLContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_PYOPENSSL = True + util.ssl_.IS_PYOPENSSL = True + + +def extract_from_urllib3(): + "Undo monkey-patching by :func:`inject_into_urllib3`." + + util.SSLContext = orig_util_SSLContext + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_PYOPENSSL = False + util.ssl_.IS_PYOPENSSL = False + + +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not met. + """ + # Method added in `cryptography==1.1`; not available in older versions + from cryptography.x509.extensions import Extensions + + if getattr(Extensions, "get_extension_for_class", None) is None: + raise ImportError( + "'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer." + ) + + # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 + # attribute is only present on those versions. + from OpenSSL.crypto import X509 + + x509 = X509() + if getattr(x509, "_x509", None) is None: + raise ImportError( + "'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer." + ) + + +def _dnsname_to_stdlib(name): + """ + Converts a dNSName SubjectAlternativeName field to the form used by the + standard library on the given Python version. + + Cryptography produces a dNSName as a unicode string that was idna-decoded + from ASCII bytes. We need to idna-encode that string to get it back, and + then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib + uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). + + If the name cannot be idna-encoded then we return None signalling that + the name given should be skipped. + """ + + def idna_encode(name): + """ + Borrowed wholesale from the Python Cryptography Project. It turns out + that we can't just safely call `idna.encode`: it can explode for + wildcard names. This avoids that problem. + """ + import idna + + try: + for prefix in [u"*.", u"."]: + if name.startswith(prefix): + name = name[len(prefix) :] + return prefix.encode("ascii") + idna.encode(name) + return idna.encode(name) + except idna.core.IDNAError: + return None + + # Don't send IPv6 addresses through the IDNA encoder. + if ":" in name: + return name + + name = idna_encode(name) + if name is None: + return None + elif sys.version_info >= (3, 0): + name = name.decode("utf-8") + return name + + +def get_subj_alt_name(peer_cert): + """ + Given an PyOpenSSL certificate, provides all the subject alternative names. + """ + # Pass the cert to cryptography, which has much better APIs for this. + if hasattr(peer_cert, "to_cryptography"): + cert = peer_cert.to_cryptography() + else: + der = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, peer_cert) + cert = x509.load_der_x509_certificate(der, openssl_backend) + + # We want to find the SAN extension. Ask Cryptography to locate it (it's + # faster than looping in Python) + try: + ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value + except x509.ExtensionNotFound: + # No such extension, return the empty list. + return [] + except ( + x509.DuplicateExtension, + UnsupportedExtension, + x509.UnsupportedGeneralNameType, + UnicodeError, + ) as e: + # A problem has been found with the quality of the certificate. Assume + # no SAN field is present. + log.warning( + "A problem was encountered with the certificate that prevented " + "urllib3 from finding the SubjectAlternativeName field. This can " + "affect certificate validation. The error was %s", + e, + ) + return [] + + # We want to return dNSName and iPAddress fields. We need to cast the IPs + # back to strings because the match_hostname function wants them as + # strings. + # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 + # decoded. This is pretty frustrating, but that's what the standard library + # does with certificates, and so we need to attempt to do the same. + # We also want to skip over names which cannot be idna encoded. + names = [ + ("DNS", name) + for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) + if name is not None + ] + names.extend( + ("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress) + ) + + return names + + +class WrappedSocket(object): + """API-compatibility wrapper for Python OpenSSL's Connection-class. + + Note: _makefile_refs, _drop() and _reuse() are needed for the garbage + collector of pypy. + """ + + def __init__(self, connection, socket, suppress_ragged_eofs=True): + self.connection = connection + self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 + self._closed = False + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, *args, **kwargs): + try: + data = self.connection.recv(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): + return b"" + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b"" + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout("The read operation timed out") + else: + return self.recv(*args, **kwargs) + + # TLS 1.3 post-handshake authentication + except OpenSSL.SSL.Error as e: + raise ssl.SSLError("read error: %r" % e) + else: + return data + + def recv_into(self, *args, **kwargs): + try: + return self.connection.recv_into(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): + return 0 + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout("The read operation timed out") + else: + return self.recv_into(*args, **kwargs) + + # TLS 1.3 post-handshake authentication + except OpenSSL.SSL.Error as e: + raise ssl.SSLError("read error: %r" % e) + + def settimeout(self, timeout): + return self.socket.settimeout(timeout) + + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + if not util.wait_for_write(self.socket, self.socket.gettimeout()): + raise timeout() + continue + except OpenSSL.SSL.SysCallError as e: + raise SocketError(str(e)) + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self._send_until_done( + data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE] + ) + total_sent += sent + + def shutdown(self): + # FIXME rethrow compatible exceptions should we ever use this + self.connection.shutdown() + + def close(self): + if self._makefile_refs < 1: + try: + self._closed = True + return self.connection.close() + except OpenSSL.SSL.Error: + return + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + x509 = self.connection.get_peer_certificate() + + if not x509: + return x509 + + if binary_form: + return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509) + + return { + "subject": ((("commonName", x509.get_subject().CN),),), + "subjectAltName": get_subj_alt_name(x509), + } + + def version(self): + return self.connection.get_protocol_version_name() + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) + +else: # Platform-specific: Python 3 + makefile = backport_makefile + +WrappedSocket.makefile = makefile + + +class PyOpenSSLContext(object): + """ + I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible + for translating the interface of the standard library ``SSLContext`` object + to calls into PyOpenSSL. + """ + + def __init__(self, protocol): + self.protocol = _openssl_versions[protocol] + self._ctx = OpenSSL.SSL.Context(self.protocol) + self._options = 0 + self.check_hostname = False + + @property + def options(self): + return self._options + + @options.setter + def options(self, value): + self._options = value + self._ctx.set_options(value) + + @property + def verify_mode(self): + return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] + + @verify_mode.setter + def verify_mode(self, value): + self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback) + + def set_default_verify_paths(self): + self._ctx.set_default_verify_paths() + + def set_ciphers(self, ciphers): + if isinstance(ciphers, six.text_type): + ciphers = ciphers.encode("utf-8") + self._ctx.set_cipher_list(ciphers) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + if cafile is not None: + cafile = cafile.encode("utf-8") + if capath is not None: + capath = capath.encode("utf-8") + try: + self._ctx.load_verify_locations(cafile, capath) + if cadata is not None: + self._ctx.load_verify_locations(BytesIO(cadata)) + except OpenSSL.SSL.Error as e: + raise ssl.SSLError("unable to load trusted certificates: %r" % e) + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._ctx.use_certificate_chain_file(certfile) + if password is not None: + if not isinstance(password, six.binary_type): + password = password.encode("utf-8") + self._ctx.set_passwd_cb(lambda *_: password) + self._ctx.use_privatekey_file(keyfile or certfile) + + def set_alpn_protocols(self, protocols): + protocols = [six.ensure_binary(p) for p in protocols] + return self._ctx.set_alpn_protos(protocols) + + def wrap_socket( + self, + sock, + server_side=False, + do_handshake_on_connect=True, + suppress_ragged_eofs=True, + server_hostname=None, + ): + cnx = OpenSSL.SSL.Connection(self._ctx, sock) + + if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 + server_hostname = server_hostname.encode("utf-8") + + if server_hostname is not None: + cnx.set_tlsext_host_name(server_hostname) + + cnx.set_connect_state() + + while True: + try: + cnx.do_handshake() + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(sock, sock.gettimeout()): + raise timeout("select timed out") + continue + except OpenSSL.SSL.Error as e: + raise ssl.SSLError("bad handshake: %r" % e) + break + + return WrappedSocket(cnx, sock) + + +def _verify_callback(cnx, x509, err_no, err_depth, return_code): + return err_no == 0 diff --git a/lib/urllib3/contrib/securetransport.py b/lib/urllib3/contrib/securetransport.py new file mode 100644 index 0000000..e311c0c --- /dev/null +++ b/lib/urllib3/contrib/securetransport.py @@ -0,0 +1,920 @@ +""" +SecureTranport support for urllib3 via ctypes. + +This makes platform-native TLS available to urllib3 users on macOS without the +use of a compiler. This is an important feature because the Python Package +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve +this is to give macOS users an alternative solution to the problem, and that +solution is to use SecureTransport. + +We use ctypes here because this solution must not require a compiler. That's +because pip is not allowed to require a compiler either. + +This is not intended to be a seriously long-term solution to this problem. +The hope is that PEP 543 will eventually solve this issue for us, at which +point we can retire this contrib module. But in the short term, we need to +solve the impending tire fire that is Python on Mac without this kind of +contrib module. So...here we are. + +To use this module, simply import and inject it:: + + import urllib3.contrib.securetransport + urllib3.contrib.securetransport.inject_into_urllib3() + +Happy TLSing! + +This code is a bastardised version of the code found in Will Bond's oscrypto +library. An enormous debt is owed to him for blazing this trail for us. For +that reason, this code should be considered to be covered both by urllib3's +license and by oscrypto's: + +.. code-block:: + + Copyright (c) 2015-2016 Will Bond + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +""" +from __future__ import absolute_import + +import contextlib +import ctypes +import errno +import os.path +import shutil +import socket +import ssl +import struct +import threading +import weakref + +from .. import util +from ..packages import six +from ..util.ssl_ import PROTOCOL_TLS_CLIENT +from ._securetransport.bindings import CoreFoundation, Security, SecurityConst +from ._securetransport.low_level import ( + _assert_no_error, + _build_tls_unknown_ca_alert, + _cert_array_from_pem, + _create_cfstring_array, + _load_client_cert_chain, + _temporary_keychain, +) + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +__all__ = ["inject_into_urllib3", "extract_from_urllib3"] + +# SNI always works +HAS_SNI = True + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + +# This dictionary is used by the read callback to obtain a handle to the +# calling wrapped socket. This is a pretty silly approach, but for now it'll +# do. I feel like I should be able to smuggle a handle to the wrapped socket +# directly in the SSLConnectionRef, but for now this approach will work I +# guess. +# +# We need to lock around this structure for inserts, but we don't do it for +# reads/writes in the callbacks. The reasoning here goes as follows: +# +# 1. It is not possible to call into the callbacks before the dictionary is +# populated, so once in the callback the id must be in the dictionary. +# 2. The callbacks don't mutate the dictionary, they only read from it, and +# so cannot conflict with any of the insertions. +# +# This is good: if we had to lock in the callbacks we'd drastically slow down +# the performance of this code. +_connection_refs = weakref.WeakValueDictionary() +_connection_ref_lock = threading.Lock() + +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over +# for no better reason than we need *a* limit, and this one is right there. +SSL_WRITE_BLOCKSIZE = 16384 + +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to +# individual cipher suites. We need to do this because this is how +# SecureTransport wants them. +CIPHER_SUITES = [ + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_AES_256_GCM_SHA384, + SecurityConst.TLS_AES_128_GCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_AES_128_CCM_8_SHA256, + SecurityConst.TLS_AES_128_CCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, +] + +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +# TLSv1 to 1.2 are supported on macOS 10.8+ +_protocol_to_min_max = { + util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), + PROTOCOL_TLS_CLIENT: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), +} + +if hasattr(ssl, "PROTOCOL_SSLv2"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( + SecurityConst.kSSLProtocol2, + SecurityConst.kSSLProtocol2, + ) +if hasattr(ssl, "PROTOCOL_SSLv3"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( + SecurityConst.kSSLProtocol3, + SecurityConst.kSSLProtocol3, + ) +if hasattr(ssl, "PROTOCOL_TLSv1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( + SecurityConst.kTLSProtocol1, + SecurityConst.kTLSProtocol1, + ) +if hasattr(ssl, "PROTOCOL_TLSv1_1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( + SecurityConst.kTLSProtocol11, + SecurityConst.kTLSProtocol11, + ) +if hasattr(ssl, "PROTOCOL_TLSv1_2"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( + SecurityConst.kTLSProtocol12, + SecurityConst.kTLSProtocol12, + ) + + +def inject_into_urllib3(): + """ + Monkey-patch urllib3 with SecureTransport-backed SSL-support. + """ + util.SSLContext = SecureTransportContext + util.ssl_.SSLContext = SecureTransportContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_SECURETRANSPORT = True + util.ssl_.IS_SECURETRANSPORT = True + + +def extract_from_urllib3(): + """ + Undo monkey-patching by :func:`inject_into_urllib3`. + """ + util.SSLContext = orig_util_SSLContext + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_SECURETRANSPORT = False + util.ssl_.IS_SECURETRANSPORT = False + + +def _read_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport read callback. This is called by ST to request that data + be returned from the socket. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + requested_length = data_length_pointer[0] + + timeout = wrapped_socket.gettimeout() + error = None + read_count = 0 + + try: + while read_count < requested_length: + if timeout is None or timeout >= 0: + if not util.wait_for_read(base_socket, timeout): + raise socket.error(errno.EAGAIN, "timed out") + + remaining = requested_length - read_count + buffer = (ctypes.c_char * remaining).from_address( + data_buffer + read_count + ) + chunk_size = base_socket.recv_into(buffer, remaining) + read_count += chunk_size + if not chunk_size: + if not read_count: + return SecurityConst.errSSLClosedGraceful + break + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = read_count + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = read_count + + if read_count != requested_length: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +def _write_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport write callback. This is called by ST to request that data + actually be sent on the network. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + bytes_to_write = data_length_pointer[0] + data = ctypes.string_at(data_buffer, bytes_to_write) + + timeout = wrapped_socket.gettimeout() + error = None + sent = 0 + + try: + while sent < bytes_to_write: + if timeout is None or timeout >= 0: + if not util.wait_for_write(base_socket, timeout): + raise socket.error(errno.EAGAIN, "timed out") + chunk_sent = base_socket.send(data) + sent += chunk_sent + + # This has some needless copying here, but I'm not sure there's + # much value in optimising this data path. + data = data[chunk_sent:] + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = sent + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = sent + + if sent != bytes_to_write: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +# We need to keep these two objects references alive: if they get GC'd while +# in use then SecureTransport could attempt to call a function that is in freed +# memory. That would be...uh...bad. Yeah, that's the word. Bad. +_read_callback_pointer = Security.SSLReadFunc(_read_callback) +_write_callback_pointer = Security.SSLWriteFunc(_write_callback) + + +class WrappedSocket(object): + """ + API-compatibility wrapper for Python's OpenSSL wrapped socket object. + + Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage + collector of PyPy. + """ + + def __init__(self, socket): + self.socket = socket + self.context = None + self._makefile_refs = 0 + self._closed = False + self._exception = None + self._keychain = None + self._keychain_dir = None + self._client_cert_chain = None + + # We save off the previously-configured timeout and then set it to + # zero. This is done because we use select and friends to handle the + # timeouts, but if we leave the timeout set on the lower socket then + # Python will "kindly" call select on that socket again for us. Avoid + # that by forcing the timeout to zero. + self._timeout = self.socket.gettimeout() + self.socket.settimeout(0) + + @contextlib.contextmanager + def _raise_on_error(self): + """ + A context manager that can be used to wrap calls that do I/O from + SecureTransport. If any of the I/O callbacks hit an exception, this + context manager will correctly propagate the exception after the fact. + This avoids silently swallowing those exceptions. + + It also correctly forces the socket closed. + """ + self._exception = None + + # We explicitly don't catch around this yield because in the unlikely + # event that an exception was hit in the block we don't want to swallow + # it. + yield + if self._exception is not None: + exception, self._exception = self._exception, None + self.close() + raise exception + + def _set_ciphers(self): + """ + Sets up the allowed ciphers. By default this matches the set in + util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done + custom and doesn't allow changing at this time, mostly because parsing + OpenSSL cipher strings is going to be a freaking nightmare. + """ + ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) + result = Security.SSLSetEnabledCiphers( + self.context, ciphers, len(CIPHER_SUITES) + ) + _assert_no_error(result) + + def _set_alpn_protocols(self, protocols): + """ + Sets up the ALPN protocols on the context. + """ + if not protocols: + return + protocols_arr = _create_cfstring_array(protocols) + try: + result = Security.SSLSetALPNProtocols(self.context, protocols_arr) + _assert_no_error(result) + finally: + CoreFoundation.CFRelease(protocols_arr) + + def _custom_validate(self, verify, trust_bundle): + """ + Called when we have set custom validation. We do this in two cases: + first, when cert validation is entirely disabled; and second, when + using a custom trust DB. + Raises an SSLError if the connection is not trusted. + """ + # If we disabled cert validation, just say: cool. + if not verify: + return + + successes = ( + SecurityConst.kSecTrustResultUnspecified, + SecurityConst.kSecTrustResultProceed, + ) + try: + trust_result = self._evaluate_trust(trust_bundle) + if trust_result in successes: + return + reason = "error code: %d" % (trust_result,) + except Exception as e: + # Do not trust on error + reason = "exception: %r" % (e,) + + # SecureTransport does not send an alert nor shuts down the connection. + rec = _build_tls_unknown_ca_alert(self.version()) + self.socket.sendall(rec) + # close the connection immediately + # l_onoff = 1, activate linger + # l_linger = 0, linger for 0 seoncds + opts = struct.pack("ii", 1, 0) + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, opts) + self.close() + raise ssl.SSLError("certificate verify failed, %s" % reason) + + def _evaluate_trust(self, trust_bundle): + # We want data in memory, so load it up. + if os.path.isfile(trust_bundle): + with open(trust_bundle, "rb") as f: + trust_bundle = f.read() + + cert_array = None + trust = Security.SecTrustRef() + + try: + # Get a CFArray that contains the certs we want. + cert_array = _cert_array_from_pem(trust_bundle) + + # Ok, now the hard part. We want to get the SecTrustRef that ST has + # created for this connection, shove our CAs into it, tell ST to + # ignore everything else it knows, and then ask if it can build a + # chain. This is a buuuunch of code. + result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) + _assert_no_error(result) + if not trust: + raise ssl.SSLError("Failed to copy trust reference") + + result = Security.SecTrustSetAnchorCertificates(trust, cert_array) + _assert_no_error(result) + + result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) + _assert_no_error(result) + + trust_result = Security.SecTrustResultType() + result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result)) + _assert_no_error(result) + finally: + if trust: + CoreFoundation.CFRelease(trust) + + if cert_array is not None: + CoreFoundation.CFRelease(cert_array) + + return trust_result.value + + def handshake( + self, + server_hostname, + verify, + trust_bundle, + min_version, + max_version, + client_cert, + client_key, + client_key_passphrase, + alpn_protocols, + ): + """ + Actually performs the TLS handshake. This is run automatically by + wrapped socket, and shouldn't be needed in user code. + """ + # First, we do the initial bits of connection setup. We need to create + # a context, set its I/O funcs, and set the connection reference. + self.context = Security.SSLCreateContext( + None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType + ) + result = Security.SSLSetIOFuncs( + self.context, _read_callback_pointer, _write_callback_pointer + ) + _assert_no_error(result) + + # Here we need to compute the handle to use. We do this by taking the + # id of self modulo 2**31 - 1. If this is already in the dictionary, we + # just keep incrementing by one until we find a free space. + with _connection_ref_lock: + handle = id(self) % 2147483647 + while handle in _connection_refs: + handle = (handle + 1) % 2147483647 + _connection_refs[handle] = self + + result = Security.SSLSetConnection(self.context, handle) + _assert_no_error(result) + + # If we have a server hostname, we should set that too. + if server_hostname: + if not isinstance(server_hostname, bytes): + server_hostname = server_hostname.encode("utf-8") + + result = Security.SSLSetPeerDomainName( + self.context, server_hostname, len(server_hostname) + ) + _assert_no_error(result) + + # Setup the ciphers. + self._set_ciphers() + + # Setup the ALPN protocols. + self._set_alpn_protocols(alpn_protocols) + + # Set the minimum and maximum TLS versions. + result = Security.SSLSetProtocolVersionMin(self.context, min_version) + _assert_no_error(result) + + result = Security.SSLSetProtocolVersionMax(self.context, max_version) + _assert_no_error(result) + + # If there's a trust DB, we need to use it. We do that by telling + # SecureTransport to break on server auth. We also do that if we don't + # want to validate the certs at all: we just won't actually do any + # authing in that case. + if not verify or trust_bundle is not None: + result = Security.SSLSetSessionOption( + self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True + ) + _assert_no_error(result) + + # If there's a client cert, we need to use it. + if client_cert: + self._keychain, self._keychain_dir = _temporary_keychain() + self._client_cert_chain = _load_client_cert_chain( + self._keychain, client_cert, client_key + ) + result = Security.SSLSetCertificate(self.context, self._client_cert_chain) + _assert_no_error(result) + + while True: + with self._raise_on_error(): + result = Security.SSLHandshake(self.context) + + if result == SecurityConst.errSSLWouldBlock: + raise socket.timeout("handshake timed out") + elif result == SecurityConst.errSSLServerAuthCompleted: + self._custom_validate(verify, trust_bundle) + continue + else: + _assert_no_error(result) + break + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, bufsiz): + buffer = ctypes.create_string_buffer(bufsiz) + bytes_read = self.recv_into(buffer, bufsiz) + data = buffer[:bytes_read] + return data + + def recv_into(self, buffer, nbytes=None): + # Read short on EOF. + if self._closed: + return 0 + + if nbytes is None: + nbytes = len(buffer) + + buffer = (ctypes.c_char * nbytes).from_buffer(buffer) + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLRead( + self.context, buffer, nbytes, ctypes.byref(processed_bytes) + ) + + # There are some result codes that we want to treat as "not always + # errors". Specifically, those are errSSLWouldBlock, + # errSSLClosedGraceful, and errSSLClosedNoNotify. + if result == SecurityConst.errSSLWouldBlock: + # If we didn't process any bytes, then this was just a time out. + # However, we can get errSSLWouldBlock in situations when we *did* + # read some data, and in those cases we should just read "short" + # and return. + if processed_bytes.value == 0: + # Timed out, no data read. + raise socket.timeout("recv timed out") + elif result in ( + SecurityConst.errSSLClosedGraceful, + SecurityConst.errSSLClosedNoNotify, + ): + # The remote peer has closed this connection. We should do so as + # well. Note that we don't actually return here because in + # principle this could actually be fired along with return data. + # It's unlikely though. + self.close() + else: + _assert_no_error(result) + + # Ok, we read and probably succeeded. We should return whatever data + # was actually read. + return processed_bytes.value + + def settimeout(self, timeout): + self._timeout = timeout + + def gettimeout(self): + return self._timeout + + def send(self, data): + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLWrite( + self.context, data, len(data), ctypes.byref(processed_bytes) + ) + + if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: + # Timed out + raise socket.timeout("send timed out") + else: + _assert_no_error(result) + + # We sent, and probably succeeded. Tell them how much we sent. + return processed_bytes.value + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + with self._raise_on_error(): + Security.SSLClose(self.context) + + def close(self): + # TODO: should I do clean shutdown here? Do I have to? + if self._makefile_refs < 1: + self._closed = True + if self.context: + CoreFoundation.CFRelease(self.context) + self.context = None + if self._client_cert_chain: + CoreFoundation.CFRelease(self._client_cert_chain) + self._client_cert_chain = None + if self._keychain: + Security.SecKeychainDelete(self._keychain) + CoreFoundation.CFRelease(self._keychain) + shutil.rmtree(self._keychain_dir) + self._keychain = self._keychain_dir = None + return self.socket.close() + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + # Urgh, annoying. + # + # Here's how we do this: + # + # 1. Call SSLCopyPeerTrust to get hold of the trust object for this + # connection. + # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. + # 3. To get the CN, call SecCertificateCopyCommonName and process that + # string so that it's of the appropriate type. + # 4. To get the SAN, we need to do something a bit more complex: + # a. Call SecCertificateCopyValues to get the data, requesting + # kSecOIDSubjectAltName. + # b. Mess about with this dictionary to try to get the SANs out. + # + # This is gross. Really gross. It's going to be a few hundred LoC extra + # just to repeat something that SecureTransport can *already do*. So my + # operating assumption at this time is that what we want to do is + # instead to just flag to urllib3 that it shouldn't do its own hostname + # validation when using SecureTransport. + if not binary_form: + raise ValueError("SecureTransport only supports dumping binary certs") + trust = Security.SecTrustRef() + certdata = None + der_bytes = None + + try: + # Grab the trust store. + result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) + _assert_no_error(result) + if not trust: + # Probably we haven't done the handshake yet. No biggie. + return None + + cert_count = Security.SecTrustGetCertificateCount(trust) + if not cert_count: + # Also a case that might happen if we haven't handshaked. + # Handshook? Handshaken? + return None + + leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) + assert leaf + + # Ok, now we want the DER bytes. + certdata = Security.SecCertificateCopyData(leaf) + assert certdata + + data_length = CoreFoundation.CFDataGetLength(certdata) + data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) + der_bytes = ctypes.string_at(data_buffer, data_length) + finally: + if certdata: + CoreFoundation.CFRelease(certdata) + if trust: + CoreFoundation.CFRelease(trust) + + return der_bytes + + def version(self): + protocol = Security.SSLProtocol() + result = Security.SSLGetNegotiatedProtocolVersion( + self.context, ctypes.byref(protocol) + ) + _assert_no_error(result) + if protocol.value == SecurityConst.kTLSProtocol13: + raise ssl.SSLError("SecureTransport does not support TLS 1.3") + elif protocol.value == SecurityConst.kTLSProtocol12: + return "TLSv1.2" + elif protocol.value == SecurityConst.kTLSProtocol11: + return "TLSv1.1" + elif protocol.value == SecurityConst.kTLSProtocol1: + return "TLSv1" + elif protocol.value == SecurityConst.kSSLProtocol3: + return "SSLv3" + elif protocol.value == SecurityConst.kSSLProtocol2: + return "SSLv2" + else: + raise ssl.SSLError("Unknown TLS version: %r" % protocol) + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) + +else: # Platform-specific: Python 3 + + def makefile(self, mode="r", buffering=None, *args, **kwargs): + # We disable buffering with SecureTransport because it conflicts with + # the buffering that ST does internally (see issue #1153 for more). + buffering = 0 + return backport_makefile(self, mode, buffering, *args, **kwargs) + + +WrappedSocket.makefile = makefile + + +class SecureTransportContext(object): + """ + I am a wrapper class for the SecureTransport library, to translate the + interface of the standard library ``SSLContext`` object to calls into + SecureTransport. + """ + + def __init__(self, protocol): + self._min_version, self._max_version = _protocol_to_min_max[protocol] + self._options = 0 + self._verify = False + self._trust_bundle = None + self._client_cert = None + self._client_key = None + self._client_key_passphrase = None + self._alpn_protocols = None + + @property + def check_hostname(self): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + return True + + @check_hostname.setter + def check_hostname(self, value): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + pass + + @property + def options(self): + # TODO: Well, crap. + # + # So this is the bit of the code that is the most likely to cause us + # trouble. Essentially we need to enumerate all of the SSL options that + # users might want to use and try to see if we can sensibly translate + # them, or whether we should just ignore them. + return self._options + + @options.setter + def options(self, value): + # TODO: Update in line with above. + self._options = value + + @property + def verify_mode(self): + return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE + + @verify_mode.setter + def verify_mode(self, value): + self._verify = True if value == ssl.CERT_REQUIRED else False + + def set_default_verify_paths(self): + # So, this has to do something a bit weird. Specifically, what it does + # is nothing. + # + # This means that, if we had previously had load_verify_locations + # called, this does not undo that. We need to do that because it turns + # out that the rest of the urllib3 code will attempt to load the + # default verify paths if it hasn't been told about any paths, even if + # the context itself was sometime earlier. We resolve that by just + # ignoring it. + pass + + def load_default_certs(self): + return self.set_default_verify_paths() + + def set_ciphers(self, ciphers): + # For now, we just require the default cipher string. + if ciphers != util.ssl_.DEFAULT_CIPHERS: + raise ValueError("SecureTransport doesn't support custom cipher strings") + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + # OK, we only really support cadata and cafile. + if capath is not None: + raise ValueError("SecureTransport does not support cert directories") + + # Raise if cafile does not exist. + if cafile is not None: + with open(cafile): + pass + + self._trust_bundle = cafile or cadata + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._client_cert = certfile + self._client_key = keyfile + self._client_cert_passphrase = password + + def set_alpn_protocols(self, protocols): + """ + Sets the ALPN protocols that will later be set on the context. + + Raises a NotImplementedError if ALPN is not supported. + """ + if not hasattr(Security, "SSLSetALPNProtocols"): + raise NotImplementedError( + "SecureTransport supports ALPN only in macOS 10.12+" + ) + self._alpn_protocols = [six.ensure_binary(p) for p in protocols] + + def wrap_socket( + self, + sock, + server_side=False, + do_handshake_on_connect=True, + suppress_ragged_eofs=True, + server_hostname=None, + ): + # So, what do we do here? Firstly, we assert some properties. This is a + # stripped down shim, so there is some functionality we don't support. + # See PEP 543 for the real deal. + assert not server_side + assert do_handshake_on_connect + assert suppress_ragged_eofs + + # Ok, we're good to go. Now we want to create the wrapped socket object + # and store it in the appropriate place. + wrapped_socket = WrappedSocket(sock) + + # Now we can handshake + wrapped_socket.handshake( + server_hostname, + self._verify, + self._trust_bundle, + self._min_version, + self._max_version, + self._client_cert, + self._client_key, + self._client_key_passphrase, + self._alpn_protocols, + ) + return wrapped_socket diff --git a/lib/urllib3/contrib/socks.py b/lib/urllib3/contrib/socks.py new file mode 100644 index 0000000..c326e80 --- /dev/null +++ b/lib/urllib3/contrib/socks.py @@ -0,0 +1,216 @@ +# -*- coding: utf-8 -*- +""" +This module contains provisional support for SOCKS proxies from within +urllib3. This module supports SOCKS4, SOCKS4A (an extension of SOCKS4), and +SOCKS5. To enable its functionality, either install PySocks or install this +module with the ``socks`` extra. + +The SOCKS implementation supports the full range of urllib3 features. It also +supports the following SOCKS features: + +- SOCKS4A (``proxy_url='socks4a://...``) +- SOCKS4 (``proxy_url='socks4://...``) +- SOCKS5 with remote DNS (``proxy_url='socks5h://...``) +- SOCKS5 with local DNS (``proxy_url='socks5://...``) +- Usernames and passwords for the SOCKS proxy + +.. note:: + It is recommended to use ``socks5h://`` or ``socks4a://`` schemes in + your ``proxy_url`` to ensure that DNS resolution is done from the remote + server instead of client-side when connecting to a domain name. + +SOCKS4 supports IPv4 and domain names with the SOCKS4A extension. SOCKS5 +supports IPv4, IPv6, and domain names. + +When connecting to a SOCKS4 proxy the ``username`` portion of the ``proxy_url`` +will be sent as the ``userid`` section of the SOCKS request: + +.. code-block:: python + + proxy_url="socks4a://@proxy-host" + +When connecting to a SOCKS5 proxy the ``username`` and ``password`` portion +of the ``proxy_url`` will be sent as the username/password to authenticate +with the proxy: + +.. code-block:: python + + proxy_url="socks5h://:@proxy-host" + +""" +from __future__ import absolute_import + +try: + import socks +except ImportError: + import warnings + + from ..exceptions import DependencyWarning + + warnings.warn( + ( + "SOCKS support in urllib3 requires the installation of optional " + "dependencies: specifically, PySocks. For more information, see " + "https://urllib3.readthedocs.io/en/1.26.x/contrib.html#socks-proxies" + ), + DependencyWarning, + ) + raise + +from socket import error as SocketError +from socket import timeout as SocketTimeout + +from ..connection import HTTPConnection, HTTPSConnection +from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from ..exceptions import ConnectTimeoutError, NewConnectionError +from ..poolmanager import PoolManager +from ..util.url import parse_url + +try: + import ssl +except ImportError: + ssl = None + + +class SOCKSConnection(HTTPConnection): + """ + A plain-text HTTP connection that connects via a SOCKS proxy. + """ + + def __init__(self, *args, **kwargs): + self._socks_options = kwargs.pop("_socks_options") + super(SOCKSConnection, self).__init__(*args, **kwargs) + + def _new_conn(self): + """ + Establish a new connection via the SOCKS proxy. + """ + extra_kw = {} + if self.source_address: + extra_kw["source_address"] = self.source_address + + if self.socket_options: + extra_kw["socket_options"] = self.socket_options + + try: + conn = socks.create_connection( + (self.host, self.port), + proxy_type=self._socks_options["socks_version"], + proxy_addr=self._socks_options["proxy_host"], + proxy_port=self._socks_options["proxy_port"], + proxy_username=self._socks_options["username"], + proxy_password=self._socks_options["password"], + proxy_rdns=self._socks_options["rdns"], + timeout=self.timeout, + **extra_kw + ) + + except SocketTimeout: + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" + % (self.host, self.timeout), + ) + + except socks.ProxyError as e: + # This is fragile as hell, but it seems to be the only way to raise + # useful errors here. + if e.socket_err: + error = e.socket_err + if isinstance(error, SocketTimeout): + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" + % (self.host, self.timeout), + ) + else: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % error + ) + else: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e + ) + + except SocketError as e: # Defensive: PySocks should catch all these. + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e + ) + + return conn + + +# We don't need to duplicate the Verified/Unverified distinction from +# urllib3/connection.py here because the HTTPSConnection will already have been +# correctly set to either the Verified or Unverified form by that module. This +# means the SOCKSHTTPSConnection will automatically be the correct type. +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): + pass + + +class SOCKSHTTPConnectionPool(HTTPConnectionPool): + ConnectionCls = SOCKSConnection + + +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): + ConnectionCls = SOCKSHTTPSConnection + + +class SOCKSProxyManager(PoolManager): + """ + A version of the urllib3 ProxyManager that routes connections via the + defined SOCKS proxy. + """ + + pool_classes_by_scheme = { + "http": SOCKSHTTPConnectionPool, + "https": SOCKSHTTPSConnectionPool, + } + + def __init__( + self, + proxy_url, + username=None, + password=None, + num_pools=10, + headers=None, + **connection_pool_kw + ): + parsed = parse_url(proxy_url) + + if username is None and password is None and parsed.auth is not None: + split = parsed.auth.split(":") + if len(split) == 2: + username, password = split + if parsed.scheme == "socks5": + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == "socks5h": + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True + elif parsed.scheme == "socks4": + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == "socks4a": + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True + else: + raise ValueError("Unable to determine SOCKS version from %s" % proxy_url) + + self.proxy_url = proxy_url + + socks_options = { + "socks_version": socks_version, + "proxy_host": parsed.host, + "proxy_port": parsed.port, + "username": username, + "password": password, + "rdns": rdns, + } + connection_pool_kw["_socks_options"] = socks_options + + super(SOCKSProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw + ) + + self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/lib/urllib3/exceptions.py b/lib/urllib3/exceptions.py new file mode 100644 index 0000000..cba6f3f --- /dev/null +++ b/lib/urllib3/exceptions.py @@ -0,0 +1,323 @@ +from __future__ import absolute_import + +from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead + +# Base Exceptions + + +class HTTPError(Exception): + """Base exception used by this module.""" + + pass + + +class HTTPWarning(Warning): + """Base warning used by this module.""" + + pass + + +class PoolError(HTTPError): + """Base exception for errors caused within a pool.""" + + def __init__(self, pool, message): + self.pool = pool + HTTPError.__init__(self, "%s: %s" % (pool, message)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +class RequestError(PoolError): + """Base exception for PoolErrors that have associated URLs.""" + + def __init__(self, pool, url, message): + self.url = url + PoolError.__init__(self, pool, message) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + """Raised when SSL certificate fails in an HTTPS connection.""" + + pass + + +class ProxyError(HTTPError): + """Raised when the connection to a proxy fails.""" + + def __init__(self, message, error, *args): + super(ProxyError, self).__init__(message, error, *args) + self.original_error = error + + +class DecodeError(HTTPError): + """Raised when automatic decoding based on Content-Type fails.""" + + pass + + +class ProtocolError(HTTPError): + """Raised when something unexpected happens mid-request/response.""" + + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +# Leaf Exceptions + + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % (url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + """Raised when an existing pool gets a request for a foreign host.""" + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """Raised when passing an invalid state to a timeout""" + + pass + + +class TimeoutError(HTTPError): + """Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + ` and :exc:`ConnectTimeoutErrors `. + """ + + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + """Raised when a socket timeout occurs while receiving data from a server""" + + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + """Raised when a socket timeout occurs while connecting to a server""" + + pass + + +class NewConnectionError(ConnectTimeoutError, PoolError): + """Raised when we fail to establish a new connection. Usually ECONNREFUSED.""" + + pass + + +class EmptyPoolError(PoolError): + """Raised when a pool runs out of connections and no more are allowed.""" + + pass + + +class ClosedPoolError(PoolError): + """Raised when a request enters a pool after the pool has been closed.""" + + pass + + +class LocationValueError(ValueError, HTTPError): + """Raised when there is something wrong with a given URL input.""" + + pass + + +class LocationParseError(LocationValueError): + """Raised when get_host or similar fails to parse the URL input.""" + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +class URLSchemeUnknown(LocationValueError): + """Raised when a URL input has an unsupported scheme.""" + + def __init__(self, scheme): + message = "Not supported URL scheme %s" % scheme + super(URLSchemeUnknown, self).__init__(message) + + self.scheme = scheme + + +class ResponseError(HTTPError): + """Used as a container for an error reason supplied in a MaxRetryError.""" + + GENERIC_ERROR = "too many error responses" + SPECIFIC_ERROR = "too many {status_code} error responses" + + +class SecurityWarning(HTTPWarning): + """Warned when performing security reducing actions""" + + pass + + +class SubjectAltNameWarning(SecurityWarning): + """Warned when connecting to a host with a certificate missing a SAN.""" + + pass + + +class InsecureRequestWarning(SecurityWarning): + """Warned when making an unverified HTTPS request.""" + + pass + + +class SystemTimeWarning(SecurityWarning): + """Warned when system time is suspected to be wrong""" + + pass + + +class InsecurePlatformWarning(SecurityWarning): + """Warned when certain TLS/SSL configuration is not available on a platform.""" + + pass + + +class SNIMissingWarning(HTTPWarning): + """Warned when making a HTTPS request without SNI available.""" + + pass + + +class DependencyWarning(HTTPWarning): + """ + Warned when an attempt is made to import a module with missing optional + dependencies. + """ + + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + """Response needs to be chunked in order to read it as chunks.""" + + pass + + +class BodyNotHttplibCompatible(HTTPError): + """ + Body should be :class:`http.client.HTTPResponse` like + (have an fp attribute which returns raw chunks) for read_chunked(). + """ + + pass + + +class IncompleteRead(HTTPError, httplib_IncompleteRead): + """ + Response length doesn't match expected Content-Length + + Subclass of :class:`http.client.IncompleteRead` to allow int value + for ``partial`` to avoid creating large objects on streamed reads. + """ + + def __init__(self, partial, expected): + super(IncompleteRead, self).__init__(partial, expected) + + def __repr__(self): + return "IncompleteRead(%i bytes read, %i more expected)" % ( + self.partial, + self.expected, + ) + + +class InvalidChunkLength(HTTPError, httplib_IncompleteRead): + """Invalid chunk length in a chunked response.""" + + def __init__(self, response, length): + super(InvalidChunkLength, self).__init__( + response.tell(), response.length_remaining + ) + self.response = response + self.length = length + + def __repr__(self): + return "InvalidChunkLength(got length %r, %i bytes read)" % ( + self.length, + self.partial, + ) + + +class InvalidHeader(HTTPError): + """The header provided was somehow invalid.""" + + pass + + +class ProxySchemeUnknown(AssertionError, URLSchemeUnknown): + """ProxyManager does not support the supplied scheme""" + + # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. + + def __init__(self, scheme): + # 'localhost' is here because our URL parser parses + # localhost:8080 -> scheme=localhost, remove if we fix this. + if scheme == "localhost": + scheme = None + if scheme is None: + message = "Proxy URL had no scheme, should start with http:// or https://" + else: + message = ( + "Proxy URL had unsupported scheme %s, should use http:// or https://" + % scheme + ) + super(ProxySchemeUnknown, self).__init__(message) + + +class ProxySchemeUnsupported(ValueError): + """Fetching HTTPS resources through HTTPS proxies is unsupported""" + + pass + + +class HeaderParsingError(HTTPError): + """Raised by assert_header_parsing, but we convert it to a log.warning statement.""" + + def __init__(self, defects, unparsed_data): + message = "%s, unparsed data: %r" % (defects or "Unknown", unparsed_data) + super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + """urllib3 encountered an error when trying to rewind a body""" + + pass diff --git a/lib/urllib3/fields.py b/lib/urllib3/fields.py new file mode 100644 index 0000000..9d630f4 --- /dev/null +++ b/lib/urllib3/fields.py @@ -0,0 +1,274 @@ +from __future__ import absolute_import + +import email.utils +import mimetypes +import re + +from .packages import six + + +def guess_content_type(filename, default="application/octet-stream"): + """ + Guess the "Content-Type" of a file. + + :param filename: + The filename to guess the "Content-Type" of using :mod:`mimetypes`. + :param default: + If no "Content-Type" can be guessed, default to `default`. + """ + if filename: + return mimetypes.guess_type(filename)[0] or default + return default + + +def format_header_param_rfc2231(name, value): + """ + Helper function to format and quote a single header parameter using the + strategy defined in RFC 2231. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows + `RFC 2388 Section 4.4 `_. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as ``bytes`` or `str``. + :ret: + An RFC-2231-formatted unicode string. + """ + if isinstance(value, six.binary_type): + value = value.decode("utf-8") + + if not any(ch in value for ch in '"\\\r\n'): + result = u'%s="%s"' % (name, value) + try: + result.encode("ascii") + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + + if six.PY2: # Python 2: + value = value.encode("utf-8") + + # encode_rfc2231 accepts an encoded string and returns an ascii-encoded + # string in Python 2 but accepts and returns unicode strings in Python 3 + value = email.utils.encode_rfc2231(value, "utf-8") + value = "%s*=%s" % (name, value) + + if six.PY2: # Python 2: + value = value.decode("utf-8") + + return value + + +_HTML5_REPLACEMENTS = { + u"\u0022": u"%22", + # Replace "\" with "\\". + u"\u005C": u"\u005C\u005C", +} + +# All control characters from 0x00 to 0x1F *except* 0x1B. +_HTML5_REPLACEMENTS.update( + { + six.unichr(cc): u"%{:02X}".format(cc) + for cc in range(0x00, 0x1F + 1) + if cc not in (0x1B,) + } +) + + +def _replace_multiple(value, needles_and_replacements): + def replacer(match): + return needles_and_replacements[match.group(0)] + + pattern = re.compile( + r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()]) + ) + + result = pattern.sub(replacer, value) + + return result + + +def format_header_param_html5(name, value): + """ + Helper function to format and quote a single header parameter using the + HTML5 strategy. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows the `HTML5 Working Draft + Section 4.10.22.7`_ and matches the behavior of curl and modern browsers. + + .. _HTML5 Working Draft Section 4.10.22.7: + https://w3c.github.io/html/sec-forms.html#multipart-form-data + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as ``bytes`` or `str``. + :ret: + A unicode string, stripped of troublesome characters. + """ + if isinstance(value, six.binary_type): + value = value.decode("utf-8") + + value = _replace_multiple(value, _HTML5_REPLACEMENTS) + + return u'%s="%s"' % (name, value) + + +# For backwards-compatibility. +format_header_param = format_header_param_html5 + + +class RequestField(object): + """ + A data container for request body parameters. + + :param name: + The name of this request field. Must be unicode. + :param data: + The data/value body. + :param filename: + An optional filename of the request field. Must be unicode. + :param headers: + An optional dict-like object of headers to initially use for the field. + :param header_formatter: + An optional callable that is used to encode and format the headers. By + default, this is :func:`format_header_param_html5`. + """ + + def __init__( + self, + name, + data, + filename=None, + headers=None, + header_formatter=format_header_param_html5, + ): + self._name = name + self._filename = filename + self.data = data + self.headers = {} + if headers: + self.headers = dict(headers) + self.header_formatter = header_formatter + + @classmethod + def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5): + """ + A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. + + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: + + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + + Field names and filenames must be unicode. + """ + if isinstance(value, tuple): + if len(value) == 3: + filename, data, content_type = value + else: + filename, data = value + content_type = guess_content_type(filename) + else: + filename = None + content_type = None + data = value + + request_param = cls( + fieldname, data, filename=filename, header_formatter=header_formatter + ) + request_param.make_multipart(content_type=content_type) + + return request_param + + def _render_part(self, name, value): + """ + Overridable helper function to format a single header parameter. By + default, this calls ``self.header_formatter``. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + + return self.header_formatter(name, value) + + def _render_parts(self, header_parts): + """ + Helper function to format and quote a single header. + + Useful for single headers that are composed of multiple items. E.g., + 'Content-Disposition' fields. + + :param header_parts: + A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. + """ + parts = [] + iterable = header_parts + if isinstance(header_parts, dict): + iterable = header_parts.items() + + for name, value in iterable: + if value is not None: + parts.append(self._render_part(name, value)) + + return u"; ".join(parts) + + def render_headers(self): + """ + Renders the headers for this request field. + """ + lines = [] + + sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"] + for sort_key in sort_keys: + if self.headers.get(sort_key, False): + lines.append(u"%s: %s" % (sort_key, self.headers[sort_key])) + + for header_name, header_value in self.headers.items(): + if header_name not in sort_keys: + if header_value: + lines.append(u"%s: %s" % (header_name, header_value)) + + lines.append(u"\r\n") + return u"\r\n".join(lines) + + def make_multipart( + self, content_disposition=None, content_type=None, content_location=None + ): + """ + Makes this request field into a multipart request field. + + This method overrides "Content-Disposition", "Content-Type" and + "Content-Location" headers to the request parameter. + + :param content_type: + The 'Content-Type' of the request body. + :param content_location: + The 'Content-Location' of the request body. + + """ + self.headers["Content-Disposition"] = content_disposition or u"form-data" + self.headers["Content-Disposition"] += u"; ".join( + [ + u"", + self._render_parts( + ((u"name", self._name), (u"filename", self._filename)) + ), + ] + ) + self.headers["Content-Type"] = content_type + self.headers["Content-Location"] = content_location diff --git a/lib/urllib3/filepost.py b/lib/urllib3/filepost.py new file mode 100644 index 0000000..36c9252 --- /dev/null +++ b/lib/urllib3/filepost.py @@ -0,0 +1,98 @@ +from __future__ import absolute_import + +import binascii +import codecs +import os +from io import BytesIO + +from .fields import RequestField +from .packages import six +from .packages.six import b + +writer = codecs.lookup("utf-8")[3] + + +def choose_boundary(): + """ + Our embarrassingly-simple replacement for mimetools.choose_boundary. + """ + boundary = binascii.hexlify(os.urandom(16)) + if not six.PY2: + boundary = boundary.decode("ascii") + return boundary + + +def iter_field_objects(fields): + """ + Iterate over fields. + + Supports list of (k, v) tuples and dicts, and lists of + :class:`~urllib3.fields.RequestField`. + + """ + if isinstance(fields, dict): + i = six.iteritems(fields) + else: + i = iter(fields) + + for field in i: + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) + + +def iter_fields(fields): + """ + .. deprecated:: 1.6 + + Iterate over fields. + + The addition of :class:`~urllib3.fields.RequestField` makes this function + obsolete. Instead, use :func:`iter_field_objects`, which returns + :class:`~urllib3.fields.RequestField` objects. + + Supports list of (k, v) tuples and dicts. + """ + if isinstance(fields, dict): + return ((k, v) for k, v in six.iteritems(fields)) + + return ((k, v) for k, v in fields) + + +def encode_multipart_formdata(fields, boundary=None): + """ + Encode a dictionary of ``fields`` using the multipart/form-data MIME format. + + :param fields: + Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). + + :param boundary: + If not specified, then a random boundary will be generated using + :func:`urllib3.filepost.choose_boundary`. + """ + body = BytesIO() + if boundary is None: + boundary = choose_boundary() + + for field in iter_field_objects(fields): + body.write(b("--%s\r\n" % (boundary))) + + writer(body).write(field.render_headers()) + data = field.data + + if isinstance(data, int): + data = str(data) # Backwards compatibility + + if isinstance(data, six.text_type): + writer(body).write(data) + else: + body.write(data) + + body.write(b"\r\n") + + body.write(b("--%s--\r\n" % (boundary))) + + content_type = str("multipart/form-data; boundary=%s" % boundary) + + return body.getvalue(), content_type diff --git a/lib/urllib3/packages/__init__.py b/lib/urllib3/packages/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/urllib3/packages/__pycache__/__init__.cpython-312.pyc b/lib/urllib3/packages/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5703b81a3fbb37c5417604dbf194f58711d413b GIT binary patch literal 189 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 literal 0 HcmV?d00001 diff --git a/lib/urllib3/packages/backports/__init__.py b/lib/urllib3/packages/backports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/lib/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc b/lib/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f9cd71d02e0a5d1954df75f59e2c5a999f3e3f1 GIT binary patch literal 199 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 literal 0 HcmV?d00001 diff --git a/lib/urllib3/packages/backports/makefile.py b/lib/urllib3/packages/backports/makefile.py new file mode 100644 index 0000000..b8fb215 --- /dev/null +++ b/lib/urllib3/packages/backports/makefile.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +""" +backports.makefile +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``socket.makefile`` method for use with anything that +wants to create a "fake" socket object. +""" +import io +from socket import SocketIO + + +def backport_makefile( + self, mode="r", buffering=None, encoding=None, errors=None, newline=None +): + """ + Backport of ``socket.makefile`` from Python 3.5. + """ + if not set(mode) <= {"r", "w", "b"}: + raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) + writing = "w" in mode + reading = "r" in mode or not writing + assert reading or writing + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = SocketIO(self, rawmode) + self._makefile_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text diff --git a/lib/urllib3/packages/backports/weakref_finalize.py b/lib/urllib3/packages/backports/weakref_finalize.py new file mode 100644 index 0000000..a2f2966 --- /dev/null +++ b/lib/urllib3/packages/backports/weakref_finalize.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +""" +backports.weakref_finalize +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``weakref.finalize`` method. +""" +from __future__ import absolute_import + +import itertools +import sys +from weakref import ref + +__all__ = ["weakref_finalize"] + + +class weakref_finalize(object): + """Class for finalization of weakrefable objects + finalize(obj, func, *args, **kwargs) returns a callable finalizer + object which will be called when obj is garbage collected. The + first time the finalizer is called it evaluates func(*arg, **kwargs) + and returns the result. After this the finalizer is dead, and + calling it just returns None. + When the program exits any remaining finalizers for which the + atexit attribute is true will be run in reverse order of creation. + By default atexit is true. + """ + + # Finalizer objects don't have any state of their own. They are + # just used as keys to lookup _Info objects in the registry. This + # ensures that they cannot be part of a ref-cycle. + + __slots__ = () + _registry = {} + _shutdown = False + _index_iter = itertools.count() + _dirty = False + _registered_with_atexit = False + + class _Info(object): + __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index") + + def __init__(self, obj, func, *args, **kwargs): + if not self._registered_with_atexit: + # We may register the exit function more than once because + # of a thread race, but that is harmless + import atexit + + atexit.register(self._exitfunc) + weakref_finalize._registered_with_atexit = True + info = self._Info() + info.weakref = ref(obj, self) + info.func = func + info.args = args + info.kwargs = kwargs or None + info.atexit = True + info.index = next(self._index_iter) + self._registry[self] = info + weakref_finalize._dirty = True + + def __call__(self, _=None): + """If alive then mark as dead and return func(*args, **kwargs); + otherwise return None""" + info = self._registry.pop(self, None) + if info and not self._shutdown: + return info.func(*info.args, **(info.kwargs or {})) + + def detach(self): + """If alive then mark as dead and return (obj, func, args, kwargs); + otherwise return None""" + info = self._registry.get(self) + obj = info and info.weakref() + if obj is not None and self._registry.pop(self, None): + return (obj, info.func, info.args, info.kwargs or {}) + + def peek(self): + """If alive then return (obj, func, args, kwargs); + otherwise return None""" + info = self._registry.get(self) + obj = info and info.weakref() + if obj is not None: + return (obj, info.func, info.args, info.kwargs or {}) + + @property + def alive(self): + """Whether finalizer is alive""" + return self in self._registry + + @property + def atexit(self): + """Whether finalizer should be called at exit""" + info = self._registry.get(self) + return bool(info) and info.atexit + + @atexit.setter + def atexit(self, value): + info = self._registry.get(self) + if info: + info.atexit = bool(value) + + def __repr__(self): + info = self._registry.get(self) + obj = info and info.weakref() + if obj is None: + return "<%s object at %#x; dead>" % (type(self).__name__, id(self)) + else: + return "<%s object at %#x; for %r at %#x>" % ( + type(self).__name__, + id(self), + type(obj).__name__, + id(obj), + ) + + @classmethod + def _select_for_exit(cls): + # Return live finalizers marked for exit, oldest first + L = [(f, i) for (f, i) in cls._registry.items() if i.atexit] + L.sort(key=lambda item: item[1].index) + return [f for (f, i) in L] + + @classmethod + def _exitfunc(cls): + # At shutdown invoke finalizers for which atexit is true. + # This is called once all other non-daemonic threads have been + # joined. + reenable_gc = False + try: + if cls._registry: + import gc + + if gc.isenabled(): + reenable_gc = True + gc.disable() + pending = None + while True: + if pending is None or weakref_finalize._dirty: + pending = cls._select_for_exit() + weakref_finalize._dirty = False + if not pending: + break + f = pending.pop() + try: + # gc is disabled, so (assuming no daemonic + # threads) the following is the only line in + # this function which might trigger creation + # of a new finalizer + f() + except Exception: + sys.excepthook(*sys.exc_info()) + assert f not in cls._registry + finally: + # prevent any more finalizers from executing during shutdown + weakref_finalize._shutdown = True + if reenable_gc: + gc.enable() diff --git a/lib/urllib3/packages/six.py b/lib/urllib3/packages/six.py new file mode 100644 index 0000000..f099a3d --- /dev/null +++ b/lib/urllib3/packages/six.py @@ -0,0 +1,1076 @@ +# Copyright (c) 2010-2020 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson " +__version__ = "1.16.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = (str,) + integer_types = (int,) + class_types = (type,) + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = (basestring,) + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + def __len__(self): + return 1 << 31 + + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + +if PY34: + from importlib.util import spec_from_loader +else: + spec_from_loader = None + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def find_spec(self, fullname, path, target=None): + if fullname in self.known_modules: + return spec_from_loader(fullname, self) + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + + get_source = get_code # same as get_code + + def create_module(self, spec): + return self.load_module(spec.name) + + def exec_module(self, module): + pass + + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute( + "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse" + ), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute( + "reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload" + ), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute( + "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest" + ), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule( + "collections_abc", + "collections", + "collections.abc" if sys.version_info >= (3, 3) else "collections", + ), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), + MovedModule( + "_dummy_thread", + "dummy_thread", + "_dummy_thread" if sys.version_info < (3, 9) else "_thread", + ), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule( + "email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart" + ), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute( + "unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes" + ), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module( + Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", + "moves.urllib.parse", +) + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module( + Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", + "moves.urllib.error", +) + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module( + Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", + "moves.urllib.request", +) + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module( + Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", + "moves.urllib.response", +) + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = ( + _urllib_robotparser_moved_attributes +) + +_importer._add_module( + Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", + "moves.urllib.robotparser", +) + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ["parse", "error", "request", "response", "robotparser"] + + +_importer._add_module( + Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib" +) + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + + def advance_iterator(it): + return it.next() + + +next = advance_iterator + + +try: + callable = callable +except NameError: + + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc( + get_unbound_function, """Get the function out of a possibly unbound function""" +) + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc( + iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary." +) + + +if PY3: + + def b(s): + return s.encode("latin-1") + + def u(s): + return s + + unichr = chr + import struct + + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + + StringIO = io.StringIO + BytesIO = io.BytesIO + del io + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" + _assertNotRegex = "assertNotRegex" +else: + + def b(s): + return s + + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape") + + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +def assertNotRegex(self, *args, **kwargs): + return getattr(self, _assertNotRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec ("""exec _code_ in _globs_, _locs_""") + + exec_( + """def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""" + ) + + +if sys.version_info[:2] > (3,): + exec_( + """def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""" + ) +else: + + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if ( + isinstance(fp, file) + and isinstance(data, unicode) + and fp.encoding is not None + ): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) + + +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + # This does exactly the same what the :func:`py3:functools.update_wrapper` + # function does on Python versions after 3.2. It sets the ``__wrapped__`` + # attribute on ``wrapper`` object and it doesn't raise an error if any of + # the attributes mentioned in ``assigned`` and ``updated`` are missing on + # ``wrapped`` object. + def _update_wrapper( + wrapper, + wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES, + ): + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + continue + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + wrapper.__wrapped__ = wrapped + return wrapper + + _update_wrapper.__doc__ = functools.update_wrapper.__doc__ + + def wraps( + wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES, + ): + return functools.partial( + _update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated + ) + + wraps.__doc__ = functools.wraps.__doc__ + +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + def __new__(cls, name, this_bases, d): + if sys.version_info[:2] >= (3, 7): + # This version introduced PEP 560 that requires a bit + # of extra care (we mimic what is done by __build_class__). + resolved_bases = types.resolve_bases(bases) + if resolved_bases is not bases: + d["__orig_bases__"] = bases + else: + resolved_bases = bases + return meta(name, resolved_bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + + return type.__new__(metaclass, "temporary_class", (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get("__slots__") + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop("__dict__", None) + orig_vars.pop("__weakref__", None) + if hasattr(cls, "__qualname__"): + orig_vars["__qualname__"] = cls.__qualname__ + return metaclass(cls.__name__, cls.__bases__, orig_vars) + + return wrapper + + +def ensure_binary(s, encoding="utf-8", errors="strict"): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, binary_type): + return s + if isinstance(s, text_type): + return s.encode(encoding, errors) + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding="utf-8", errors="strict"): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + # Optimization: Fast return for the common case. + if type(s) is str: + return s + if PY2 and isinstance(s, text_type): + return s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + return s.decode(encoding, errors) + elif not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + return s + + +def ensure_text(s, encoding="utf-8", errors="strict"): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def python_2_unicode_compatible(klass): + """ + A class decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if "__str__" not in klass.__dict__: + raise ValueError( + "@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % klass.__name__ + ) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode("utf-8") + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if ( + type(importer).__name__ == "_SixMetaPathImporter" + and importer.name == __name__ + ): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/lib/urllib3/poolmanager.py b/lib/urllib3/poolmanager.py new file mode 100644 index 0000000..fb51bf7 --- /dev/null +++ b/lib/urllib3/poolmanager.py @@ -0,0 +1,540 @@ +from __future__ import absolute_import + +import collections +import functools +import logging + +from ._collections import HTTPHeaderDict, RecentlyUsedContainer +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme +from .exceptions import ( + LocationValueError, + MaxRetryError, + ProxySchemeUnknown, + ProxySchemeUnsupported, + URLSchemeUnknown, +) +from .packages import six +from .packages.six.moves.urllib.parse import urljoin +from .request import RequestMethods +from .util.proxy import connection_requires_http_tunnel +from .util.retry import Retry +from .util.url import parse_url + +__all__ = ["PoolManager", "ProxyManager", "proxy_from_url"] + + +log = logging.getLogger(__name__) + +SSL_KEYWORDS = ( + "key_file", + "cert_file", + "cert_reqs", + "ca_certs", + "ssl_version", + "ca_cert_dir", + "ssl_context", + "key_password", + "server_hostname", +) + +# All known keyword arguments that could be provided to the pool manager, its +# pools, or the underlying connections. This is used to construct a pool key. +_key_fields = ( + "key_scheme", # str + "key_host", # str + "key_port", # int + "key_timeout", # int or float or Timeout + "key_retries", # int or Retry + "key_strict", # bool + "key_block", # bool + "key_source_address", # str + "key_key_file", # str + "key_key_password", # str + "key_cert_file", # str + "key_cert_reqs", # str + "key_ca_certs", # str + "key_ssl_version", # str + "key_ca_cert_dir", # str + "key_ssl_context", # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext + "key_maxsize", # int + "key_headers", # dict + "key__proxy", # parsed proxy url + "key__proxy_headers", # dict + "key__proxy_config", # class + "key_socket_options", # list of (level (int), optname (int), value (int or str)) tuples + "key__socks_options", # dict + "key_assert_hostname", # bool or string + "key_assert_fingerprint", # str + "key_server_hostname", # str +) + +#: The namedtuple class used to construct keys for the connection pool. +#: All custom key schemes should include the fields in this key at a minimum. +PoolKey = collections.namedtuple("PoolKey", _key_fields) + +_proxy_config_fields = ("ssl_context", "use_forwarding_for_https") +ProxyConfig = collections.namedtuple("ProxyConfig", _proxy_config_fields) + + +def _default_key_normalizer(key_class, request_context): + """ + Create a pool key out of a request context dictionary. + + According to RFC 3986, both the scheme and host are case-insensitive. + Therefore, this function normalizes both before constructing the pool + key for an HTTPS request. If you wish to change this behaviour, provide + alternate callables to ``key_fn_by_scheme``. + + :param key_class: + The class to use when constructing the key. This should be a namedtuple + with the ``scheme`` and ``host`` keys at a minimum. + :type key_class: namedtuple + :param request_context: + A dictionary-like object that contain the context for a request. + :type request_context: dict + + :return: A namedtuple that can be used as a connection pool key. + :rtype: PoolKey + """ + # Since we mutate the dictionary, make a copy first + context = request_context.copy() + context["scheme"] = context["scheme"].lower() + context["host"] = context["host"].lower() + + # These are both dictionaries and need to be transformed into frozensets + for key in ("headers", "_proxy_headers", "_socks_options"): + if key in context and context[key] is not None: + context[key] = frozenset(context[key].items()) + + # The socket_options key may be a list and needs to be transformed into a + # tuple. + socket_opts = context.get("socket_options") + if socket_opts is not None: + context["socket_options"] = tuple(socket_opts) + + # Map the kwargs to the names in the namedtuple - this is necessary since + # namedtuples can't have fields starting with '_'. + for key in list(context.keys()): + context["key_" + key] = context.pop(key) + + # Default to ``None`` for keys missing from the context + for field in key_class._fields: + if field not in context: + context[field] = None + + return key_class(**context) + + +#: A dictionary that maps a scheme to a callable that creates a pool key. +#: This can be used to alter the way pool keys are constructed, if desired. +#: Each PoolManager makes a copy of this dictionary so they can be configured +#: globally here, or individually on the instance. +key_fn_by_scheme = { + "http": functools.partial(_default_key_normalizer, PoolKey), + "https": functools.partial(_default_key_normalizer, PoolKey), +} + +pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool} + + +class PoolManager(RequestMethods): + """ + Allows for arbitrary requests while transparently keeping track of + necessary connection pools for you. + + :param num_pools: + Number of connection pools to cache before discarding the least + recently used pool. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param \\**connection_pool_kw: + Additional parameters are used to create fresh + :class:`urllib3.connectionpool.ConnectionPool` instances. + + Example:: + + >>> manager = PoolManager(num_pools=2) + >>> r = manager.request('GET', 'http://google.com/') + >>> r = manager.request('GET', 'http://google.com/mail') + >>> r = manager.request('GET', 'http://yahoo.com/') + >>> len(manager.pools) + 2 + + """ + + proxy = None + proxy_config = None + + def __init__(self, num_pools=10, headers=None, **connection_pool_kw): + RequestMethods.__init__(self, headers) + self.connection_pool_kw = connection_pool_kw + self.pools = RecentlyUsedContainer(num_pools) + + # Locally set the pool classes and keys so other PoolManagers can + # override them. + self.pool_classes_by_scheme = pool_classes_by_scheme + self.key_fn_by_scheme = key_fn_by_scheme.copy() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.clear() + # Return False to re-raise any potential exceptions + return False + + def _new_pool(self, scheme, host, port, request_context=None): + """ + Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and + any additional pool keyword arguments. + + If ``request_context`` is provided, it is provided as keyword arguments + to the pool class used. This method is used to actually create the + connection pools handed out by :meth:`connection_from_url` and + companion methods. It is intended to be overridden for customization. + """ + pool_cls = self.pool_classes_by_scheme[scheme] + if request_context is None: + request_context = self.connection_pool_kw.copy() + + # Although the context has everything necessary to create the pool, + # this function has historically only used the scheme, host, and port + # in the positional args. When an API change is acceptable these can + # be removed. + for key in ("scheme", "host", "port"): + request_context.pop(key, None) + + if scheme == "http": + for kw in SSL_KEYWORDS: + request_context.pop(kw, None) + + return pool_cls(host, port, **request_context) + + def clear(self): + """ + Empty our store of pools and direct them all to close. + + This will not affect in-flight connections, but they will not be + re-used after completion. + """ + self.pools.clear() + + def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None): + """ + Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme. + + If ``port`` isn't given, it will be derived from the ``scheme`` using + ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is + provided, it is merged with the instance's ``connection_pool_kw`` + variable and used to create the new connection pool, if one is + needed. + """ + + if not host: + raise LocationValueError("No host specified.") + + request_context = self._merge_pool_kwargs(pool_kwargs) + request_context["scheme"] = scheme or "http" + if not port: + port = port_by_scheme.get(request_context["scheme"].lower(), 80) + request_context["port"] = port + request_context["host"] = host + + return self.connection_from_context(request_context) + + def connection_from_context(self, request_context): + """ + Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context. + + ``request_context`` must at least contain the ``scheme`` key and its + value must be a key in ``key_fn_by_scheme`` instance variable. + """ + scheme = request_context["scheme"].lower() + pool_key_constructor = self.key_fn_by_scheme.get(scheme) + if not pool_key_constructor: + raise URLSchemeUnknown(scheme) + pool_key = pool_key_constructor(request_context) + + return self.connection_from_pool_key(pool_key, request_context=request_context) + + def connection_from_pool_key(self, pool_key, request_context=None): + """ + Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key. + + ``pool_key`` should be a namedtuple that only contains immutable + objects. At a minimum it must have the ``scheme``, ``host``, and + ``port`` fields. + """ + with self.pools.lock: + # If the scheme, host, or port doesn't match existing open + # connections, open a new ConnectionPool. + pool = self.pools.get(pool_key) + if pool: + return pool + + # Make a fresh ConnectionPool of the desired type + scheme = request_context["scheme"] + host = request_context["host"] + port = request_context["port"] + pool = self._new_pool(scheme, host, port, request_context=request_context) + self.pools[pool_key] = pool + + return pool + + def connection_from_url(self, url, pool_kwargs=None): + """ + Similar to :func:`urllib3.connectionpool.connection_from_url`. + + If ``pool_kwargs`` is not provided and a new pool needs to be + constructed, ``self.connection_pool_kw`` is used to initialize + the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` + is provided, it is used instead. Note that if a new pool does not + need to be created for the request, the provided ``pool_kwargs`` are + not used. + """ + u = parse_url(url) + return self.connection_from_host( + u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs + ) + + def _merge_pool_kwargs(self, override): + """ + Merge a dictionary of override values for self.connection_pool_kw. + + This does not modify self.connection_pool_kw and returns a new dict. + Any keys in the override dictionary with a value of ``None`` are + removed from the merged dictionary. + """ + base_pool_kwargs = self.connection_pool_kw.copy() + if override: + for key, value in override.items(): + if value is None: + try: + del base_pool_kwargs[key] + except KeyError: + pass + else: + base_pool_kwargs[key] = value + return base_pool_kwargs + + def _proxy_requires_url_absolute_form(self, parsed_url): + """ + Indicates if the proxy requires the complete destination URL in the + request. Normally this is only needed when not using an HTTP CONNECT + tunnel. + """ + if self.proxy is None: + return False + + return not connection_requires_http_tunnel( + self.proxy, self.proxy_config, parsed_url.scheme + ) + + def _validate_proxy_scheme_url_selection(self, url_scheme): + """ + Validates that were not attempting to do TLS in TLS connections on + Python2 or with unsupported SSL implementations. + """ + if self.proxy is None or url_scheme != "https": + return + + if self.proxy.scheme != "https": + return + + if six.PY2 and not self.proxy_config.use_forwarding_for_https: + raise ProxySchemeUnsupported( + "Contacting HTTPS destinations through HTTPS proxies " + "'via CONNECT tunnels' is not supported in Python 2" + ) + + def urlopen(self, method, url, redirect=True, **kw): + """ + Same as :meth:`urllib3.HTTPConnectionPool.urlopen` + with custom cross-host redirect logic and only sends the request-uri + portion of the ``url``. + + The given ``url`` parameter must be absolute, such that an appropriate + :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. + """ + u = parse_url(url) + self._validate_proxy_scheme_url_selection(u.scheme) + + conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) + + kw["assert_same_host"] = False + kw["redirect"] = False + + if "headers" not in kw: + kw["headers"] = self.headers.copy() + + if self._proxy_requires_url_absolute_form(u): + response = conn.urlopen(method, url, **kw) + else: + response = conn.urlopen(method, u.request_uri, **kw) + + redirect_location = redirect and response.get_redirect_location() + if not redirect_location: + return response + + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + + if response.status == 303: + # Change the method according to RFC 9110, Section 15.4.4. + method = "GET" + # And lose the body not to transfer anything sensitive. + kw["body"] = None + kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change() + + retries = kw.get("retries") + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + + # Strip headers marked as unsafe to forward to the redirected location. + # Check remove_headers_on_redirect to avoid a potential network call within + # conn.is_same_host() which may use socket.gethostbyname() in the future. + if retries.remove_headers_on_redirect and not conn.is_same_host( + redirect_location + ): + headers = list(six.iterkeys(kw["headers"])) + for header in headers: + if header.lower() in retries.remove_headers_on_redirect: + kw["headers"].pop(header, None) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: + if retries.raise_on_redirect: + response.drain_conn() + raise + return response + + kw["retries"] = retries + kw["redirect"] = redirect + + log.info("Redirecting %s -> %s", url, redirect_location) + + response.drain_conn() + return self.urlopen(method, redirect_location, **kw) + + +class ProxyManager(PoolManager): + """ + Behaves just like :class:`PoolManager`, but sends all requests through + the defined proxy, using the CONNECT method for HTTPS URLs. + + :param proxy_url: + The URL of the proxy to be used. + + :param proxy_headers: + A dictionary containing headers that will be sent to the proxy. In case + of HTTP they are being sent with each request, while in the + HTTPS/CONNECT case they are sent only once. Could be used for proxy + authentication. + + :param proxy_ssl_context: + The proxy SSL context is used to establish the TLS connection to the + proxy when using HTTPS proxies. + + :param use_forwarding_for_https: + (Defaults to False) If set to True will forward requests to the HTTPS + proxy to be made on behalf of the client instead of creating a TLS + tunnel via the CONNECT method. **Enabling this flag means that request + and response headers and content will be visible from the HTTPS proxy** + whereas tunneling keeps request and response headers and content + private. IP address, target hostname, SNI, and port are always visible + to an HTTPS proxy even when this flag is disabled. + + Example: + >>> proxy = urllib3.ProxyManager('http://localhost:3128/') + >>> r1 = proxy.request('GET', 'http://google.com/') + >>> r2 = proxy.request('GET', 'http://httpbin.org/') + >>> len(proxy.pools) + 1 + >>> r3 = proxy.request('GET', 'https://httpbin.org/') + >>> r4 = proxy.request('GET', 'https://twitter.com/') + >>> len(proxy.pools) + 3 + + """ + + def __init__( + self, + proxy_url, + num_pools=10, + headers=None, + proxy_headers=None, + proxy_ssl_context=None, + use_forwarding_for_https=False, + **connection_pool_kw + ): + + if isinstance(proxy_url, HTTPConnectionPool): + proxy_url = "%s://%s:%i" % ( + proxy_url.scheme, + proxy_url.host, + proxy_url.port, + ) + proxy = parse_url(proxy_url) + + if proxy.scheme not in ("http", "https"): + raise ProxySchemeUnknown(proxy.scheme) + + if not proxy.port: + port = port_by_scheme.get(proxy.scheme, 80) + proxy = proxy._replace(port=port) + + self.proxy = proxy + self.proxy_headers = proxy_headers or {} + self.proxy_ssl_context = proxy_ssl_context + self.proxy_config = ProxyConfig(proxy_ssl_context, use_forwarding_for_https) + + connection_pool_kw["_proxy"] = self.proxy + connection_pool_kw["_proxy_headers"] = self.proxy_headers + connection_pool_kw["_proxy_config"] = self.proxy_config + + super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw) + + def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None): + if scheme == "https": + return super(ProxyManager, self).connection_from_host( + host, port, scheme, pool_kwargs=pool_kwargs + ) + + return super(ProxyManager, self).connection_from_host( + self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs + ) + + def _set_proxy_headers(self, url, headers=None): + """ + Sets headers needed by proxies: specifically, the Accept and Host + headers. Only sets headers not provided by the user. + """ + headers_ = {"Accept": "*/*"} + + netloc = parse_url(url).netloc + if netloc: + headers_["Host"] = netloc + + if headers: + headers_.update(headers) + return headers_ + + def urlopen(self, method, url, redirect=True, **kw): + "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." + u = parse_url(url) + if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme): + # For connections using HTTP CONNECT, httplib sets the necessary + # headers on the CONNECT to the proxy. If we're not using CONNECT, + # we'll definitely need to set 'Host' at the very least. + headers = kw.get("headers", self.headers) + kw["headers"] = self._set_proxy_headers(url, headers) + + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) + + +def proxy_from_url(url, **kw): + return ProxyManager(proxy_url=url, **kw) diff --git a/lib/urllib3/request.py b/lib/urllib3/request.py new file mode 100644 index 0000000..3b4cf99 --- /dev/null +++ b/lib/urllib3/request.py @@ -0,0 +1,191 @@ +from __future__ import absolute_import + +import sys + +from .filepost import encode_multipart_formdata +from .packages import six +from .packages.six.moves.urllib.parse import urlencode + +__all__ = ["RequestMethods"] + + +class RequestMethods(object): + """ + Convenience mixin for classes who implement a :meth:`urlopen` method, such + as :class:`urllib3.HTTPConnectionPool` and + :class:`urllib3.PoolManager`. + + Provides behavior for making common types of HTTP request methods and + decides which type of request field encoding to use. + + Specifically, + + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). + + :meth:`.request_encode_body` is for sending requests whose fields are + encoded in the *body* of the request using multipart or www-form-urlencoded + (such as for POST, PUT, PATCH). + + :meth:`.request` is for making any kind of request, it will look up the + appropriate encoding format and use one of the above two methods to make + the request. + + Initializer parameters: + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + """ + + _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"} + + def __init__(self, headers=None): + self.headers = headers or {} + + def urlopen( + self, + method, + url, + body=None, + headers=None, + encode_multipart=True, + multipart_boundary=None, + **kw + ): # Abstract + raise NotImplementedError( + "Classes extending RequestMethods must implement " + "their own ``urlopen`` method." + ) + + def request(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the appropriate encoding of + ``fields`` based on the ``method`` used. + + This is a convenience method that requires the least amount of manual + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as + :meth:`request_encode_url`, :meth:`request_encode_body`, + or even the lowest level :meth:`urlopen`. + """ + method = method.upper() + + urlopen_kw["request_url"] = url + + if method in self._encode_url_methods: + return self.request_encode_url( + method, url, fields=fields, headers=headers, **urlopen_kw + ) + else: + return self.request_encode_body( + method, url, fields=fields, headers=headers, **urlopen_kw + ) + + def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the url. This is useful for request methods like GET, HEAD, DELETE, etc. + """ + if headers is None: + headers = self.headers + + extra_kw = {"headers": headers} + extra_kw.update(urlopen_kw) + + if fields: + url += "?" + urlencode(fields) + + return self.urlopen(method, url, **extra_kw) + + def request_encode_body( + self, + method, + url, + fields=None, + headers=None, + encode_multipart=True, + multipart_boundary=None, + **urlopen_kw + ): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the body. This is useful for request methods like POST, PUT, PATCH, etc. + + When ``encode_multipart=True`` (default), then + :func:`urllib3.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise + :func:`urllib.parse.urlencode` is used with the + 'application/x-www-form-urlencoded' content type. + + Multipart encoding must be used when posting files, and it's reasonably + safe to use it in other times too. However, it may break request + signing, such as with OAuth. + + Supports an optional ``fields`` parameter of key/value strings AND + key/filetuple. A filetuple is a (filename, data, MIME type) tuple where + the MIME type is optional. For example:: + + fields = { + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), + 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + } + + When uploading a file, providing a filename (the first parameter of the + tuple) is optional but recommended to best mimic behavior of browsers. + + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string + which is used to compose the body of the request. The random boundary + string can be explicitly set with the ``multipart_boundary`` parameter. + """ + if headers is None: + headers = self.headers + + extra_kw = {"headers": {}} + + if fields: + if "body" in urlopen_kw: + raise TypeError( + "request got values for both 'fields' and 'body', can only specify one." + ) + + if encode_multipart: + body, content_type = encode_multipart_formdata( + fields, boundary=multipart_boundary + ) + else: + body, content_type = ( + urlencode(fields), + "application/x-www-form-urlencoded", + ) + + extra_kw["body"] = body + extra_kw["headers"] = {"Content-Type": content_type} + + extra_kw["headers"].update(headers) + extra_kw.update(urlopen_kw) + + return self.urlopen(method, url, **extra_kw) + + +if not six.PY2: + + class RequestModule(sys.modules[__name__].__class__): + def __call__(self, *args, **kwargs): + """ + If user tries to call this module directly urllib3 v2.x style raise an error to the user + suggesting they may need urllib3 v2 + """ + raise TypeError( + "'module' object is not callable\n" + "urllib3.request() method is not supported in this release, " + "upgrade to urllib3 v2 to use it\n" + "see https://urllib3.readthedocs.io/en/stable/v2-migration-guide.html" + ) + + sys.modules[__name__].__class__ = RequestModule diff --git a/lib/urllib3/response.py b/lib/urllib3/response.py new file mode 100644 index 0000000..0bd13d4 --- /dev/null +++ b/lib/urllib3/response.py @@ -0,0 +1,885 @@ +from __future__ import absolute_import + +import io +import logging +import sys +import warnings +import zlib +from contextlib import contextmanager +from socket import error as SocketError +from socket import timeout as SocketTimeout + +try: + try: + import brotlicffi as brotli + except ImportError: + import brotli +except ImportError: + brotli = None + +from . import util +from ._collections import HTTPHeaderDict +from .connection import BaseSSLError, HTTPException +from .exceptions import ( + BodyNotHttplibCompatible, + DecodeError, + HTTPError, + IncompleteRead, + InvalidChunkLength, + InvalidHeader, + ProtocolError, + ReadTimeoutError, + ResponseNotChunked, + SSLError, +) +from .packages import six +from .util.response import is_fp_closed, is_response_to_head + +log = logging.getLogger(__name__) + + +class DeflateDecoder(object): + def __init__(self): + self._first_try = True + self._data = b"" + self._obj = zlib.decompressobj() + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + + if not self._first_try: + return self._obj.decompress(data) + + self._data += data + try: + decompressed = self._obj.decompress(data) + if decompressed: + self._first_try = False + self._data = None + return decompressed + except zlib.error: + self._first_try = False + self._obj = zlib.decompressobj(-zlib.MAX_WBITS) + try: + return self.decompress(self._data) + finally: + self._data = None + + +class GzipDecoderState(object): + + FIRST_MEMBER = 0 + OTHER_MEMBERS = 1 + SWALLOW_DATA = 2 + + +class GzipDecoder(object): + def __init__(self): + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + self._state = GzipDecoderState.FIRST_MEMBER + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + ret = bytearray() + if self._state == GzipDecoderState.SWALLOW_DATA or not data: + return bytes(ret) + while True: + try: + ret += self._obj.decompress(data) + except zlib.error: + previous_state = self._state + # Ignore data after the first error + self._state = GzipDecoderState.SWALLOW_DATA + if previous_state == GzipDecoderState.OTHER_MEMBERS: + # Allow trailing garbage acceptable in other gzip clients + return bytes(ret) + raise + data = self._obj.unused_data + if not data: + return bytes(ret) + self._state = GzipDecoderState.OTHER_MEMBERS + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + + +if brotli is not None: + + class BrotliDecoder(object): + # Supports both 'brotlipy' and 'Brotli' packages + # since they share an import name. The top branches + # are for 'brotlipy' and bottom branches for 'Brotli' + def __init__(self): + self._obj = brotli.Decompressor() + if hasattr(self._obj, "decompress"): + self.decompress = self._obj.decompress + else: + self.decompress = self._obj.process + + def flush(self): + if hasattr(self._obj, "flush"): + return self._obj.flush() + return b"" + + +class MultiDecoder(object): + """ + From RFC7231: + If one or more encodings have been applied to a representation, the + sender that applied the encodings MUST generate a Content-Encoding + header field that lists the content codings in the order in which + they were applied. + """ + + def __init__(self, modes): + self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] + + def flush(self): + return self._decoders[0].flush() + + def decompress(self, data): + for d in reversed(self._decoders): + data = d.decompress(data) + return data + + +def _get_decoder(mode): + if "," in mode: + return MultiDecoder(mode) + + if mode == "gzip": + return GzipDecoder() + + if brotli is not None and mode == "br": + return BrotliDecoder() + + return DeflateDecoder() + + +class HTTPResponse(io.IOBase): + """ + HTTP Response container. + + Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. + + Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`: + + :param preload_content: + If True, the response's body will be preloaded during construction. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param original_response: + When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse` + object, it's convenient to include the original for debug purposes. It's + otherwise unused. + + :param retries: + The retries contains the last :class:`~urllib3.util.retry.Retry` that + was used during the request. + + :param enforce_content_length: + Enforce content length checking. Body returned by server must match + value of Content-Length header, if present. Otherwise, raise error. + """ + + CONTENT_DECODERS = ["gzip", "deflate"] + if brotli is not None: + CONTENT_DECODERS += ["br"] + REDIRECT_STATUSES = [301, 302, 303, 307, 308] + + def __init__( + self, + body="", + headers=None, + status=0, + version=0, + reason=None, + strict=0, + preload_content=True, + decode_content=True, + original_response=None, + pool=None, + connection=None, + msg=None, + retries=None, + enforce_content_length=False, + request_method=None, + request_url=None, + auto_close=True, + ): + + if isinstance(headers, HTTPHeaderDict): + self.headers = headers + else: + self.headers = HTTPHeaderDict(headers) + self.status = status + self.version = version + self.reason = reason + self.strict = strict + self.decode_content = decode_content + self.retries = retries + self.enforce_content_length = enforce_content_length + self.auto_close = auto_close + + self._decoder = None + self._body = None + self._fp = None + self._original_response = original_response + self._fp_bytes_read = 0 + self.msg = msg + self._request_url = request_url + + if body and isinstance(body, (six.string_types, bytes)): + self._body = body + + self._pool = pool + self._connection = connection + + if hasattr(body, "read"): + self._fp = body + + # Are we using the chunked-style of transfer encoding? + self.chunked = False + self.chunk_left = None + tr_enc = self.headers.get("transfer-encoding", "").lower() + # Don't incur the penalty of creating a list and then discarding it + encodings = (enc.strip() for enc in tr_enc.split(",")) + if "chunked" in encodings: + self.chunked = True + + # Determine length of response + self.length_remaining = self._init_length(request_method) + + # If requested, preload the body. + if preload_content and not self._body: + self._body = self.read(decode_content=decode_content) + + def get_redirect_location(self): + """ + Should we redirect and where to? + + :returns: Truthy redirect location string if we got a redirect status + code and valid location. ``None`` if redirect status and no + location. ``False`` if not a redirect status code. + """ + if self.status in self.REDIRECT_STATUSES: + return self.headers.get("location") + + return False + + def release_conn(self): + if not self._pool or not self._connection: + return + + self._pool._put_conn(self._connection) + self._connection = None + + def drain_conn(self): + """ + Read and discard any remaining HTTP response data in the response connection. + + Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. + """ + try: + self.read() + except (HTTPError, SocketError, BaseSSLError, HTTPException): + pass + + @property + def data(self): + # For backwards-compat with earlier urllib3 0.4 and earlier. + if self._body: + return self._body + + if self._fp: + return self.read(cache_content=True) + + @property + def connection(self): + return self._connection + + def isclosed(self): + return is_fp_closed(self._fp) + + def tell(self): + """ + Obtain the number of bytes pulled over the wire so far. May differ from + the amount of content returned by :meth:``urllib3.response.HTTPResponse.read`` + if bytes are encoded on the wire (e.g, compressed). + """ + return self._fp_bytes_read + + def _init_length(self, request_method): + """ + Set initial length value for Response content if available. + """ + length = self.headers.get("content-length") + + if length is not None: + if self.chunked: + # This Response will fail with an IncompleteRead if it can't be + # received as chunked. This method falls back to attempt reading + # the response before raising an exception. + log.warning( + "Received response with both Content-Length and " + "Transfer-Encoding set. This is expressly forbidden " + "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " + "attempting to process response as Transfer-Encoding: " + "chunked." + ) + return None + + try: + # RFC 7230 section 3.3.2 specifies multiple content lengths can + # be sent in a single Content-Length header + # (e.g. Content-Length: 42, 42). This line ensures the values + # are all valid ints and that as long as the `set` length is 1, + # all values are the same. Otherwise, the header is invalid. + lengths = set([int(val) for val in length.split(",")]) + if len(lengths) > 1: + raise InvalidHeader( + "Content-Length contained multiple " + "unmatching values (%s)" % length + ) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + # Convert status to int for comparison + # In some cases, httplib returns a status of "_UNKNOWN" + try: + status = int(self.status) + except ValueError: + status = 0 + + # Check for responses that shouldn't include a body + if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD": + length = 0 + + return length + + def _init_decoder(self): + """ + Set-up the _decoder attribute if necessary. + """ + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 + content_encoding = self.headers.get("content-encoding", "").lower() + if self._decoder is None: + if content_encoding in self.CONTENT_DECODERS: + self._decoder = _get_decoder(content_encoding) + elif "," in content_encoding: + encodings = [ + e.strip() + for e in content_encoding.split(",") + if e.strip() in self.CONTENT_DECODERS + ] + if len(encodings): + self._decoder = _get_decoder(content_encoding) + + DECODER_ERROR_CLASSES = (IOError, zlib.error) + if brotli is not None: + DECODER_ERROR_CLASSES += (brotli.error,) + + def _decode(self, data, decode_content, flush_decoder): + """ + Decode the data passed in and potentially flush the decoder. + """ + if not decode_content: + return data + + try: + if self._decoder: + data = self._decoder.decompress(data) + except self.DECODER_ERROR_CLASSES as e: + content_encoding = self.headers.get("content-encoding", "").lower() + raise DecodeError( + "Received response with content-encoding: %s, but " + "failed to decode it." % content_encoding, + e, + ) + if flush_decoder: + data += self._flush_decoder() + + return data + + def _flush_decoder(self): + """ + Flushes the decoder. Should only be called if the decoder is actually + being used. + """ + if self._decoder: + buf = self._decoder.decompress(b"") + return buf + self._decoder.flush() + + return b"" + + @contextmanager + def _error_catcher(self): + """ + Catch low-level python exceptions, instead re-raising urllib3 + variants, so that low-level exceptions are not leaked in the + high-level api. + + On exit, release the connection back to the pool. + """ + clean_exit = False + + try: + try: + yield + + except SocketTimeout: + # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but + # there is yet no clean way to get at it from this context. + raise ReadTimeoutError(self._pool, None, "Read timed out.") + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + if "read operation timed out" not in str(e): + # SSL errors related to framing/MAC get wrapped and reraised here + raise SSLError(e) + + raise ReadTimeoutError(self._pool, None, "Read timed out.") + + except (HTTPException, SocketError) as e: + # This includes IncompleteRead. + raise ProtocolError("Connection broken: %r" % e, e) + + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + finally: + # If we didn't terminate cleanly, we need to throw away our + # connection. + if not clean_exit: + # The response may not be closed but we're not going to use it + # anymore so close it now to ensure that the connection is + # released back to the pool. + if self._original_response: + self._original_response.close() + + # Closing the response may not actually be sufficient to close + # everything, so if we have a hold of the connection close that + # too. + if self._connection: + self._connection.close() + + # If we hold the original response but it's closed now, we should + # return the connection back to the pool. + if self._original_response and self._original_response.isclosed(): + self.release_conn() + + def _fp_read(self, amt): + """ + Read a response with the thought that reading the number of bytes + larger than can fit in a 32-bit int at a time via SSL in some + known cases leads to an overflow error that has to be prevented + if `amt` or `self.length_remaining` indicate that a problem may + happen. + + The known cases: + * 3.8 <= CPython < 3.9.7 because of a bug + https://github.com/urllib3/urllib3/issues/2513#issuecomment-1152559900. + * urllib3 injected with pyOpenSSL-backed SSL-support. + * CPython < 3.10 only when `amt` does not fit 32-bit int. + """ + assert self._fp + c_int_max = 2 ** 31 - 1 + if ( + ( + (amt and amt > c_int_max) + or (self.length_remaining and self.length_remaining > c_int_max) + ) + and not util.IS_SECURETRANSPORT + and (util.IS_PYOPENSSL or sys.version_info < (3, 10)) + ): + buffer = io.BytesIO() + # Besides `max_chunk_amt` being a maximum chunk size, it + # affects memory overhead of reading a response by this + # method in CPython. + # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum + # chunk size that does not lead to an overflow error, but + # 256 MiB is a compromise. + max_chunk_amt = 2 ** 28 + while amt is None or amt != 0: + if amt is not None: + chunk_amt = min(amt, max_chunk_amt) + amt -= chunk_amt + else: + chunk_amt = max_chunk_amt + data = self._fp.read(chunk_amt) + if not data: + break + buffer.write(data) + del data # to reduce peak memory usage by `max_chunk_amt`. + return buffer.getvalue() + else: + # StringIO doesn't like amt=None + return self._fp.read(amt) if amt is not None else self._fp.read() + + def read(self, amt=None, decode_content=None, cache_content=False): + """ + Similar to :meth:`http.client.HTTPResponse.read`, but with two additional + parameters: ``decode_content`` and ``cache_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param cache_content: + If True, will save the returned data such that the same result is + returned despite of the state of the underlying file object. This + is useful if you want the ``.data`` property to continue working + after having ``.read()`` the file object. (Overridden if ``amt`` is + set.) + """ + self._init_decoder() + if decode_content is None: + decode_content = self.decode_content + + if self._fp is None: + return + + flush_decoder = False + fp_closed = getattr(self._fp, "closed", False) + + with self._error_catcher(): + data = self._fp_read(amt) if not fp_closed else b"" + if amt is None: + flush_decoder = True + else: + cache_content = False + if ( + amt != 0 and not data + ): # Platform-specific: Buggy versions of Python. + # Close the connection when no data is returned + # + # This is redundant to what httplib/http.client _should_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # no harm in redundantly calling close. + self._fp.close() + flush_decoder = True + if self.enforce_content_length and self.length_remaining not in ( + 0, + None, + ): + # This is an edge case that httplib failed to cover due + # to concerns of backward compatibility. We're + # addressing it here to make sure IncompleteRead is + # raised during streaming, so all calls with incorrect + # Content-Length are caught. + raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + + if data: + self._fp_bytes_read += len(data) + if self.length_remaining is not None: + self.length_remaining -= len(data) + + data = self._decode(data, decode_content, flush_decoder) + + if cache_content: + self._body = data + + return data + + def stream(self, amt=2 ** 16, decode_content=None): + """ + A generator wrapper for the read() method. A call will block until + ``amt`` bytes have been read from the connection or until the + connection is closed. + + :param amt: + How much of the content to read. The generator will return up to + much data per iteration, but may return less. This is particularly + likely when using compressed data. However, the empty string will + never be returned. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if self.chunked and self.supports_chunked_reads(): + for line in self.read_chunked(amt, decode_content=decode_content): + yield line + else: + while not is_fp_closed(self._fp): + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + + @classmethod + def from_httplib(ResponseCls, r, **response_kw): + """ + Given an :class:`http.client.HTTPResponse` instance ``r``, return a + corresponding :class:`urllib3.response.HTTPResponse` object. + + Remaining parameters are passed to the HTTPResponse constructor, along + with ``original_response=r``. + """ + headers = r.msg + + if not isinstance(headers, HTTPHeaderDict): + if six.PY2: + # Python 2.7 + headers = HTTPHeaderDict.from_httplib(headers) + else: + headers = HTTPHeaderDict(headers.items()) + + # HTTPResponse objects in Python 3 don't have a .strict attribute + strict = getattr(r, "strict", 0) + resp = ResponseCls( + body=r, + headers=headers, + status=r.status, + version=r.version, + reason=r.reason, + strict=strict, + original_response=r, + **response_kw + ) + return resp + + # Backwards-compatibility methods for http.client.HTTPResponse + def getheaders(self): + warnings.warn( + "HTTPResponse.getheaders() is deprecated and will be removed " + "in urllib3 v2.1.0. Instead access HTTPResponse.headers directly.", + category=DeprecationWarning, + stacklevel=2, + ) + return self.headers + + def getheader(self, name, default=None): + warnings.warn( + "HTTPResponse.getheader() is deprecated and will be removed " + "in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).", + category=DeprecationWarning, + stacklevel=2, + ) + return self.headers.get(name, default) + + # Backwards compatibility for http.cookiejar + def info(self): + return self.headers + + # Overrides from io.IOBase + def close(self): + if not self.closed: + self._fp.close() + + if self._connection: + self._connection.close() + + if not self.auto_close: + io.IOBase.close(self) + + @property + def closed(self): + if not self.auto_close: + return io.IOBase.closed.__get__(self) + elif self._fp is None: + return True + elif hasattr(self._fp, "isclosed"): + return self._fp.isclosed() + elif hasattr(self._fp, "closed"): + return self._fp.closed + else: + return True + + def fileno(self): + if self._fp is None: + raise IOError("HTTPResponse has no file to get a fileno from") + elif hasattr(self._fp, "fileno"): + return self._fp.fileno() + else: + raise IOError( + "The file-like object this HTTPResponse is wrapped " + "around has no file descriptor" + ) + + def flush(self): + if ( + self._fp is not None + and hasattr(self._fp, "flush") + and not getattr(self._fp, "closed", False) + ): + return self._fp.flush() + + def readable(self): + # This method is required for `io` module compatibility. + return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[: len(temp)] = temp + return len(temp) + + def supports_chunked_reads(self): + """ + Checks if the underlying file-like object looks like a + :class:`http.client.HTTPResponse` object. We do this by testing for + the fp attribute. If it is present we assume it returns raw chunks as + processed by read_chunked(). + """ + return hasattr(self._fp, "fp") + + def _update_chunk_length(self): + # First, we'll figure out length of a chunk and then + # we'll try to read it from socket. + if self.chunk_left is not None: + return + line = self._fp.fp.readline() + line = line.split(b";", 1)[0] + try: + self.chunk_left = int(line, 16) + except ValueError: + # Invalid chunked protocol response, abort. + self.close() + raise InvalidChunkLength(self, line) + + def _handle_chunk(self, amt): + returned_chunk = None + if amt is None: + chunk = self._fp._safe_read(self.chunk_left) + returned_chunk = chunk + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + elif amt < self.chunk_left: + value = self._fp._safe_read(amt) + self.chunk_left = self.chunk_left - amt + returned_chunk = value + elif amt == self.chunk_left: + value = self._fp._safe_read(amt) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + returned_chunk = value + else: # amt > self.chunk_left + returned_chunk = self._fp._safe_read(self.chunk_left) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + return returned_chunk + + def read_chunked(self, amt=None, decode_content=None): + """ + Similar to :meth:`HTTPResponse.read`, but with an additional + parameter: ``decode_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + self._init_decoder() + # FIXME: Rewrite this method and make it a class with a better structured logic. + if not self.chunked: + raise ResponseNotChunked( + "Response is not chunked. " + "Header 'transfer-encoding: chunked' is missing." + ) + if not self.supports_chunked_reads(): + raise BodyNotHttplibCompatible( + "Body should be http.client.HTTPResponse like. " + "It should have have an fp attribute which returns raw chunks." + ) + + with self._error_catcher(): + # Don't bother reading the body of a HEAD request. + if self._original_response and is_response_to_head(self._original_response): + self._original_response.close() + return + + # If a response is already read and closed + # then return immediately. + if self._fp.fp is None: + return + + while True: + self._update_chunk_length() + if self.chunk_left == 0: + break + chunk = self._handle_chunk(amt) + decoded = self._decode( + chunk, decode_content=decode_content, flush_decoder=False + ) + if decoded: + yield decoded + + if decode_content: + # On CPython and PyPy, we should never need to flush the + # decoder. However, on Jython we *might* need to, so + # lets defensively do it anyway. + decoded = self._flush_decoder() + if decoded: # Platform-specific: Jython. + yield decoded + + # Chunk content ends with \r\n: discard it. + while True: + line = self._fp.fp.readline() + if not line: + # Some sites may not end with '\r\n'. + break + if line == b"\r\n": + break + + # We read everything; close the "file". + if self._original_response: + self._original_response.close() + + def geturl(self): + """ + Returns the URL that was the source of this response. + If the request that generated this response redirected, this method + will return the final redirect location. + """ + if self.retries is not None and len(self.retries.history): + return self.retries.history[-1].redirect_location + else: + return self._request_url + + def __iter__(self): + buffer = [] + for chunk in self.stream(decode_content=True): + if b"\n" in chunk: + chunk = chunk.split(b"\n") + yield b"".join(buffer) + chunk[0] + b"\n" + for x in chunk[1:-1]: + yield x + b"\n" + if chunk[-1]: + buffer = [chunk[-1]] + else: + buffer = [] + else: + buffer.append(chunk) + if buffer: + yield b"".join(buffer) diff --git a/lib/urllib3/util/__init__.py b/lib/urllib3/util/__init__.py new file mode 100644 index 0000000..4547fc5 --- /dev/null +++ b/lib/urllib3/util/__init__.py @@ -0,0 +1,49 @@ +from __future__ import absolute_import + +# For backwards compatibility, provide imports that used to be here. +from .connection import is_connection_dropped +from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers +from .response import is_fp_closed +from .retry import Retry +from .ssl_ import ( + ALPN_PROTOCOLS, + HAS_SNI, + IS_PYOPENSSL, + IS_SECURETRANSPORT, + PROTOCOL_TLS, + SSLContext, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .timeout import Timeout, current_time +from .url import Url, get_host, parse_url, split_first +from .wait import wait_for_read, wait_for_write + +__all__ = ( + "HAS_SNI", + "IS_PYOPENSSL", + "IS_SECURETRANSPORT", + "SSLContext", + "PROTOCOL_TLS", + "ALPN_PROTOCOLS", + "Retry", + "Timeout", + "Url", + "assert_fingerprint", + "current_time", + "is_connection_dropped", + "is_fp_closed", + "get_host", + "parse_url", + "make_headers", + "resolve_cert_reqs", + "resolve_ssl_version", + "split_first", + "ssl_wrap_socket", + "wait_for_read", + "wait_for_write", + "SKIP_HEADER", + "SKIPPABLE_HEADERS", +) diff --git a/lib/urllib3/util/__pycache__/__init__.cpython-312.pyc b/lib/urllib3/util/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b94db7197059444006dcb7cc98f6825599e40d9d GIT binary patch literal 1136 zcmZ9LO^X{x5Qcm7HTu>{`(dqj?br?&E5Y7Fz=x0ol(oQ1gd{XtNSc9WtZ8|N?Vg!* z_jsdY$RR%=zajVhi=0Ak4a**K^37m^!KYNsdM(Ht9_p=`?y9#+`m@!l6L`v{Usu1B z2>A!a%~SXgy!``$-$+P8M-b^y$01=MEQ*3G(qbN$L`jxuSypI8y41~cWl@ziTFc{# zsLKXz@6-FB8}z}tIcU8`3j@b?f)_dwnc*ywX`;+) z=Q_U|X|_z_m@iF~#4J=vn(}Z^v<>gOlNozH8a^A%Z5PFC`0aS~A>-Mm49+<_<3Y%k zh5}8vXqB?1NHm;xYVM}0uI*Uv*RQ-{3m03f!16Zwu<7HT%{_CjqNH97GH6; z#5aonsO|PmN^8MhL8IW&c2HcXAZ0pPo^vxOSa%Ugo@B;0mzh#LHq1a`P_o5SC2aL2 zH|#9Y#@5n6Y0ff8HgqZ?Y(Qzep>+|UN)!|hLfif*FH~gsps$)RZ`DGy5nG53qJhBQ zpxQ;;LUa*(h%%yv=p*(KRYVW5jkt~2K^!0s5fy|Bm<&F(b;eei$rNWy6(MKqn~moM ztP9i1xHg+}c@bNM`K3t=qsA6&S>aCeW^D;V-yM z{WMA+n?S(=AFs~MYOO9-zKCA<>Drtnu@8koeQ}hTNE|U1#jr#6BwfF+ekGGI6Z{+X z85F|*ivAk#rsz1%C3*O7g*Z>H$nY;Ryd)1UN&j7;;S}DHkLVNU^DFZ7Z}Rkt9K9*+ MHwr(y>Ji-VA4_L6)Bpeg literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/connection.cpython-312.pyc b/lib/urllib3/util/__pycache__/connection.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f9ef4329d83566b169772990c339c577976612a GIT binary patch literal 4746 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 A00000 literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/proxy.cpython-312.pyc b/lib/urllib3/util/__pycache__/proxy.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..91a294bae356ff57415c53a32c5da06f19d754c3 GIT binary patch literal 1542 zcmZ8h&2QT_6elgqkrStJZ7(yrtkW8-jeyiev5!MGv>4Kl4GG*Jb#@302#Q48N@YnS zsk9z6Acq0lakuoi-;foXvxN-R#yhy1hb<5YkX|-1L#V5_?!^IZ((ID#fq<=_*7lX#Q z%(oC))avVNtIN7nivwAZ7Ew*8gS1E%B(zz~ib%5<_#L;K#R3pmT!u>z0S~khwIsq0 z4f=W*1YY0rtuCRBa4-slajH9nao3mbCbN5_PcBooV85wu2yDc=q0hMuqW3rt*}VMC z>xA2eEbu7F3qztxbIZsjg)~u8j~FpK0ex;!$Mw5HG^G>pqENhuZ6?Ie|vx*19) zH~{DKZf$X)y~cnk?PUw5ufy=+qFusocb@UifIjcEfrssI zzhnRXu_1_ zzkslVxM(Cf_(dzkXgAaHi^v!cb${aBjN(74agOP+!mh`8Hp9n;nPSz+4Si@iRyT`7 z%jJJJ6ETX_r_jkiwB_wSCO!d%3FZTTI#%TIl$1Jjt)QUjZqYD-4+OE8e~arIg!sZ~ z%XNsOZwy3p$Yj6=+K>{kWMZW4lj7yGQ1JrGF|%6oxnPD$#aU3Xc`7a<8G}+5=akl9 zWfW*dSgOLJ*;X2qOk|SjxHKtUEPyd-?F>8<7Xa*nL9d7m_3Q~tX(>=;_Dy3dZ?ToL#vC%3 zLuC3?|AnzX#TUnrX;cuz2j9l3FMINwq?z0B!3+Ize%;gWe)lBr1_p9~OI4Pt+YI14 zIoVQsMz?`R2OMyi2PQa@BYUhanGz#g@#MN-K3!$8IveqbSJJu^seo2@6rlqgOy+jvUOs!TpAknf_-|$tnCZa3S=EU9fi=f6t_)f!TO>+X6Kl5b^M;f0R@{)+_Yqet zKMLE2_s~Y4vZX-3c;32G$h;Nk?qDTGx>4xCUBIzdnWPNN!EOeg9&tCa-dQ+=?1e zz@3bD5>1H=W0Sw+cJ!<1(XNSem>}T-`hsl9jIqx!_ybOUg^_Qvwlw~H{JS#xOUtv; PYqgVqlm889CY}BOj`I#G literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/request.cpython-312.pyc b/lib/urllib3/util/__pycache__/request.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50cb9138d93d8bd4a9fdef7f47439b292bba13a7 GIT binary patch literal 4412 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 KNS6e*H=KN3I2mJ^p~L)Be|EVN zCFjrqc6Mgxf6dJQegFO~nT#W7n)-{v?~@39BPL;!>w||shQV!QAVacHQJRt@F_ta4 zs7xtEbxMV~VyKo@j7&xRv1Ub!v8g5)M}Cf`;zktugb{*Q23gdvGCWTMl6iOTN zWbUEZDfw*7Z_feBYciftm9d8k=VFkTBP4H7YKG{=HY0u$#C9s7%{SO zUvCgDLNAKdL4Pi6P0o?W6}f}+!bjE@8(+!1Y3nl{p=|m!xbEp;*B#Zl zKK+`L*RAPEQgo+X)9r_xnI*ixu)qstx>T69%$aGo%;y|?xo>r-tQ7Pu(G(mxY2Rrh@IV7^Zj^7wev^Y@!_gET#E{uECc?p zr`ym6O{bJ!NvD)wC$i|bO@qoGq(SA6$>C=7d2`e7S>^LH67)y%JO-M6o__#GcN_78 z9IrIw^Za*Y?q)sPSs#yr4Zj)E{6Y4G-w@)7a9lx~b^FKP*Ch^I6SN92iJ@$YsGzML zT~QlWKx$Q~$n*kWGaX1b_8~UeX&F`IaJH&8>`~<{p$2aYM+G_D8A#H7W%v{ zm6g0KfuB`v31uSsML04aL&FSGnm1t9vhbWwY7Ecmiv-UQKrk!i^MtWN$+F5A!0JO+ zpmc1RQ#}v*#Lfdf0tAVHiQqwo3)CrMAOZ}z4s45^g0Bih8G5M0|8*OzE;$sa!?E!d zA1!#`C^ra7%?6a3y)-#_rEP^_ZT)vku4Co?Xp)QNyn#Y}`u# zE96|gY&p7-k!d^Jlb0;n!CB@EV3JJIiUUejdR4N0ru(4x*g zmBS}53ifqiHJ?n1VR7@cnKCELQy8aI1D{lYjtXpLBH$vpXg?Y%(v5aP=SAyrdXakg zqE?98#+ZuK_BwSxYjS};Y|Afyv=7$42M_xSx;6CeDb(C`Yxbk1JEx!9I{n;EVqh=T zUF{jV(=)QwGxF!rzjS|jdAsM0?bJjyHgP}Id24o~{K>iP)P=Q|_u6_l&VT&F-<{iT zdtvR>dmTM%m+wZ~1PgZGN%w7~`*zY#-R(N_Ve!Vx_tPNyo3YOZJ|5ahKf8<1-%8$% zrfMh9lV|^}McU){TDtbyPwuvK?esps^MkjlJ#T-j$Q`MD4JF%a3JBbY))2h@*@9x} z_xtx!_>=BGC3jNe)!2AVLGAdz`>n9d#2I|idU`}vk5HXBPoL`MVQ^a%ba)?cKsR;b zL8v0}1L6zeNddryv;b!}0qgSz)OTnnBpO2wq@d*f%g67rk{iJ7-4bCw-gJRIzs>-d zS%767Um6=8?We?-3X=JfZW|VWM5w=8GJPZ#FqF74dlpJ+2&JG*ABW-_p^MPhA&L%` z!orQsg73tkCK!g_Eg*w>B>r|pj+KC2@OcsBc??18xCp-!P91g+#6fzhSk0(jG#9K< z!H}L}+T7Dhu1hHV;>E&nyhtF#L~#jIxE*S4D3IfhpUU(Z5cnxP?0M**^md?B*PZ0a zt>nqIm-eEqx1Ro}Zzpx_+%1dtx`ydUI%f=)H>@SGN*iGp=HkM`Pa<=F!5=KQmrQMpnMb?Dmq5VA{XfZOhrj#ebB)Vf+T&7p8f}V>+k6MU!xcHBPXO6rTvQo P((BSgOG--Td?Wt@ZP)?W literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/retry.cpython-312.pyc b/lib/urllib3/util/__pycache__/retry.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98da92ec7f50544c752a1dfc6836a93ff5a30fcb GIT binary patch literal 21708 zcmch9eQ+DcmFM7-AOI2|`28VrBvB$kQ4sZI*_36QmMDw1EXgEoCyX5s%Ipy0>N$x~mc2~-+cTJyt7y0bla@FP!Z{1a0vUh)E>#A-6Q3;WWQl-?Y>dISn zRkY|-a{23iuX|=N03l~{&ZZ^yOn-O3e(&|`_uk-t*3`HK1c&__Gdo@pgny)j9-P|C z=HnJYxG6}2WQhrLmI;f6-mNj~gq1yQ6E^m=PuSVhG2viO=Y$haTdZo%HQ{1y?6K-O z_k36lFwLGsA$AK0`y9jMbV zJE&DMJ>(9(ch=5}b~WftYiIP@iT0gRtzK8|40q|BELelSPbd+zsJ_TlG7(Fsis!l~N%9k%hWAZ07|6r9`e>@S7%hRdx=$xELr-l_Jp{O+@ z@k^0dR5~R`BpJyUBUeV{l(L|eo>LO3#B?IYlWruhXhr@}v?%RrR8Gz(;z^lR#uRMH z=oPhgRQ_68PNq&plc|KV5Ok={IXQJ9A*r^s5>p*An}#!)ilov>wN8E->&vI7wiCkUZ6t0AvM^zhgbAx`lPqrv1`O@8eU@ROxv2mwE2(3XY^JnRc2;a- zFR5db9Hw-YTvf4+(_CkvD(F((VFuI}hYcP&F?@39<?VZkQa@MmkxvmLgLFwxxBxj)2GkA zI($OwcMRRdlPMs_`*ziJIikcdg`{eyH#KlV8wMNuDlbx-^?8-`^F9!0I+jclOvK;3 ze0=aVjIAVJI~_qZG(UeLl8U@`8dws0ZCsw4e{DWGzc&?8&daI2GZ#}c3(Do0*J9DB z*X9?1ZSmKDY)Bp4mrg}v`xHX)(ENhhq7PmUl+4cJmOT=3-I!W(7ouyz1DF3s&GniM ztEFbl^1$2qS(Uxoz2O%8_3OUAyst0k>f1y`VcNX0#`d2?$^Yl}Te3n}Vko0q2n+7KCpar_{FoY3>*EPJrmZ)G9kRu1}G@)6m=j{ zcj)N#=+;UnDsm)en`3VCsI_GFRzOaDI>r=@r9Va^Y(dknmZRz6yzg+%b(rtuzciZm z5R7^$Vnk%dPCA-@#}z(JE8K#oB`Z8|gzz-<2glP`37$R+Y&?7NWcbCQFMUzATiTV* za?3HWUdKRF^(`ppF%@Q-Ot@vrKSdzkf<$M_k!W|`w>#(B{f9v!VoyqlqAf@?fZRtd z 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 literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/ssl_.cpython-312.pyc b/lib/urllib3/util/__pycache__/ssl_.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c8a83e8d94c2d0b44eb5ec3395f9e2330cbd1a3 GIT binary patch literal 15081 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 W-Gk-!UzYI{R+bI6+ke@{BmDo%6CX_g literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc b/lib/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1802f752f29be8f5a8170c4396266c73defa8cf GIT binary patch literal 5061 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 Sf2ymF1L&6P2=gg*g!wlq@}S}X literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/ssltransport.cpython-312.pyc b/lib/urllib3/util/__pycache__/ssltransport.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e7968502d683b6963f173653dc33a9ada38b9d8 GIT binary patch literal 10762 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 literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/url.cpython-312.pyc b/lib/urllib3/util/__pycache__/url.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d77b05b2f78ad3fd9d2c33e07c133b4c95e0a86 GIT binary patch literal 15761 zcmbt*Yj9Inn&7>9zbx63{04K4ZEP7^HrNm_U}F3L6EMU!32_WU*1ZN9S#s{Z1}vmR z^iUHy$qaTUGl(I(ai*)L&5)U}Rb4gg{@G0LR&`fxZIy)RLENQx>78uVrfPpUz;<=B zRh#|3b9E)z7`k`&fX+RS@4V0X-u@3oMJ5V@R`cQHFJ7alf5waw4B5of|E#8{>l90| zbby+s$7mYUs(@-t1z&YQJ*^qjK$(Ws2DH<3=`kZ~7&ECT zPBm4g43Ph_#@n=<8?(F=#*~98dMS(<`rnZ6S4lx>jgroP!+MIkt&;O&#jItlge@Ag zv(~A`JdBd!>|DuLwj8t*@=mt+bJbWWtgi&tSH{}M%2@~NoZ6f<}@30#e zE!n&iLMSjRavuNmOo$hUpv)BXPIIg{I}_l(!{-7;_9G#mSM-O1$GyD3_49m)hf=lR zzjRA4=>*?7Zkm%c-dXXSq&XK7L`j34LF|PR?R&EvKPMR`dGFb2E-1Rx03?btk``lO zC~RwZ*V{VT(>l=Jy8G1S?a^?}>8AZ%P!{fK9Xpl%LfzKZQ_WqGHdlBA>zmdAa07&^ z%e5b>+uEAmJv~0&w!aRFpyb`tBn36&n8}vz@2YEZV|{&iBaTUCu&t#dI_`E|?uh2| z;bKg~9AT!XE^lk;jE2jg!R2$@rKlW7F8gOLbVgk+m86DJNrPFJinqfSN}7PsvE5}1 zmqVL|Ca87^U9QVJqYX`@LI_uOb*-w}k*{jVSGe}C0qe|zZ3nPCBy2)+7&K>WW)9ykp>qe-VHlWMb_L}*VeFV z{N1p|wSW9nxE6s-rWYTM!u-+a4pGQKJfp$cv!o+wth=vldE}a%btDD zY1oF>pVMv6>HR)L9ZJX|Bm+9EOYp0tuxJCICwhZ?PnK#_=r=LLd z7xZ;1qUFmX+Nmrv1%nR zAwvC`g90WdLPt~)bwm@$Oe&Q^mu#$uON6l0z%{YVu(E- z>FpYa!{deVBXBt5Ju@?S?&C5MeW1C3kkF??Qnv4AJjm)b~!xQk>9yVY^{lR^P8^ z$vDaq&c&{HU&dULG;hq5R$m`q9RKumeBhDI`PoRKE@j)2vDg*>Dj_b7E_dE3y=!=? zRu!98D3#Il6ndq6g{OyUa>7-Rfb*rM5M)h&{iegO55T3K@cPbQ^zy9G>I+Q+vGq^* z1AcLi!QE$ILFCf9nYXz{yqJC;#{~T6Ik>uB(e0wimfxZ!jlcya1ss~;T@XtKyv)c2 zge|xcN^TnJ1U#1*wW6bno!92(=aPmBz8Q*EtpZm-RxtsIm#yLwEdWEp(oq^#nPtlX zJQuFmBQ&d8zYcG67_JGlrC~SJVOLLF9>oKo z&AFQf=~gI`)U&)_z{xP#tuXT(G#5m8`TnpCccY+y2SA|{BC;Vi$2I@F|DLrb(Ggca zHruXs&37fuwRrv=3FjA8H>y&Ox|F3Z-uu{QkDFexZReoNmu(wg4bOSq4O{=ROsY`s z7{RNw&L-p24L1#O;>8euo(W{Ryn_9c(Hh`4Waz@$2BE8gh0P-Gl)Ts$+=GI&N!+P>=*tU{$=OamA5LB8#_{tj-;g{1H1ULYX!Ws ze68+40{3SeWh*+WimIcUs5YvL>ft&W0Ld955VNY>H8Dg~q)f%C3(C}2v;e0j7s(LO zTq%hdSdEx_juDN5LJQhxNgHjpjShQd0T~uR=t&u%$AU5g?6ck*hXWvJ9nn{BD0qS6 zMF!s<>^Go(FTPk)4q)`0Uto~-Am7ah=R&gqmYEL0LxzVR-~@r;L$g7)6|VJ+{NS^c z%3VmRM$gHl2Zxl&8_*>fhne=y0jUz1369||d3|DFPNrz^>X8^Cbwev^8<=v+fq`S;%!qkd>F22zZ0%$u)!3 z1Om)CFVMy=nDlh$0>`@C`JL&%Jh5$`|4SySuxY6U;uq0a;qz)QBPm$O30W zp|b(b4Op^m+6&0O(UluM*U*jIk2xj0wDBq^GAJLAhiYtL8fSqdA@b~+0ip%(ip4^F zM>ssBceS^y>cH)GGmUMCw-AsZD@-WjQlsmo6MJE#*Og(qcD0ip_ml4Ga((3nmZ-2A z_Jv37315v7qQvKP9g*uq-en{R@sFX;fHMQDD6@<@`CZUqSbqZ0008_6WCUa~00(TL z_Uum?UW@A%Gz)B^Z>fG+yL>5QEs3jvtXS+wNC9W=ObjgUPgyp{doyNR(p-&Yor(Iz zJt<4gscBWd0wmo;UFdH zsj<$b_5KeSp1ehP`z%T(pkCqFt}bSqd;1O_ek44|OFyZ}W`V2H>2$?t&ZJG^;-Wi^xjAnVdev>@ro z0SS_R+8^}z*-MfU6Qoe0SxF5=0?J}CVUl@tbHUc}N1*a+_z5wH0K?W(Hb?AWrq~%9 z%oI7EPrRQnNmyX9-(aMMVvwBiF{Dj21P5L=Q|UtHp7J@(7qw2o|b{7^X@U`21Iy zO@zKc@j8&n4TLe(ebN=tO_k^2loYEKE0uI4XM|ymh?~~iEv5e{ieAvw3^FL?!Yc)y5?^Ep zcut=4&ddbnK(aI8>j)7>8qj6{D%d#&XkI}#Y`z0ozcTcK*ouep^mT}c{Iw2|$SYP} zrA9%yN`CX84%VIpP949Up>MIPaE?W{Q2x=Sh& zWHrsMs?z5PR@p5cDb z6wFQpC7nD)N$Ud&BTB}JIT6q#@12vhyf=83lhnZWOKRYJ5wqd>L6b`&7i48+xHdcq z3_gDxM>I*s+@VTE-T-QhvWu1sWE?nJsU&-j^5#H^AQ?d*_u$BaWcLf6RRA0-mB@31 zu9Pby(SAvT4I~4`9+;khiYFPVVk{%p(sfUOp9au-@Ds{m`vAonC__n7Uy-p@fC}W> zV#jscqHW2TE^dwuJ~L7E?w{`ea{og^%d#KTJ@vYjhKUU(Z45Lksd`Y%q>7oP^5wR4 zaTj3d%I0PN*P&aXyKLIso2u+hYRVo})ZR2FHKpGc*%!8b=1aIf4W^44o=`^Z+jN|M zY^z9=B;H&qxp5+CtBY$MIm#BqPj|-+4=puIoy(nny%+HMg7DE$Lj2RE-?+%}IbvY3$RyW>CnoI%S4@$@*)^ z(;d`|P35RgzOPkyQZH*=pVRKJ%I(gx7@*TpwYkIUHn-cQ2lXrRhLR2tB|Je%JrkPY z>!3$ThgxVb)4@AqWreL~D&!BkG(;~Z83c~l>wrH2ObcoNNw1XPvF2Y)rAHRhJt)J1 z03v!6IDQTQpTSSK2~muC4AM<_KAfog_=DJ?Opz@%@YqrPgfeL><9gsj7JMIdBS%u? zOlUsxWGwb;N9T_w8h>Tk{6t4tomg;q{_vk2St*4UD;p?-<--rIe6S$g*H?e}*7Air z-oKs87_8Td=8G1*3HyD+27INK52IJ23#abu>y)~Q`-aNLX6vzEOY$PK&};K~RseU=zYLsMm5_Nkk`BDB~)-h1>#+0}dw< z4R9pua2?9ql~ryqH!b#z?TCu=6)k|@L}dpFuij1J@T<>^)lO|vddh#{&DZ90N-F>6 z!6ihWbqRrY9o38Y21x)*N)~5=dx(v=hvZ6>8eH87nD2=RUk@gHc>8_OI;;kxi^CJO;F%e-nC@Ok>A}`aOev$PDNNp!zKPv4>#?aGy6eP_W+BJVV37rcouD^MZ(Ro21cb;{(gR5c z`}t0JR4uV7Noqu2`Y1C-U%)s;EO?2gh3|YHc!q3=RtiK|K|W=haDESLKK6} z&5z8b3+(5;UmUw}?7q1L$mjL$#qOp0w4*WJ_t;!=ztnZl?0QsI_n^#`DswH@r_0*n z2OrwXo*Aghx(5}mR0S4Rv@K{KIw~@?TYg&gWz}-ePc|+dUg%GBWNJ1q?O1jsLJJ2U zm)ATfccsc*%MJI-+wZ*njrQJ-{>*0Aa_#cwrL8ygkCkLXpQ)+6U%&fqSU zrtSA?j;Eb(0*6vz2ZL0J9rbU;u{VDIL`!XYlO{6fzi+VjYb>kyU>uo zF|srYV|_V;qH=-xCL?%}u~YyIK1S+;^@$rbl@qGq%(6jw^57k$`AVz!z>w$u3h4Eo zIGcM`BUD|1P+3p$n`uhSiI!72G_1^lqQo3QXLF1On-e-|>K*Enz(wkk`W@;bU5D!{ z&bL)kFiyk&#W;Wn(RQQk;F{55%4jabYB2_>Q3w2x^p>gcFaqn3!$X%M@yTh9b zpK^h?q5y2i_lNlYzoQ-Xo}+!q`&n;-{&XPW`-`I~NBi#uoc50@s%XN-gj-JpiJA-S zB1D^yruv-Fhl-{~L>-M_5J5%gD9lfXiZUO_D}u;&cz7rk!gWJv&S-298c{!m<_<4f z_x&t0*f-R}5DX$|y@Jp0M}xFCI0tS!(63}3B<@he(@932Cf@4@2Y^XFG|eL&=f^N2 zn9Yct$xcx!NrS3bJ^_`5TgAr_8l!Ev5q}4X81+zZ{!9&PU+%o`Xun_FzM|3@t^dhV zzGBfDtrHB7MVNcp|IB7Y&VuDwS*2RzaJ}}p$%r%LNX>(&z z)A+k*s*9{EYN-5QD^@h$zCZu|6H2`r zcJP;dsk-Co;y05cZ~s=U!Uh2GT-XdV{!2~I2I^+*0TcC)8=4O2)j!wK7@M{o=vM!H z9}V#;G=T?-gz4$uKy;lFA(q3s+p-W zErF4aXlRjhAUYF5Ux9HxbbOV{Kz0iuCSXSPBw&OPXga+jsyo3LC%b%r%2U2qD6WGw z4Ro@yjaerdM|*}3_M`YL6Ehvr1_&~(G#&35JtR{}$^7Pt{^57z4EV_DKjQZAIeZ6h5ZD~u|?s{NvPubhk_U%{Ri1o!A9u;j~>inuI zUDO#Hcx0(vYWS);ZP^j)&*&{E&>E}@bqVd_)|6pmTnBy)v7;}Fb%+be(e8yq{?Ljv zKrrQzi-NHcM+4HyGs^1-V|fOcII0jj_%Q_~S5M-a3qG`dM%n z63Re8Q>{lIly-SW`T{EMRDAKP;X!0o^QVBJUWe_@Q;Tufv8W+xjG7{btn-5k)PR7P z<*@ELb6(J|Tqo>s)Eu=$3?QEB`C>7rDvTJ!od0$1`Wqq^Rzt*UBddy9g5Y?Sog4OH zxzbvoB(x~hCu(7J5sOcCNp-#oP??R@<5wsbb1ZlMOnwBUWc_k6rz(t?L6ptjjHnrA zy)mNUtHm5+omZqrH3jR@h>Wsdxz?aqg>`FJty?Q1#v&mHrzLQ@Rd717{slN)L?eJA z7L?SwE1)ipYJzZcU>0o(BnW@#^FqQ@yOPR(l@a-p0yt1;tPLMogT)09=t;6Bd}NJV z!C}sD)etSpzb_RPDatDXNG_*BCONZmY7y|S2iTk^1Igu-+a#A$N_=I!okg33JKCa5 zMQl=1ld3GIv{fmYLi^^LP;l~jCL?#&KGi!Q$mDnzleY?NMGW!4?L7)f>a3XPQ z0Nc%gp9`=uPXM;j3t+}!WxoUPT|i5atRN;%7^DXtIS9o&kJ!sFvvb#LokXb|@Oy(| z)>t+Q>`AswAavI6ll=p^08A_A&;fJ>h{pu@0)p!x=e^(uD^n;)W=~vkSeOD36=G96 zbB3Svp;O?QGg*EoI}msn@ZM=Ow4p~u7vYf#R!n?KUb=B6GT3pj-NDc=I+B5jkyyRD zfWzuK1KpDqoym^;5_2AbK_|&S#_IBCe^$zZP4+|xp8vD?^37On@pvY?*lD#x`z&mrP!5@Hd$o?OGSjX#*m@iPxLA*n=b~Y6? z4=!W3fjPi10^%Bc_*#g7%l|QaateQRHaGt?0s9!?v1E~!# z_!(#E!eIQpq+#2adzRn(NjD@27r~=s<*Mcx9Mvdm8jv%(ig_KFcoa5?{{l(~d(B_L zIuj3ri{LOD3WBG?p<^SXp5w=c30H-hdC7VLG!BD91IMz=lp0*BWIi3Gf1-!vmoW7u zfgTv{Id~L}8bm=MnchN|U&6vm)*cZA3Gio<^Mw27{|cMFk4=qe6d@`U{%tIbK?HUa zl(j(g2+e}M2_FD)oRN(9ClMhYTr%@)ob1$El-E&!A%l3pN;LRw;C=MqoiFf*{V9%v zOtgUVE~3hOkbN^GWA149e*l=HXf-U z(R<&_WUTguk@+d`z0qve_R)_zcK^fPf3^1;b-JVPLB|`ZjyKXBM^lD&aMm#RUd8d{Enm0XYPs#czxQ~u`FOnOH|CN857^(BotfI^2ems=wL9+k(zRXa zx6`*!yYLQ(Hb35*=#2M0s@(FRvL#j7viwfE^0fz*-Kom%bmi;whXJnsq0Mol=uvsg z^61aH)8z*iG~gPuz<(6Zlvgim9&c((SvDY8LIbXr;2xydK>Fb7C7k!2Tb4@iIk!A2 zYg%@s%UYAgtt)D(w6P%nt*r)pa^FhZTH>1Dm@96KK61cVX~%Y$m!oOf`BgaW0MFis zP<7&w6BIZx^X6|M5nK$$&CfKncKb8Xy4W7tsuDZXw#^TVDiY3g zQH}BiXBs8>&{~;jNL!hQB^wea(DIm;}9V*R$L!p1n{D;=$SgrMk6c6h-`ERN+oSl=^ZWF~mEcdBFuAD5C&2M^+}% zJgQp2YJoRjc35*`%7UdT`DM~Gh0?fW0FQ84H~4P==8y7Al-a{#TdE3`JZ|zK)wl;R<(6Qt_N*_Jslg zj`(j1JnjT2T`&2#8AM_NK~CV81s>eqvz#C+8NjF+@OT0L2r|~wBh%s!aQsPV%`amY z`V&Kgy~p}M{n~eIwCBhX{uY)Rh;kK#NlAaG|D*>KI%I*oVBI+~(y^VCXgy%Q6(qCg zf|vJ`Kj#tvZ|0S?(26K$NpCwz6SJc4#U8B%3SrD!hWihChI)?nBPjnbaf%<3DH1rq z>OaC<`GMh{-u@%~BO{)I_E7sLSZgi7<=6{~VDN`!oXGzvrfef84tVFgk(}k^&jm6ReN=7XBv~k*k4c4M&C)j~L(E35^5eyR1a&=I=ud-gDs{ zK%MYbX!_UGmVc&`KRE{|ZnXLj4_`UFV833uSeepPJuT9kR52ZR z+E`j*hKy-LOrJ5=Juo+?%+1Re@19JWo73h2s3|UAsz@1{W7;PwhfNhTuQXHklXT1q zcxR#G`mV)Ycg+8^Vej%bunL#neCOVVy=lk3lzHDb>Xf+`np-z6SyNVba@#=4IuJ8w zO3D%ysgl~IfmBKJ^1G>$U3Xtgl^lTXY#lL6!7BEoEqi0e$0lcd^R?#r=7o{OuEoY3wU{ja?P9 z!j6_yXGiK@-u`vht**POe{1~L#?;oHbn$^$(Qh1O8OP<|gikjdkH@TKamitqiwk4@;F>^flOb34oT>*P= zA~BdYZFvTN=tNgM39A^o^XUM+iFQBfqpRr+Pxfx0i=TAc=%y$2dfNWPd77qmPYvKd-YKY&QKL67P&d literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/__pycache__/wait.cpython-312.pyc b/lib/urllib3/util/__pycache__/wait.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60658f1d57c6609c69fe77ffb39478bdaddfc03b GIT binary patch literal 4393 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 bH}2fCX*Gipx8%My@_AdJuSfj6n}Yl=s*ktf literal 0 HcmV?d00001 diff --git a/lib/urllib3/util/connection.py b/lib/urllib3/util/connection.py new file mode 100644 index 0000000..6af1138 --- /dev/null +++ b/lib/urllib3/util/connection.py @@ -0,0 +1,149 @@ +from __future__ import absolute_import + +import socket + +from ..contrib import _appengine_environ +from ..exceptions import LocationParseError +from ..packages import six +from .wait import NoWayToWaitForSocketError, wait_for_read + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`http.client.HTTPConnection` object. + + Note: For platforms like AppEngine, this will always return ``False`` to + let the platform handle connection recycling transparently for us. + """ + sock = getattr(conn, "sock", False) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + try: + # Returns True if readable, which here means it's been dropped + return wait_for_read(sock, timeout=0.0) + except NoWayToWaitForSocketError: # Platform-specific: AppEngine + return False + + +# This function is copied from socket.py in the Python 2.7 standard +# library test suite. Added to its signature is only `socket_options`. +# One additional modification is that we avoid binding to IPv6 servers +# discovered in DNS if the system doesn't have IPv6 functionality. +def create_connection( + address, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, + socket_options=None, +): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`socket.getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + if host.startswith("["): + host = host.strip("[]") + err = None + + # Using the value from allowed_gai_family() in the context of getaddrinfo lets + # us select whether to work with IPv4 DNS records, IPv6 records, or both. + # The original create_connection function always returns all records. + family = allowed_gai_family() + + try: + host.encode("idna") + except UnicodeError: + return six.raise_from( + LocationParseError(u"'%s', label empty or too long" % host), None + ) + + for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as e: + err = e + if sock is not None: + sock.close() + sock = None + + if err is not None: + raise err + + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) + + +def allowed_gai_family(): + """This function is designed to work in the context of + getaddrinfo, where family=socket.AF_UNSPEC is the default and + will perform a DNS search for both IPv6 and IPv4 records.""" + + family = socket.AF_INET + if HAS_IPV6: + family = socket.AF_UNSPEC + return family + + +def _has_ipv6(host): + """Returns True if the system can bind an IPv6 address.""" + sock = None + has_ipv6 = False + + # App Engine doesn't support IPV6 sockets and actually has a quota on the + # number of sockets that can be used, so just early out here instead of + # creating a socket needlessly. + # See https://github.com/urllib3/urllib3/issues/1446 + if _appengine_environ.is_appengine_sandbox(): + return False + + if socket.has_ipv6: + # has_ipv6 returns true if cPython was compiled with IPv6 support. + # It does not tell us if the system has IPv6 support enabled. To + # determine that we must bind to an IPv6 address. + # https://github.com/urllib3/urllib3/pull/611 + # https://bugs.python.org/issue658327 + try: + sock = socket.socket(socket.AF_INET6) + sock.bind((host, 0)) + has_ipv6 = True + except Exception: + pass + + if sock: + sock.close() + return has_ipv6 + + +HAS_IPV6 = _has_ipv6("::1") diff --git a/lib/urllib3/util/proxy.py b/lib/urllib3/util/proxy.py new file mode 100644 index 0000000..2199cc7 --- /dev/null +++ b/lib/urllib3/util/proxy.py @@ -0,0 +1,57 @@ +from .ssl_ import create_urllib3_context, resolve_cert_reqs, resolve_ssl_version + + +def connection_requires_http_tunnel( + proxy_url=None, proxy_config=None, destination_scheme=None +): + """ + Returns True if the connection requires an HTTP CONNECT through the proxy. + + :param URL proxy_url: + URL of the proxy. + :param ProxyConfig proxy_config: + Proxy configuration from poolmanager.py + :param str destination_scheme: + The scheme of the destination. (i.e https, http, etc) + """ + # If we're not using a proxy, no way to use a tunnel. + if proxy_url is None: + return False + + # HTTP destinations never require tunneling, we always forward. + if destination_scheme == "http": + return False + + # Support for forwarding with HTTPS proxies and HTTPS destinations. + if ( + proxy_url.scheme == "https" + and proxy_config + and proxy_config.use_forwarding_for_https + ): + return False + + # Otherwise always use a tunnel. + return True + + +def create_proxy_ssl_context( + ssl_version, cert_reqs, ca_certs=None, ca_cert_dir=None, ca_cert_data=None +): + """ + Generates a default proxy ssl context if one hasn't been provided by the + user. + """ + ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(ssl_version), + cert_reqs=resolve_cert_reqs(cert_reqs), + ) + + if ( + not ca_certs + and not ca_cert_dir + and not ca_cert_data + and hasattr(ssl_context, "load_default_certs") + ): + ssl_context.load_default_certs() + + return ssl_context diff --git a/lib/urllib3/util/queue.py b/lib/urllib3/util/queue.py new file mode 100644 index 0000000..4178410 --- /dev/null +++ b/lib/urllib3/util/queue.py @@ -0,0 +1,22 @@ +import collections + +from ..packages import six +from ..packages.six.moves import queue + +if six.PY2: + # Queue is imported for side effects on MS Windows. See issue #229. + import Queue as _unused_module_Queue # noqa: F401 + + +class LifoQueue(queue.Queue): + def _init(self, _): + self.queue = collections.deque() + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item): + self.queue.append(item) + + def _get(self): + return self.queue.pop() diff --git a/lib/urllib3/util/request.py b/lib/urllib3/util/request.py new file mode 100644 index 0000000..b574b08 --- /dev/null +++ b/lib/urllib3/util/request.py @@ -0,0 +1,146 @@ +from __future__ import absolute_import + +from base64 import b64encode + +from ..exceptions import UnrewindableBodyError +from ..packages.six import b, integer_types + +# Pass as a value within ``headers`` to skip +# emitting some HTTP headers that are added automatically. +# The only headers that are supported are ``Accept-Encoding``, +# ``Host``, and ``User-Agent``. +SKIP_HEADER = "@@@SKIP_HEADER@@@" +SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"]) + +ACCEPT_ENCODING = "gzip,deflate" +try: + try: + import brotlicffi as _unused_module_brotli # noqa: F401 + except ImportError: + import brotli as _unused_module_brotli # noqa: F401 +except ImportError: + pass +else: + ACCEPT_ENCODING += ",br" + +_FAILEDTELL = object() + + +def make_headers( + keep_alive=None, + accept_encoding=None, + user_agent=None, + basic_auth=None, + proxy_basic_auth=None, + disable_cache=None, +): + """ + Shortcuts for generating request headers. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ",".join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers["accept-encoding"] = accept_encoding + + if user_agent: + headers["user-agent"] = user_agent + + if keep_alive: + headers["connection"] = "keep-alive" + + if basic_auth: + headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8") + + if proxy_basic_auth: + headers["proxy-authorization"] = "Basic " + b64encode( + b(proxy_basic_auth) + ).decode("utf-8") + + if disable_cache: + headers["cache-control"] = "no-cache" + + return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, "tell", None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + body_seek = getattr(body, "seek", None) + if body_seek is not None and isinstance(body_pos, integer_types): + try: + body_seek(body_pos) + except (IOError, OSError): + raise UnrewindableBodyError( + "An error occurred when rewinding request body for redirect/retry." + ) + elif body_pos is _FAILEDTELL: + raise UnrewindableBodyError( + "Unable to record file position for rewinding " + "request body during a redirect/retry." + ) + else: + raise ValueError( + "body_pos must be of type integer, instead it was %s." % type(body_pos) + ) diff --git a/lib/urllib3/util/response.py b/lib/urllib3/util/response.py new file mode 100644 index 0000000..5ea609c --- /dev/null +++ b/lib/urllib3/util/response.py @@ -0,0 +1,107 @@ +from __future__ import absolute_import + +from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect + +from ..exceptions import HeaderParsingError +from ..packages.six.moves import http_client as httplib + + +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check `isclosed()` first, in case Python3 doesn't set `closed`. + # GH Issue #928 + return obj.isclosed() + except AttributeError: + pass + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") + + +def assert_header_parsing(headers): + """ + Asserts whether all headers have been successfully parsed. + Extracts encountered errors from the result of parsing headers. + + Only works on Python 3. + + :param http.client.HTTPMessage headers: Headers to verify. + + :raises urllib3.exceptions.HeaderParsingError: + If parsing errors are found. + """ + + # This will fail silently if we pass in the wrong kind of parameter. + # To make debugging easier add an explicit check. + if not isinstance(headers, httplib.HTTPMessage): + raise TypeError("expected httplib.Message, got {0}.".format(type(headers))) + + defects = getattr(headers, "defects", None) + get_payload = getattr(headers, "get_payload", None) + + unparsed_data = None + if get_payload: + # get_payload is actually email.message.Message.get_payload; + # we're only interested in the result if it's not a multipart message + if not headers.is_multipart(): + payload = get_payload() + + if isinstance(payload, (bytes, str)): + unparsed_data = payload + if defects: + # httplib is assuming a response body is available + # when parsing headers even when httplib only sends + # header data to parse_headers() This results in + # defects on multipart responses in particular. + # See: https://github.com/urllib3/urllib3/issues/800 + + # So we ignore the following defects: + # - StartBoundaryNotFoundDefect: + # The claimed start boundary was never found. + # - MultipartInvariantViolationDefect: + # A message claimed to be a multipart but no subparts were found. + defects = [ + defect + for defect in defects + if not isinstance( + defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect) + ) + ] + + if defects or unparsed_data: + raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) + + +def is_response_to_head(response): + """ + Checks whether the request of a response has been a HEAD-request. + Handles the quirks of AppEngine. + + :param http.client.HTTPResponse response: + Response to check if the originating request + used 'HEAD' as a method. + """ + # FIXME: Can we do this somehow without accessing private httplib _method? + method = response._method + if isinstance(method, int): # Platform-specific: Appengine + return method == 3 + return method.upper() == "HEAD" diff --git a/lib/urllib3/util/retry.py b/lib/urllib3/util/retry.py new file mode 100644 index 0000000..9a1e90d --- /dev/null +++ b/lib/urllib3/util/retry.py @@ -0,0 +1,622 @@ +from __future__ import absolute_import + +import email +import logging +import re +import time +import warnings +from collections import namedtuple +from itertools import takewhile + +from ..exceptions import ( + ConnectTimeoutError, + InvalidHeader, + MaxRetryError, + ProtocolError, + ProxyError, + ReadTimeoutError, + ResponseError, +) +from ..packages import six + +log = logging.getLogger(__name__) + + +# Data structure for representing the metadata of requests that result in a retry. +RequestHistory = namedtuple( + "RequestHistory", ["method", "url", "error", "status", "redirect_location"] +) + + +# TODO: In v2 we can remove this sentinel and metaclass with deprecated options. +_Default = object() + + +class _RetryMeta(type): + @property + def DEFAULT_METHOD_WHITELIST(cls): + warnings.warn( + "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and " + "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead", + DeprecationWarning, + ) + return cls.DEFAULT_ALLOWED_METHODS + + @DEFAULT_METHOD_WHITELIST.setter + def DEFAULT_METHOD_WHITELIST(cls, value): + warnings.warn( + "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and " + "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead", + DeprecationWarning, + ) + cls.DEFAULT_ALLOWED_METHODS = value + + @property + def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls): + warnings.warn( + "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and " + "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead", + DeprecationWarning, + ) + return cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT + + @DEFAULT_REDIRECT_HEADERS_BLACKLIST.setter + def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls, value): + warnings.warn( + "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and " + "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead", + DeprecationWarning, + ) + cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT = value + + @property + def BACKOFF_MAX(cls): + warnings.warn( + "Using 'Retry.BACKOFF_MAX' is deprecated and " + "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead", + DeprecationWarning, + ) + return cls.DEFAULT_BACKOFF_MAX + + @BACKOFF_MAX.setter + def BACKOFF_MAX(cls, value): + warnings.warn( + "Using 'Retry.BACKOFF_MAX' is deprecated and " + "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead", + DeprecationWarning, + ) + cls.DEFAULT_BACKOFF_MAX = value + + +@six.add_metaclass(_RetryMeta) +class Retry(object): + """Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int status: + How many times to retry on bad status codes. + + These are retries made on responses, where status code matches + ``status_forcelist``. + + Set to ``0`` to fail on the first retry of this type. + + :param int other: + How many times to retry on other errors. + + Other errors are errors that are not connect, read, redirect or status errors. + These errors might be raised after the request was sent to the server, so the + request might have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + If ``total`` is not set, it's a good idea to set this to 0 to account + for unexpected edge cases and avoid infinite retry loops. + + :param iterable allowed_methods: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + idempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`. + + Set to a ``False`` value to retry on any verb. + + .. warning:: + + Previously this parameter was named ``method_whitelist``, that + usage is deprecated in v1.26.0 and will be removed in v2.0. + + :param iterable status_forcelist: + A set of integer HTTP status codes that we should force a retry on. + A retry is initiated if the request method is in ``allowed_methods`` + and the response status code is in ``status_forcelist``. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts after the second try + (most errors are resolved immediately by a second try without a + delay). urllib3 will sleep for:: + + {backoff factor} * (2 ** ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.DEFAULT_BACKOFF_MAX`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + + :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: + whether we should raise an exception, or return a response, + if status falls in ``status_forcelist`` range and retries have + been exhausted. + + :param tuple history: The history of the request encountered during + each call to :meth:`~Retry.increment`. The list is in the order + the requests occurred. Each list item is of class :class:`RequestHistory`. + + :param bool respect_retry_after_header: + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + + :param iterable remove_headers_on_redirect: + Sequence of headers to remove from the request when a response + indicating a redirect is returned before firing off the redirected + request. + """ + + #: Default methods to be used for ``allowed_methods`` + DEFAULT_ALLOWED_METHODS = frozenset( + ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"] + ) + + #: Default status codes to be used for ``status_forcelist`` + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + #: Default headers to be used for ``remove_headers_on_redirect`` + DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( + ["Cookie", "Authorization", "Proxy-Authorization"] + ) + + #: Maximum backoff time. + DEFAULT_BACKOFF_MAX = 120 + + def __init__( + self, + total=10, + connect=None, + read=None, + redirect=None, + status=None, + other=None, + allowed_methods=_Default, + status_forcelist=None, + backoff_factor=0, + raise_on_redirect=True, + raise_on_status=True, + history=None, + respect_retry_after_header=True, + remove_headers_on_redirect=_Default, + # TODO: Deprecated, remove in v2.0 + method_whitelist=_Default, + ): + + if method_whitelist is not _Default: + if allowed_methods is not _Default: + raise ValueError( + "Using both 'allowed_methods' and " + "'method_whitelist' together is not allowed. " + "Instead only use 'allowed_methods'" + ) + warnings.warn( + "Using 'method_whitelist' with Retry is deprecated and " + "will be removed in v2.0. Use 'allowed_methods' instead", + DeprecationWarning, + stacklevel=2, + ) + allowed_methods = method_whitelist + if allowed_methods is _Default: + allowed_methods = self.DEFAULT_ALLOWED_METHODS + if remove_headers_on_redirect is _Default: + remove_headers_on_redirect = self.DEFAULT_REMOVE_HEADERS_ON_REDIRECT + + self.total = total + self.connect = connect + self.read = read + self.status = status + self.other = other + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.allowed_methods = allowed_methods + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header + self.remove_headers_on_redirect = frozenset( + [h.lower() for h in remove_headers_on_redirect] + ) + + def new(self, **kw): + params = dict( + total=self.total, + connect=self.connect, + read=self.read, + redirect=self.redirect, + status=self.status, + other=self.other, + status_forcelist=self.status_forcelist, + backoff_factor=self.backoff_factor, + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, + remove_headers_on_redirect=self.remove_headers_on_redirect, + respect_retry_after_header=self.respect_retry_after_header, + ) + + # TODO: If already given in **kw we use what's given to us + # If not given we need to figure out what to pass. We decide + # based on whether our class has the 'method_whitelist' property + # and if so we pass the deprecated 'method_whitelist' otherwise + # we use 'allowed_methods'. Remove in v2.0 + if "method_whitelist" not in kw and "allowed_methods" not in kw: + if "method_whitelist" in self.__dict__: + warnings.warn( + "Using 'method_whitelist' with Retry is deprecated and " + "will be removed in v2.0. Use 'allowed_methods' instead", + DeprecationWarning, + ) + params["method_whitelist"] = self.allowed_methods + else: + params["allowed_methods"] = self.allowed_methods + + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r", retries, new_retries) + return new_retries + + def get_backoff_time(self): + """Formula for computing the current backoff + + :rtype: float + """ + # We want to consider only the last consecutive errors sequence (Ignore redirects). + consecutive_errors_len = len( + list( + takewhile(lambda x: x.redirect_location is None, reversed(self.history)) + ) + ) + if consecutive_errors_len <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) + return min(self.DEFAULT_BACKOFF_MAX, backoff_value) + + def parse_retry_after(self, retry_after): + # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 + if re.match(r"^\s*[0-9]+\s*$", retry_after): + seconds = int(retry_after) + else: + retry_date_tuple = email.utils.parsedate_tz(retry_after) + if retry_date_tuple is None: + raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) + if retry_date_tuple[9] is None: # Python 2 + # Assume UTC if no timezone was specified + # On Python2.7, parsedate_tz returns None for a timezone offset + # instead of 0 if no timezone is given, where mktime_tz treats + # a None timezone offset as local time. + retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:] + + retry_date = email.utils.mktime_tz(retry_date_tuple) + seconds = retry_date - time.time() + + if seconds < 0: + seconds = 0 + + return seconds + + def get_retry_after(self, response): + """Get the value of Retry-After in seconds.""" + + retry_after = response.headers.get("Retry-After") + + if retry_after is None: + return None + + return self.parse_retry_after(retry_after) + + def sleep_for_retry(self, response=None): + retry_after = self.get_retry_after(response) + if retry_after: + time.sleep(retry_after) + return True + + return False + + def _sleep_backoff(self): + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def sleep(self, response=None): + """Sleep between retry attempts. + + This method will respect a server's ``Retry-After`` response header + and sleep the duration of the time requested. If that is not present, it + will use an exponential backoff. By default, the backoff factor is 0 and + this method will return immediately. + """ + + if self.respect_retry_after_header and response: + slept = self.sleep_for_retry(response) + if slept: + return + + self._sleep_backoff() + + def _is_connection_error(self, err): + """Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + if isinstance(err, ProxyError): + err = err.original_error + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def _is_method_retryable(self, method): + """Checks if a given HTTP method should be retried upon, depending if + it is included in the allowed_methods + """ + # TODO: For now favor if the Retry implementation sets its own method_whitelist + # property outside of our constructor to avoid breaking custom implementations. + if "method_whitelist" in self.__dict__: + warnings.warn( + "Using 'method_whitelist' with Retry is deprecated and " + "will be removed in v2.0. Use 'allowed_methods' instead", + DeprecationWarning, + ) + allowed_methods = self.method_whitelist + else: + allowed_methods = self.allowed_methods + + if allowed_methods and method.upper() not in allowed_methods: + return False + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """Is this method/status code retryable? (Based on allowlists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + + if self.status_forcelist and status_code in self.status_forcelist: + return True + + return ( + self.total + and self.respect_retry_after_header + and has_retry_after + and (status_code in self.RETRY_AFTER_STATUS_CODES) + ) + + def is_exhausted(self): + """Are we out of retries?""" + retry_counts = ( + self.total, + self.connect, + self.read, + self.redirect, + self.status, + self.other, + ) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + def increment( + self, + method=None, + url=None, + response=None, + error=None, + _pool=None, + _stacktrace=None, + ): + """Return a new Retry object with incremented retry counters. + + :param response: A response object, or None, if the server did not + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + connect = self.connect + read = self.read + redirect = self.redirect + status_count = self.status + other = self.other + cause = "unknown" + status = None + redirect_location = None + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False or not self._is_method_retryable(method): + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + + elif error: + # Other retry? + if other is not None: + other -= 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = "too many redirects" + redirect_location = response.get_redirect_location() + status = response.status + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and the given method is in the allowed_methods + cause = ResponseError.GENERIC_ERROR + if response and response.status: + if status_count is not None: + status_count -= 1 + cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) + status = response.status + + history = self.history + ( + RequestHistory(method, url, error, status, redirect_location), + ) + + new_retry = self.new( + total=total, + connect=connect, + read=read, + redirect=redirect, + status=status_count, + other=other, + history=history, + ) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) + + return new_retry + + def __repr__(self): + return ( + "{cls.__name__}(total={self.total}, connect={self.connect}, " + "read={self.read}, redirect={self.redirect}, status={self.status})" + ).format(cls=type(self), self=self) + + def __getattr__(self, item): + if item == "method_whitelist": + # TODO: Remove this deprecated alias in v2.0 + warnings.warn( + "Using 'method_whitelist' with Retry is deprecated and " + "will be removed in v2.0. Use 'allowed_methods' instead", + DeprecationWarning, + ) + return self.allowed_methods + try: + return getattr(super(Retry, self), item) + except AttributeError: + return getattr(Retry, item) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/lib/urllib3/util/ssl_.py b/lib/urllib3/util/ssl_.py new file mode 100644 index 0000000..8f86781 --- /dev/null +++ b/lib/urllib3/util/ssl_.py @@ -0,0 +1,495 @@ +from __future__ import absolute_import + +import hmac +import os +import sys +import warnings +from binascii import hexlify, unhexlify +from hashlib import md5, sha1, sha256 + +from ..exceptions import ( + InsecurePlatformWarning, + ProxySchemeUnsupported, + SNIMissingWarning, + SSLError, +) +from ..packages import six +from .url import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE + +SSLContext = None +SSLTransport = None +HAS_SNI = False +IS_PYOPENSSL = False +IS_SECURETRANSPORT = False +ALPN_PROTOCOLS = ["http/1.1"] + +# Maps the length of a digest to a possible hash function producing this digest +HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256} + + +def _const_compare_digest_backport(a, b): + """ + Compare two digests of equal length in constant time. + + The digests must be of type str/bytes. + Returns True if the digests match, and False otherwise. + """ + result = abs(len(a) - len(b)) + for left, right in zip(bytearray(a), bytearray(b)): + result |= left ^ right + return result == 0 + + +_const_compare_digest = getattr(hmac, "compare_digest", _const_compare_digest_backport) + +try: # Test for SSL features + import ssl + from ssl import CERT_REQUIRED, wrap_socket +except ImportError: + pass + +try: + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + +try: + from .ssltransport import SSLTransport +except ImportError: + pass + + +try: # Platform-specific: Python 3.6 + from ssl import PROTOCOL_TLS + + PROTOCOL_SSLv23 = PROTOCOL_TLS +except ImportError: + try: + from ssl import PROTOCOL_SSLv23 as PROTOCOL_TLS + + PROTOCOL_SSLv23 = PROTOCOL_TLS + except ImportError: + PROTOCOL_SSLv23 = PROTOCOL_TLS = 2 + +try: + from ssl import PROTOCOL_TLS_CLIENT +except ImportError: + PROTOCOL_TLS_CLIENT = PROTOCOL_TLS + + +try: + from ssl import OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3 +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + + +try: # OP_NO_TICKET was added in Python 3.6 + from ssl import OP_NO_TICKET +except ImportError: + OP_NO_TICKET = 0x4000 + + +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and +# security, +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, +# - disable NULL authentication, MD5 MACs, DSS, and other +# insecure ciphers for security reasons. +# - NOTE: TLS 1.3 cipher suites are managed through a different interface +# not exposed by CPython (yet!) and are enabled by default if they're available. +DEFAULT_CIPHERS = ":".join( + [ + "ECDHE+AESGCM", + "ECDHE+CHACHA20", + "DHE+AESGCM", + "DHE+CHACHA20", + "ECDH+AESGCM", + "DH+AESGCM", + "ECDH+AES", + "DH+AES", + "RSA+AESGCM", + "RSA+AES", + "!aNULL", + "!eNULL", + "!MD5", + "!DSS", + ] +) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + + class SSLContext(object): # Platform-specific: Python 2 + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + self.ca_certs = cafile + + if capath is not None: + raise SSLError("CA directories not supported in older Pythons") + + if cadata is not None: + raise SSLError("CA data not supported in older Pythons") + + def set_ciphers(self, cipher_suite): + self.ciphers = cipher_suite + + def wrap_socket(self, socket, server_hostname=None, server_side=False): + warnings.warn( + "A true SSLContext object is not available. This prevents " + "urllib3 from configuring SSL appropriately and may cause " + "certain SSL connections to fail. You can upgrade to a newer " + "version of Python to solve this. For more information, see " + "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" + "#ssl-warnings", + InsecurePlatformWarning, + ) + kwargs = { + "keyfile": self.keyfile, + "certfile": self.certfile, + "ca_certs": self.ca_certs, + "cert_reqs": self.verify_mode, + "ssl_version": self.protocol, + "server_side": server_side, + } + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + fingerprint = fingerprint.replace(":", "").lower() + digest_length = len(fingerprint) + hashfunc = HASHFUNC_MAP.get(digest_length) + if not hashfunc: + raise SSLError("Fingerprint of invalid length: {0}".format(fingerprint)) + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + cert_digest = hashfunc(cert).digest() + + if not _const_compare_digest(cert_digest, fingerprint_bytes): + raise SSLError( + 'Fingerprints did not match. Expected "{0}", got "{1}".'.format( + fingerprint, hexlify(cert_digest) + ) + ) + + +def resolve_cert_reqs(candidate): + """ + Resolves the argument to a numeric constant, which can be passed to + the wrap_socket function/method from the ssl module. + Defaults to :data:`ssl.CERT_REQUIRED`. + If given a string it is assumed to be the name of the constant in the + :mod:`ssl` module or its abbreviation. + (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_REQUIRED + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, "CERT_" + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_TLS + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, "PROTOCOL_" + candidate) + return res + + return candidate + + +def create_urllib3_context( + ssl_version=None, cert_reqs=None, options=None, ciphers=None +): + """All arguments have the same meaning as ``ssl_wrap_socket``. + + By default, this function does a lot of the same work that + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + # PROTOCOL_TLS is deprecated in Python 3.10 + if not ssl_version or ssl_version == PROTOCOL_TLS: + ssl_version = PROTOCOL_TLS_CLIENT + + context = SSLContext(ssl_version) + + context.set_ciphers(ciphers or DEFAULT_CIPHERS) + + # Setting the default here, as we may have no ssl module on import + cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + # TLSv1.2 only. Unless set explicitly, do not request tickets. + # This may save some bandwidth on wire, and although the ticket is encrypted, + # there is a risk associated with it being on wire, + # if the server is not rotating its ticketing keys properly. + options |= OP_NO_TICKET + + context.options |= options + + # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is + # necessary for conditional client cert authentication with TLS 1.3. + # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older + # versions of Python. We only enable on Python 3.7.4+ or if certificate + # verification is enabled to work around Python issue #37428 + # See: https://bugs.python.org/issue37428 + if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr( + context, "post_handshake_auth", None + ) is not None: + context.post_handshake_auth = True + + def disable_check_hostname(): + if ( + getattr(context, "check_hostname", None) is not None + ): # Platform-specific: Python 3.2 + # We do our own verification, including fingerprints and alternative + # hostnames. So disable it here + context.check_hostname = False + + # The order of the below lines setting verify_mode and check_hostname + # matter due to safe-guards SSLContext has to prevent an SSLContext with + # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more + # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used + # or not so we don't know the initial state of the freshly created SSLContext. + if cert_reqs == ssl.CERT_REQUIRED: + context.verify_mode = cert_reqs + disable_check_hostname() + else: + disable_check_hostname() + context.verify_mode = cert_reqs + + # Enable logging of TLS session keys via defacto standard environment variable + # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values. + if hasattr(context, "keylog_filename"): + sslkeylogfile = os.environ.get("SSLKEYLOGFILE") + if sslkeylogfile: + context.keylog_filename = sslkeylogfile + + return context + + +def ssl_wrap_socket( + sock, + keyfile=None, + certfile=None, + cert_reqs=None, + ca_certs=None, + server_hostname=None, + ssl_version=None, + ciphers=None, + ssl_context=None, + ca_cert_dir=None, + key_password=None, + ca_cert_data=None, + tls_in_tls=False, +): + """ + All arguments except for server_hostname, ssl_context, and ca_cert_dir have + the same meaning as they do when using :func:`ssl.wrap_socket`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. + :param ca_cert_dir: + A directory containing CA certificates in multiple separate files, as + supported by OpenSSL's -CApath flag or the capath argument to + SSLContext.load_verify_locations(). + :param key_password: + Optional password if the keyfile is encrypted. + :param ca_cert_data: + Optional string containing CA certificates in PEM format suitable for + passing as the cadata parameter to SSLContext.load_verify_locations() + :param tls_in_tls: + Use SSLTransport to wrap the existing socket. + """ + context = ssl_context + if context is None: + # Note: This branch of code and all the variables in it are no longer + # used by urllib3 itself. We should consider deprecating and removing + # this code. + context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers) + + if ca_certs or ca_cert_dir or ca_cert_data: + try: + context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data) + except (IOError, OSError) as e: + raise SSLError(e) + + elif ssl_context is None and hasattr(context, "load_default_certs"): + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + + # Attempt to detect if we get the goofy behavior of the + # keyfile being encrypted and OpenSSL asking for the + # passphrase via the terminal and instead error out. + if keyfile and key_password is None and _is_key_file_encrypted(keyfile): + raise SSLError("Client private key is encrypted, password is required") + + if certfile: + if key_password is None: + context.load_cert_chain(certfile, keyfile) + else: + context.load_cert_chain(certfile, keyfile, key_password) + + try: + if hasattr(context, "set_alpn_protocols"): + context.set_alpn_protocols(ALPN_PROTOCOLS) + except NotImplementedError: # Defensive: in CI, we always have set_alpn_protocols + pass + + # If we detect server_hostname is an IP address then the SNI + # extension should not be used according to RFC3546 Section 3.1 + use_sni_hostname = server_hostname and not is_ipaddress(server_hostname) + # SecureTransport uses server_hostname in certificate verification. + send_sni = (use_sni_hostname and HAS_SNI) or ( + IS_SECURETRANSPORT and server_hostname + ) + # Do not warn the user if server_hostname is an invalid SNI hostname. + if not HAS_SNI and use_sni_hostname: + warnings.warn( + "An HTTPS request has been made, but the SNI (Server Name " + "Indication) extension to TLS is not available on this platform. " + "This may cause the server to present an incorrect TLS " + "certificate, which can cause validation failures. You can upgrade to " + "a newer version of Python to solve this. For more information, see " + "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html" + "#ssl-warnings", + SNIMissingWarning, + ) + + if send_sni: + ssl_sock = _ssl_wrap_socket_impl( + sock, context, tls_in_tls, server_hostname=server_hostname + ) + else: + ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls) + return ssl_sock + + +def is_ipaddress(hostname): + """Detects whether the hostname given is an IPv4 or IPv6 address. + Also detects IPv6 addresses with Zone IDs. + + :param str hostname: Hostname to examine. + :return: True if the hostname is an IP address, False otherwise. + """ + if not six.PY2 and isinstance(hostname, bytes): + # IDN A-label bytes are ASCII compatible. + hostname = hostname.decode("ascii") + return bool(IPV4_RE.match(hostname) or BRACELESS_IPV6_ADDRZ_RE.match(hostname)) + + +def _is_key_file_encrypted(key_file): + """Detects if a key file is encrypted or not.""" + with open(key_file, "r") as f: + for line in f: + # Look for Proc-Type: 4,ENCRYPTED + if "ENCRYPTED" in line: + return True + + return False + + +def _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname=None): + if tls_in_tls: + if not SSLTransport: + # Import error, ssl is not available. + raise ProxySchemeUnsupported( + "TLS in TLS requires support for the 'ssl' module" + ) + + SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context) + return SSLTransport(sock, ssl_context, server_hostname) + + if server_hostname: + return ssl_context.wrap_socket(sock, server_hostname=server_hostname) + else: + return ssl_context.wrap_socket(sock) diff --git a/lib/urllib3/util/ssl_match_hostname.py b/lib/urllib3/util/ssl_match_hostname.py new file mode 100644 index 0000000..1dd950c --- /dev/null +++ b/lib/urllib3/util/ssl_match_hostname.py @@ -0,0 +1,159 @@ +"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" + +# Note: This file is under the PSF license as the code comes from the python +# stdlib. http://docs.python.org/3/license.html + +import re +import sys + +# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +# system, use it to handle IPAddress ServerAltnames (this was added in +# python-3.5) otherwise only do DNS matching. This allows +# util.ssl_match_hostname to continue to be used in Python 2.7. +try: + import ipaddress +except ImportError: + ipaddress = None + +__version__ = "3.5.0.1" + + +class CertificateError(ValueError): + pass + + +def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r".") + leftmost = parts[0] + remainder = parts[1:] + + wildcards = leftmost.count("*") + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn) + ) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == "*": + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append("[^.]+") + elif leftmost.startswith("xn--") or hostname.startswith("xn--"): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r"\*", "[^.]*")) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE) + return pat.match(hostname) + + +def _to_unicode(obj): + if isinstance(obj, str) and sys.version_info < (3,): + # ignored flake8 # F821 to support python 2.7 function + obj = unicode(obj, encoding="ascii", errors="strict") # noqa: F821 + return obj + + +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + # Divergence from upstream: ipaddress can't handle byte str + ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) + return ip == host_ip + + +def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError( + "empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED" + ) + try: + # Divergence from upstream: ipaddress can't handle byte str + host_ip = ipaddress.ip_address(_to_unicode(hostname)) + except (UnicodeError, ValueError): + # ValueError: Not an IP address (common case) + # UnicodeError: Divergence from upstream: Have to deal with ipaddress not taking + # byte strings. addresses should be all ascii, so we consider it not + # an ipaddress in this case + host_ip = None + except AttributeError: + # Divergence from upstream: Make ipaddress library optional + if ipaddress is None: + host_ip = None + else: # Defensive + raise + dnsnames = [] + san = cert.get("subjectAltName", ()) + for key, value in san: + if key == "DNS": + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == "IP Address": + if host_ip is not None and _ipaddress_match(value, host_ip): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get("subject", ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == "commonName": + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError( + "hostname %r " + "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames))) + ) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0])) + else: + raise CertificateError( + "no appropriate commonName or subjectAltName fields were found" + ) diff --git a/lib/urllib3/util/ssltransport.py b/lib/urllib3/util/ssltransport.py new file mode 100644 index 0000000..4a7105d --- /dev/null +++ b/lib/urllib3/util/ssltransport.py @@ -0,0 +1,221 @@ +import io +import socket +import ssl + +from ..exceptions import ProxySchemeUnsupported +from ..packages import six + +SSL_BLOCKSIZE = 16384 + + +class SSLTransport: + """ + The SSLTransport wraps an existing socket and establishes an SSL connection. + + Contrary to Python's implementation of SSLSocket, it allows you to chain + multiple TLS connections together. It's particularly useful if you need to + implement TLS within TLS. + + The class supports most of the socket API operations. + """ + + @staticmethod + def _validate_ssl_context_for_tls_in_tls(ssl_context): + """ + Raises a ProxySchemeUnsupported if the provided ssl_context can't be used + for TLS in TLS. + + The only requirement is that the ssl_context provides the 'wrap_bio' + methods. + """ + + if not hasattr(ssl_context, "wrap_bio"): + if six.PY2: + raise ProxySchemeUnsupported( + "TLS in TLS requires SSLContext.wrap_bio() which isn't " + "supported on Python 2" + ) + else: + raise ProxySchemeUnsupported( + "TLS in TLS requires SSLContext.wrap_bio() which isn't " + "available on non-native SSLContext" + ) + + def __init__( + self, socket, ssl_context, server_hostname=None, suppress_ragged_eofs=True + ): + """ + Create an SSLTransport around socket using the provided ssl_context. + """ + self.incoming = ssl.MemoryBIO() + self.outgoing = ssl.MemoryBIO() + + self.suppress_ragged_eofs = suppress_ragged_eofs + self.socket = socket + + self.sslobj = ssl_context.wrap_bio( + self.incoming, self.outgoing, server_hostname=server_hostname + ) + + # Perform initial handshake. + self._ssl_io_loop(self.sslobj.do_handshake) + + def __enter__(self): + return self + + def __exit__(self, *_): + self.close() + + def fileno(self): + return self.socket.fileno() + + def read(self, len=1024, buffer=None): + return self._wrap_ssl_read(len, buffer) + + def recv(self, len=1024, flags=0): + if flags != 0: + raise ValueError("non-zero flags not allowed in calls to recv") + return self._wrap_ssl_read(len) + + def recv_into(self, buffer, nbytes=None, flags=0): + if flags != 0: + raise ValueError("non-zero flags not allowed in calls to recv_into") + if buffer and (nbytes is None): + nbytes = len(buffer) + elif nbytes is None: + nbytes = 1024 + return self.read(nbytes, buffer) + + def sendall(self, data, flags=0): + if flags != 0: + raise ValueError("non-zero flags not allowed in calls to sendall") + count = 0 + with memoryview(data) as view, view.cast("B") as byte_view: + amount = len(byte_view) + while count < amount: + v = self.send(byte_view[count:]) + count += v + + def send(self, data, flags=0): + if flags != 0: + raise ValueError("non-zero flags not allowed in calls to send") + response = self._ssl_io_loop(self.sslobj.write, data) + return response + + def makefile( + self, mode="r", buffering=None, encoding=None, errors=None, newline=None + ): + """ + Python's httpclient uses makefile and buffered io when reading HTTP + messages and we need to support it. + + This is unfortunately a copy and paste of socket.py makefile with small + changes to point to the socket directly. + """ + if not set(mode) <= {"r", "w", "b"}: + raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) + + writing = "w" in mode + reading = "r" in mode or not writing + assert reading or writing + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = socket.SocketIO(self, rawmode) + self.socket._io_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text + + def unwrap(self): + self._ssl_io_loop(self.sslobj.unwrap) + + def close(self): + self.socket.close() + + def getpeercert(self, binary_form=False): + return self.sslobj.getpeercert(binary_form) + + def version(self): + return self.sslobj.version() + + def cipher(self): + return self.sslobj.cipher() + + def selected_alpn_protocol(self): + return self.sslobj.selected_alpn_protocol() + + def selected_npn_protocol(self): + return self.sslobj.selected_npn_protocol() + + def shared_ciphers(self): + return self.sslobj.shared_ciphers() + + def compression(self): + return self.sslobj.compression() + + def settimeout(self, value): + self.socket.settimeout(value) + + def gettimeout(self): + return self.socket.gettimeout() + + def _decref_socketios(self): + self.socket._decref_socketios() + + def _wrap_ssl_read(self, len, buffer=None): + try: + return self._ssl_io_loop(self.sslobj.read, len, buffer) + except ssl.SSLError as e: + if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs: + return 0 # eof, return 0. + else: + raise + + def _ssl_io_loop(self, func, *args): + """Performs an I/O loop between incoming/outgoing and the socket.""" + should_loop = True + ret = None + + while should_loop: + errno = None + try: + ret = func(*args) + except ssl.SSLError as e: + if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE): + # WANT_READ, and WANT_WRITE are expected, others are not. + raise e + errno = e.errno + + buf = self.outgoing.read() + self.socket.sendall(buf) + + if errno is None: + should_loop = False + elif errno == ssl.SSL_ERROR_WANT_READ: + buf = self.socket.recv(SSL_BLOCKSIZE) + if buf: + self.incoming.write(buf) + else: + self.incoming.write_eof() + return ret diff --git a/lib/urllib3/util/timeout.py b/lib/urllib3/util/timeout.py new file mode 100644 index 0000000..78e18a6 --- /dev/null +++ b/lib/urllib3/util/timeout.py @@ -0,0 +1,271 @@ +from __future__ import absolute_import + +import time + +# The default socket timeout, used by httplib to indicate that no timeout was; specified by the user +from socket import _GLOBAL_DEFAULT_TIMEOUT, getdefaulttimeout + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + + +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) + + +class Timeout(object): + """Timeout configuration. + + Timeouts can be defined as a default for a pool: + + .. code-block:: python + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool): + + .. code-block:: python + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``: + + .. code-block:: python + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :type total: int, float, or None + + :param connect: + The maximum amount of time (in seconds) to wait for a connection + attempt to a server to succeed. Omitting the parameter will default the + connect timeout to the system default, probably `the global default + timeout in socket.py + `_. + None will set an infinite timeout for connection attempts. + + :type connect: int, float, or None + + :param read: + The maximum amount of time (in seconds) to wait between consecutive + read operations for a response from the server. Omitting the parameter + will default the read timeout to the system default, probably `the + global default timeout in socket.py + `_. + None will set an infinite timeout. + + :type read: int, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT + + def __init__(self, total=None, connect=_Default, read=_Default): + self._connect = self._validate_timeout(connect, "connect") + self._read = self._validate_timeout(read, "read") + self.total = self._validate_timeout(total, "total") + self._start_connect = None + + def __repr__(self): + return "%s(connect=%r, read=%r, total=%r)" % ( + type(self).__name__, + self._connect, + self._read, + self.total, + ) + + # __str__ provided for backwards compatibility + __str__ = __repr__ + + @classmethod + def resolve_default_timeout(cls, timeout): + return getdefaulttimeout() if timeout is cls.DEFAULT_TIMEOUT else timeout + + @classmethod + def _validate_timeout(cls, value, name): + """Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If it is a numeric value less than or equal to + zero, or the type is not an integer, float, or None. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + if isinstance(value, bool): + raise ValueError( + "Timeout cannot be a boolean value. It must " + "be an int, float or None." + ) + try: + float(value) + except (TypeError, ValueError): + raise ValueError( + "Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value) + ) + + try: + if value <= 0: + raise ValueError( + "Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than or equal to 0." % (name, value) + ) + except TypeError: + # Python 3 + raise ValueError( + "Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value) + ) + + return value + + @classmethod + def from_float(cls, timeout): + """Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # We can't use copy.deepcopy because that will also create a new object + # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to + # detect the user default. + return Timeout(connect=self._connect, read=self._read, total=self.total) + + def start_connect(self): + """Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time in seconds. + :rtype: float + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to get duration for a timer that hasn't been started. + """ + if self._start_connect is None: + raise TimeoutStateError( + "Can't get connect duration for timer that has not started." + ) + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` + has not yet been called on this object. + """ + if ( + self.total is not None + and self.total is not self.DEFAULT_TIMEOUT + and self._read is not None + and self._read is not self.DEFAULT_TIMEOUT + ): + # In case the connect timeout has not yet been established. + if self._start_connect is None: + return self._read + return max(0, min(self.total - self.get_connect_duration(), self._read)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/lib/urllib3/util/url.py b/lib/urllib3/util/url.py new file mode 100644 index 0000000..e5682d3 --- /dev/null +++ b/lib/urllib3/util/url.py @@ -0,0 +1,435 @@ +from __future__ import absolute_import + +import re +from collections import namedtuple + +from ..exceptions import LocationParseError +from ..packages import six + +url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"] + +# We only want to normalize urls with an HTTP(S) scheme. +# urllib3 infers URLs without a scheme (None) to be http. +NORMALIZABLE_SCHEMES = ("http", "https", None) + +# Almost all of these patterns were derived from the +# 'rfc3986' module: https://github.com/python-hyper/rfc3986 +PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}") +SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)") +URI_RE = re.compile( + r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?" + r"(?://([^\\/?#]*))?" + r"([^?#]*)" + r"(?:\?([^#]*))?" + r"(?:#(.*))?$", + re.UNICODE | re.DOTALL, +) + +IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}" +HEX_PAT = "[0-9A-Fa-f]{1,4}" +LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT) +_subs = {"hex": HEX_PAT, "ls32": LS32_PAT} +_variations = [ + # 6( h16 ":" ) ls32 + "(?:%(hex)s:){6}%(ls32)s", + # "::" 5( h16 ":" ) ls32 + "::(?:%(hex)s:){5}%(ls32)s", + # [ h16 ] "::" 4( h16 ":" ) ls32 + "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s", + # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s", + # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s", + # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s", + # [ *4( h16 ":" ) h16 ] "::" ls32 + "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s", + # [ *5( h16 ":" ) h16 ] "::" h16 + "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s", + # [ *6( h16 ":" ) h16 ] "::" + "(?:(?:%(hex)s:){0,6}%(hex)s)?::", +] + +UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._\-~" +IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")" +ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+" +IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]" +REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*" +TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$") + +IPV4_RE = re.compile("^" + IPV4_PAT + "$") +IPV6_RE = re.compile("^" + IPV6_PAT + "$") +IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$") +BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$") +ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$") + +_HOST_PORT_PAT = ("^(%s|%s|%s)(?::0*?(|0|[1-9][0-9]{0,4}))?$") % ( + REG_NAME_PAT, + IPV4_PAT, + IPV6_ADDRZ_PAT, +) +_HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL) + +UNRESERVED_CHARS = set( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~" +) +SUB_DELIM_CHARS = set("!$&'()*+,;=") +USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"} +PATH_CHARS = USERINFO_CHARS | {"@", "/"} +QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"} + + +class Url(namedtuple("Url", url_attrs)): + """ + Data structure for representing an HTTP URL. Used as a return value for + :func:`parse_url`. Both the scheme and host are normalized as they are + both case-insensitive according to RFC 3986. + """ + + __slots__ = () + + def __new__( + cls, + scheme=None, + auth=None, + host=None, + port=None, + path=None, + query=None, + fragment=None, + ): + if path and not path.startswith("/"): + path = "/" + path + if scheme is not None: + scheme = scheme.lower() + return super(Url, cls).__new__( + cls, scheme, auth, host, port, path, query, fragment + ) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or "/" + + if self.query is not None: + uri += "?" + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return "%s:%d" % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = u"" + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + u"://" + if auth is not None: + url += auth + u"@" + if host is not None: + url += host + if port is not None: + url += u":" + str(port) + if path is not None: + url += path + if query is not None: + url += u"?" + query + if fragment is not None: + url += u"#" + fragment + + return url + + def __str__(self): + return self.url + + +def split_first(s, delims): + """ + .. deprecated:: 1.25 + + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, "", None + + return s[:min_idx], s[min_idx + 1 :], min_delim + + +def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"): + """Percent-encodes a URI component without reapplying + onto an already percent-encoded component. + """ + if component is None: + return component + + component = six.ensure_text(component) + + # Normalize existing percent-encoded bytes. + # Try to see if the component we're encoding is already percent-encoded + # so we can skip all '%' characters but still encode all others. + component, percent_encodings = PERCENT_RE.subn( + lambda match: match.group(0).upper(), component + ) + + uri_bytes = component.encode("utf-8", "surrogatepass") + is_percent_encoded = percent_encodings == uri_bytes.count(b"%") + encoded_component = bytearray() + + for i in range(0, len(uri_bytes)): + # Will return a single character bytestring on both Python 2 & 3 + byte = uri_bytes[i : i + 1] + byte_ord = ord(byte) + if (is_percent_encoded and byte == b"%") or ( + byte_ord < 128 and byte.decode() in allowed_chars + ): + encoded_component += byte + continue + encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper())) + + return encoded_component.decode(encoding) + + +def _remove_path_dot_segments(path): + # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code + segments = path.split("/") # Turn the path into a list of segments + output = [] # Initialize the variable to use to store output + + for segment in segments: + # '.' is the current directory, so ignore it, it is superfluous + if segment == ".": + continue + # Anything other than '..', should be appended to the output + elif segment != "..": + output.append(segment) + # In this case segment == '..', if we can, we should pop the last + # element + elif output: + output.pop() + + # If the path starts with '/' and the output is empty or the first string + # is non-empty + if path.startswith("/") and (not output or output[0]): + output.insert(0, "") + + # If the path starts with '/.' or '/..' ensure we add one more empty + # string to add a trailing '/' + if path.endswith(("/.", "/..")): + output.append("") + + return "/".join(output) + + +def _normalize_host(host, scheme): + if host: + if isinstance(host, six.binary_type): + host = six.ensure_str(host) + + if scheme in NORMALIZABLE_SCHEMES: + is_ipv6 = IPV6_ADDRZ_RE.match(host) + if is_ipv6: + # IPv6 hosts of the form 'a::b%zone' are encoded in a URL as + # such per RFC 6874: 'a::b%25zone'. Unquote the ZoneID + # separator as necessary to return a valid RFC 4007 scoped IP. + match = ZONE_ID_RE.search(host) + if match: + start, end = match.span(1) + zone_id = host[start:end] + + if zone_id.startswith("%25") and zone_id != "%25": + zone_id = zone_id[3:] + else: + zone_id = zone_id[1:] + zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS) + return host[:start].lower() + zone_id + host[end:] + else: + return host.lower() + elif not IPV4_RE.match(host): + return six.ensure_str( + b".".join([_idna_encode(label) for label in host.split(".")]) + ) + return host + + +def _idna_encode(name): + if name and any(ord(x) >= 128 for x in name): + try: + import idna + except ImportError: + six.raise_from( + LocationParseError("Unable to parse URL without the 'idna' module"), + None, + ) + try: + return idna.encode(name.lower(), strict=True, std3_rules=True) + except idna.IDNAError: + six.raise_from( + LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None + ) + return name.lower().encode("ascii") + + +def _encode_target(target): + """Percent-encodes a request target so that there are no invalid characters""" + path, query = TARGET_RE.match(target).groups() + target = _encode_invalid_chars(path, PATH_CHARS) + query = _encode_invalid_chars(query, QUERY_CHARS) + if query is not None: + target += "?" + query + return target + + +def parse_url(url): + """ + Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is + performed to parse incomplete urls. Fields not provided will be None. + This parser is RFC 3986 and RFC 6874 compliant. + + The parser logic and helper functions are based heavily on + work done in the ``rfc3986`` module. + + :param str url: URL to parse into a :class:`.Url` namedtuple. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + if not url: + # Empty + return Url() + + source_url = url + if not SCHEME_RE.search(url): + url = "//" + url + + try: + scheme, authority, path, query, fragment = URI_RE.match(url).groups() + normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES + + if scheme: + scheme = scheme.lower() + + if authority: + auth, _, host_port = authority.rpartition("@") + auth = auth or None + host, port = _HOST_PORT_RE.match(host_port).groups() + if auth and normalize_uri: + auth = _encode_invalid_chars(auth, USERINFO_CHARS) + if port == "": + port = None + else: + auth, host, port = None, None, None + + if port is not None: + port = int(port) + if not (0 <= port <= 65535): + raise LocationParseError(url) + + host = _normalize_host(host, scheme) + + if normalize_uri and path: + path = _remove_path_dot_segments(path) + path = _encode_invalid_chars(path, PATH_CHARS) + if normalize_uri and query: + query = _encode_invalid_chars(query, QUERY_CHARS) + if normalize_uri and fragment: + fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS) + + except (ValueError, AttributeError): + return six.raise_from(LocationParseError(source_url), None) + + # For the sake of backwards compatibility we put empty + # string values for path if there are any defined values + # beyond the path in the URL. + # TODO: Remove this when we break backwards compatibility. + if not path: + if query is not None or fragment is not None: + path = "" + else: + path = None + + # Ensure that each part of the URL is a `str` for + # backwards compatibility. + if isinstance(url, six.text_type): + ensure_func = six.ensure_text + else: + ensure_func = six.ensure_str + + def ensure_type(x): + return x if x is None else ensure_func(x) + + return Url( + scheme=ensure_type(scheme), + auth=ensure_type(auth), + host=ensure_type(host), + port=port, + path=ensure_type(path), + query=ensure_type(query), + fragment=ensure_type(fragment), + ) + + +def get_host(url): + """ + Deprecated. Use :func:`parse_url` instead. + """ + p = parse_url(url) + return p.scheme or "http", p.hostname, p.port diff --git a/lib/urllib3/util/wait.py b/lib/urllib3/util/wait.py new file mode 100644 index 0000000..21b4590 --- /dev/null +++ b/lib/urllib3/util/wait.py @@ -0,0 +1,152 @@ +import errno +import select +import sys +from functools import partial + +try: + from time import monotonic +except ImportError: + from time import time as monotonic + +__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"] + + +class NoWayToWaitForSocketError(Exception): + pass + + +# How should we wait on sockets? +# +# There are two types of APIs you can use for waiting on sockets: the fancy +# modern stateful APIs like epoll/kqueue, and the older stateless APIs like +# select/poll. The stateful APIs are more efficient when you have a lots of +# sockets to keep track of, because you can set them up once and then use them +# lots of times. But we only ever want to wait on a single socket at a time +# and don't want to keep track of state, so the stateless APIs are actually +# more efficient. So we want to use select() or poll(). +# +# Now, how do we choose between select() and poll()? On traditional Unixes, +# select() has a strange calling convention that makes it slow, or fail +# altogether, for high-numbered file descriptors. The point of poll() is to fix +# that, so on Unixes, we prefer poll(). +# +# On Windows, there is no poll() (or at least Python doesn't provide a wrapper +# for it), but that's OK, because on Windows, select() doesn't have this +# strange calling convention; plain select() works fine. +# +# So: on Windows we use select(), and everywhere else we use poll(). We also +# fall back to select() in case poll() is somehow broken or missing. + +if sys.version_info >= (3, 5): + # Modern Python, that retries syscalls by default + def _retry_on_intr(fn, timeout): + return fn(timeout) + +else: + # Old and broken Pythons. + def _retry_on_intr(fn, timeout): + if timeout is None: + deadline = float("inf") + else: + deadline = monotonic() + timeout + + while True: + try: + return fn(timeout) + # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7 + except (OSError, select.error) as e: + # 'e.args[0]' incantation works for both OSError and select.error + if e.args[0] != errno.EINTR: + raise + else: + timeout = deadline - monotonic() + if timeout < 0: + timeout = 0 + if timeout == float("inf"): + timeout = None + continue + + +def select_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + rcheck = [] + wcheck = [] + if read: + rcheck.append(sock) + if write: + wcheck.append(sock) + # When doing a non-blocking connect, most systems signal success by + # marking the socket writable. Windows, though, signals success by marked + # it as "exceptional". We paper over the difference by checking the write + # sockets for both conditions. (The stdlib selectors module does the same + # thing.) + fn = partial(select.select, rcheck, wcheck, wcheck) + rready, wready, xready = _retry_on_intr(fn, timeout) + return bool(rready or wready or xready) + + +def poll_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + mask = 0 + if read: + mask |= select.POLLIN + if write: + mask |= select.POLLOUT + poll_obj = select.poll() + poll_obj.register(sock, mask) + + # For some reason, poll() takes timeout in milliseconds + def do_poll(t): + if t is not None: + t *= 1000 + return poll_obj.poll(t) + + return bool(_retry_on_intr(do_poll, timeout)) + + +def null_wait_for_socket(*args, **kwargs): + raise NoWayToWaitForSocketError("no select-equivalent available") + + +def _have_working_poll(): + # Apparently some systems have a select.poll that fails as soon as you try + # to use it, either due to strange configuration or broken monkeypatching + # from libraries like eventlet/greenlet. + try: + poll_obj = select.poll() + _retry_on_intr(poll_obj.poll, 0) + except (AttributeError, OSError): + return False + else: + return True + + +def wait_for_socket(*args, **kwargs): + # We delay choosing which implementation to use until the first time we're + # called. We could do it at import time, but then we might make the wrong + # decision if someone goes wild with monkeypatching select.poll after + # we're imported. + global wait_for_socket + if _have_working_poll(): + wait_for_socket = poll_wait_for_socket + elif hasattr(select, "select"): + wait_for_socket = select_wait_for_socket + else: # Platform-specific: Appengine. + wait_for_socket = null_wait_for_socket + return wait_for_socket(*args, **kwargs) + + +def wait_for_read(sock, timeout=None): + """Waits for reading to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, read=True, timeout=timeout) + + +def wait_for_write(sock, timeout=None): + """Waits for writing to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/plugin.json b/plugin.json new file mode 100644 index 0000000..92e2092 --- /dev/null +++ b/plugin.json @@ -0,0 +1,12 @@ +{ + "ID": "060347D7D8A8070255342938D465B04F", + "ActionKeyword": "osrs", + "Name": "OSRSSearch", + "Description": "Searches OSRS Wiki", + "Author": "Lars", + "Version": "0.0.1", + "Language": "python", + "Website": "https://git.lrsb.nl/Lars/FlowLauncher-OSRS-Wiki-Search", + "IcoPath": "./icon.png", + "ExecuteFileName": "run.py" +} \ No newline at end of file diff --git a/plugin.log b/plugin.log new file mode 100644 index 0000000..ea37253 --- /dev/null +++ b/plugin.log @@ -0,0 +1,595 @@ +22:35:59 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:36:01 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:36:05 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:36:07 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:36:10 ERROR (launcher.py): Launcher.change_query() missing 1 required positional argument: 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: Launcher.change_query() missing 1 required positional argument: 'query' +22:36:28 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:36:34 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:38:04 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:38:07 ERROR (launcher.py): Launcher.change_query() missing 1 required positional argument: 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: Launcher.change_query() missing 1 required positional argument: 'query' +22:38:09 ERROR (launcher.py): OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 15, in query + for result in self.OSRSWIKI.search(query): + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 20, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 3 required positional arguments: 'method', 'url', and 'endpoint' +22:38:52 ERROR (launcher.py): 'list' object has no attribute 'add_item' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results.add_item( + ^^^^^^^^^^^^^^^^ +AttributeError: 'list' object has no attribute 'add_item' +22:38:55 ERROR (launcher.py): 'list' object has no attribute 'add_item' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results.add_item( + ^^^^^^^^^^^^^^^^ +AttributeError: 'list' object has no attribute 'add_item' +22:38:57 ERROR (launcher.py): 'list' object has no attribute 'add_item' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results.add_item( + ^^^^^^^^^^^^^^^^ +AttributeError: 'list' object has no attribute 'add_item' +22:38:59 ERROR (launcher.py): Launcher.change_query() missing 1 required positional argument: 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: Launcher.change_query() missing 1 required positional argument: 'query' +22:39:26 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:39:32 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:39:34 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:39:49 ERROR (launcher.py): Launcher.change_query() missing 1 required positional argument: 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: Launcher.change_query() missing 1 required positional argument: 'query' +22:40:51 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:42:32 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 14, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:42:35 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 14, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:42:36 ERROR (launcher.py): 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 19, in query + parameters=[result['url']] + ~~~~~~^^^^^^^ +KeyError: 'url' +22:42:38 ERROR (launcher.py): 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 19, in query + parameters=[result['url']] + ~~~~~~^^^^^^^ +KeyError: 'url' +22:44:07 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:44:42 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:45:18 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 18, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:45:18 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 18, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:45:20 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 18, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:45:46 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:45:47 ERROR (launcher.py): string indices must be integers, not 'str' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 18, in query + title=result['title'], + ~~~~~~^^^^^^^^^ +TypeError: string indices must be integers, not 'str' +22:46:11 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:47:54 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:52:33 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +22:56:28 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 19, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:56:29 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 19, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:56:30 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 19, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:56:34 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 19, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:56:39 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 19, in search + response = self.request('GET', BASE_URL, params={'srsearch': query}) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:58:21 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 22, in search + response = self.request("get", BASE_URL, params) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:58:22 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 22, in search + response = self.request("get", BASE_URL, params) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +22:58:24 ERROR (launcher.py): Launcher.change_query() missing 1 required positional argument: 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +TypeError: Launcher.change_query() missing 1 required positional argument: 'query' +22:59:23 ERROR (launcher.py): OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\osrswiki.py", line 22, in search + response = self.request("get", BASE_URL, params) + ^^^^^^^^^^^^ +TypeError: OSRSSearch.request() missing 2 required positional arguments: 'method' and 'url' +23:00:02 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:00:34 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:00:34 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + for result in self.OSRSWIKI.search(query)["query"]["search"]: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:00:35 ERROR (launcher.py): 'charmap' codec can't encode characters in position 224-225: character maps to +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 17, in query + print(result) + File "encodings\cp1252.py", line 19, in encode +UnicodeEncodeError: 'charmap' codec can't encode characters in position 224-225: character maps to +23:05:36 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results = self.OSRSWIKI.search(query)["query"]["search"] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:08:32 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results = self.OSRSWIKI.search(query)["query"]["search"] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:08:35 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results = self.OSRSWIKI.search(query)["query"]["search"] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:12:23 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results = self.OSRSWIKI.search(query)["query"]["search"] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:13:20 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results = self.OSRSWIKI.search(query)["query"]["search"] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' +23:13:21 ERROR (launcher.py): 'query' +Traceback (most recent call last): + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\launcher.py", line 44, in run + results = request_method(*request_parameters) or self._results + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\lib\flox\__init__.py", line 132, in _query + self.query(query) + File "C:\Users\Lars\AppData\Roaming\FlowLauncher\Plugins\OSRS-Wiki-Search\plugin\searchwiki.py", line 16, in query + results = self.OSRSWIKI.search(query)["query"]["search"] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^ +KeyError: 'query' diff --git a/plugin/osrswiki.py b/plugin/osrswiki.py new file mode 100644 index 0000000..779f675 --- /dev/null +++ b/plugin/osrswiki.py @@ -0,0 +1,23 @@ +import json +import os +import shutil +import requests + +BASE_URL = 'https://oldschool.runescape.wiki/api.php?action=query&list=search&srwhat=text&format=json&srsearch=' + +class OSRSSearch(object): + def __init__(self): + self._session = requests.Session() + + def request(self, method, url, params=None, verify_ssl=True, timeout=60): + response = self._session.request(method, url, params=params, verify=verify_ssl, timeout=timeout) + response.raise_for_status() + return response + + def search(self, query): + params = { + ('srsearch', query) + } + response = self.request("get", BASE_URL, params) + return response.json() + \ No newline at end of file diff --git a/plugin/searchwiki.py b/plugin/searchwiki.py new file mode 100644 index 0000000..d02324b --- /dev/null +++ b/plugin/searchwiki.py @@ -0,0 +1,34 @@ +import webbrowser +import re +import os +import tempfile +from flox import Flox +from osrswiki import OSRSSearch, BASE_URL + +WIKI_URL = 'https://oldschool.runescape.wiki/w/' + +class OSRSSearcher(Flox): + def __init__(self): + self.OSRSWIKI = OSRSSearch() + super().__init__() + + def query(self, query): + results = self.OSRSWIKI.search(query)["query"]["search"] + for result in results: + openurl = f"{WIKI_URL}{result['title'].replace(' ', '_')}" + self.add_item( + title=result['title'].replace('"', ''), + subtitle="Open OSRS Wiki", + method='open_url', + parameters=[openurl] + ) + return + + def context_menu(self, data): + pass + + def open_url(self, url): + webbrowser.open(url) + +if __name__ == "__main__": + OSRSSearcher() \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..998f4da --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +requests==2.25.1 +flox-lib==0.19.6 \ No newline at end of file diff --git a/run.py b/run.py new file mode 100644 index 0000000..e4dc7d3 --- /dev/null +++ b/run.py @@ -0,0 +1,12 @@ +import sys +import os + +plugindir = os.path.abspath(os.path.dirname(__file__)) +sys.path.append(plugindir) +sys.path.append(os.path.join(plugindir, "lib")) +sys.path.append(os.path.join(plugindir, "plugin")) + +from plugin.searchwiki import OSRSSearcher + +if __name__ == "__main__": + OSRSSearcher() \ No newline at end of file