From e9ff1f6d3b4b0737373cb5861b7da6206e8f8d55 Mon Sep 17 00:00:00 2001 From: Mathew Payne <2772944+GeekMasher@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:54:56 +0000 Subject: [PATCH 1/3] feat(version): v1.2.0 --- .release.yml | 7 +++++++ cpdsa/__init__.py | 2 +- cpdsa/__main__.py | 3 +-- 3 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 .release.yml diff --git a/.release.yml b/.release.yml new file mode 100644 index 0000000..85e50e0 --- /dev/null +++ b/.release.yml @@ -0,0 +1,7 @@ +name: cocoapods-dependency-submission-action +repository: advanced-security/cocoapods-dependency-submission-action +version: 1.2.0 + +ecosystems: + - Docs + - Python diff --git a/cpdsa/__init__.py b/cpdsa/__init__.py index 7f1d3d9..c90a66e 100644 --- a/cpdsa/__init__.py +++ b/cpdsa/__init__.py @@ -1,5 +1,5 @@ __name__ = "cpdsa" __title__ = "cocoapods-dependency-submission-action" -__version__ = "0.1.1" +__version__ = "1.2.0" __url__ = "https://github.com/GeekMasher/cocoapods-dependency-submission-action" diff --git a/cpdsa/__main__.py b/cpdsa/__main__.py index 8e97533..23b87af 100644 --- a/cpdsa/__main__.py +++ b/cpdsa/__main__.py @@ -3,8 +3,7 @@ import logging import argparse -from ghastoolkit.octokit.github import GitHub -from ghastoolkit.octokit.dependencygraph import DependencyGraph +from ghastoolkit import GitHub, DependencyGraph from cpdsa import __name__ as tool_name from cpdsa.cocoapods import parseLockFile, findCocoaPods From 2f8cae0786fb9fcc747b2d3b0ac935a15cf14191 Mon Sep 17 00:00:00 2001 From: Mathew Payne <2772944+GeekMasher@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:55:41 +0000 Subject: [PATCH 2/3] feat(vendor): Update vendored deps --- vendor/bin/normalizer | 4 +- vendor/certifi/__init__.py | 2 +- vendor/certifi/cacert.pem | 840 +- vendor/certifi/core.py | 6 + vendor/charset_normalizer/__init__.py | 3 +- vendor/charset_normalizer/__main__.py | 4 + vendor/charset_normalizer/api.py | 158 +- vendor/charset_normalizer/assets/__init__.py | 1440 -- vendor/charset_normalizer/cd.py | 9 +- vendor/charset_normalizer/cli/__init__.py | 6 + .../cli/{normalizer.py => __main__.py} | 36 +- vendor/charset_normalizer/constant.py | 2072 +- vendor/charset_normalizer/legacy.py | 15 +- vendor/charset_normalizer/md.py | 81 +- vendor/charset_normalizer/models.py | 46 +- vendor/charset_normalizer/utils.py | 47 +- vendor/charset_normalizer/version.py | 2 +- vendor/ghastoolkit/__init__.py | 31 +- vendor/ghastoolkit/__main__.py | 130 +- vendor/ghastoolkit/codeql/__init__.py | 2 - vendor/ghastoolkit/codeql/__main__.py | 38 + vendor/ghastoolkit/codeql/cli.py | 269 +- vendor/ghastoolkit/codeql/databases.py | 102 +- .../codeql/dataextensions/__init__.py | 1 + .../codeql/dataextensions/__main__.py | 30 + .../ghastoolkit/codeql/dataextensions/ext.py | 87 + .../codeql/dataextensions/models.py | 171 + .../codeql/packs}/__init__.py | 0 vendor/ghastoolkit/codeql/packs/__main__.py | 117 + vendor/ghastoolkit/codeql/packs/pack.py | 230 + vendor/ghastoolkit/codeql/packs/packs.py | 53 + vendor/ghastoolkit/codeql/results.py | 20 + vendor/ghastoolkit/codeql/utils.py | 19 - vendor/ghastoolkit/errors.py | 50 + vendor/ghastoolkit/octokit/advisories.py | 120 + vendor/ghastoolkit/octokit/clearlydefined.py | 72 + vendor/ghastoolkit/octokit/codescanning.py | 593 +- vendor/ghastoolkit/octokit/dependabot.py | 167 +- vendor/ghastoolkit/octokit/dependencygraph.py | 248 +- vendor/ghastoolkit/octokit/enterprise.py | 197 + vendor/ghastoolkit/octokit/github.py | 236 +- .../ghastoolkit/octokit/graphql/__init__.py | 102 + vendor/ghastoolkit/octokit/octokit.py | 177 +- vendor/ghastoolkit/octokit/repository.py | 273 + vendor/ghastoolkit/octokit/secretscanning.py | 174 +- .../secretscanning/secretalerts.py | 2 +- vendor/ghastoolkit/supplychain/__main__.py | 84 + vendor/ghastoolkit/supplychain/advisories.py | 279 +- .../ghastoolkit/supplychain/dependencies.py | 88 +- .../supplychain/dependencyalert.py | 11 + vendor/ghastoolkit/utils/__init__.py | 0 vendor/ghastoolkit/utils/cli.py | 129 + vendor/idna/__init__.py | 3 +- vendor/idna/codec.py | 76 +- vendor/idna/compat.py | 10 +- vendor/idna/core.py | 295 +- vendor/idna/idnadata.py | 5596 ++++-- vendor/idna/intranges.py | 11 +- vendor/idna/package_data.py | 3 +- vendor/idna/uts46data.py | 16441 ++++++++-------- vendor/requests/__init__.py | 6 +- vendor/requests/__version__.py | 6 +- vendor/requests/adapters.py | 219 +- vendor/requests/api.py | 2 +- vendor/requests/auth.py | 1 - vendor/requests/compat.py | 25 +- vendor/requests/cookies.py | 16 +- vendor/requests/exceptions.py | 10 + vendor/requests/models.py | 13 +- vendor/requests/packages.py | 23 +- vendor/requests/sessions.py | 14 +- vendor/requests/status_codes.py | 10 +- vendor/requests/utils.py | 16 +- vendor/semantic_version/__init__.py | 18 + vendor/semantic_version/base.py | 1449 ++ vendor/semantic_version/django_fields.py | 107 + vendor/urllib3/__init__.py | 98 +- vendor/urllib3/_base_connection.py | 11 +- vendor/urllib3/_collections.py | 55 +- vendor/urllib3/_request_methods.py | 65 +- vendor/urllib3/_version.py | 18 +- vendor/urllib3/connection.py | 270 +- vendor/urllib3/connectionpool.py | 32 +- .../contrib/_securetransport/bindings.py | 430 - .../contrib/_securetransport/low_level.py | 474 - vendor/urllib3/contrib/emscripten/__init__.py | 16 + .../urllib3/contrib/emscripten/connection.py | 254 + .../emscripten/emscripten_fetch_worker.js | 110 + vendor/urllib3/contrib/emscripten/fetch.py | 418 + vendor/urllib3/contrib/emscripten/request.py | 22 + vendor/urllib3/contrib/emscripten/response.py | 285 + vendor/urllib3/contrib/pyopenssl.py | 25 +- vendor/urllib3/contrib/securetransport.py | 913 - vendor/urllib3/contrib/socks.py | 25 +- vendor/urllib3/exceptions.py | 11 +- vendor/urllib3/fields.py | 8 +- vendor/urllib3/http2/__init__.py | 53 + vendor/urllib3/http2/connection.py | 356 + vendor/urllib3/http2/probe.py | 87 + vendor/urllib3/poolmanager.py | 29 +- vendor/urllib3/response.py | 220 +- vendor/urllib3/util/__init__.py | 2 - vendor/urllib3/util/connection.py | 2 +- vendor/urllib3/util/request.py | 12 +- vendor/urllib3/util/retry.py | 12 +- vendor/urllib3/util/ssl_.py | 92 +- vendor/urllib3/util/ssltransport.py | 12 +- vendor/urllib3/util/timeout.py | 6 +- vendor/yaml/__init__.py | 2 +- 109 files changed, 23044 insertions(+), 14824 deletions(-) create mode 100644 vendor/charset_normalizer/__main__.py delete mode 100644 vendor/charset_normalizer/assets/__init__.py rename vendor/charset_normalizer/cli/{normalizer.py => __main__.py} (90%) create mode 100644 vendor/ghastoolkit/codeql/__main__.py create mode 100644 vendor/ghastoolkit/codeql/dataextensions/__init__.py create mode 100644 vendor/ghastoolkit/codeql/dataextensions/__main__.py create mode 100644 vendor/ghastoolkit/codeql/dataextensions/ext.py create mode 100644 vendor/ghastoolkit/codeql/dataextensions/models.py rename vendor/{urllib3/contrib/_securetransport => ghastoolkit/codeql/packs}/__init__.py (100%) create mode 100644 vendor/ghastoolkit/codeql/packs/__main__.py create mode 100644 vendor/ghastoolkit/codeql/packs/pack.py create mode 100644 vendor/ghastoolkit/codeql/packs/packs.py delete mode 100644 vendor/ghastoolkit/codeql/utils.py create mode 100644 vendor/ghastoolkit/errors.py create mode 100644 vendor/ghastoolkit/octokit/advisories.py create mode 100644 vendor/ghastoolkit/octokit/clearlydefined.py create mode 100644 vendor/ghastoolkit/octokit/enterprise.py create mode 100644 vendor/ghastoolkit/octokit/graphql/__init__.py create mode 100644 vendor/ghastoolkit/octokit/repository.py create mode 100644 vendor/ghastoolkit/supplychain/__main__.py create mode 100644 vendor/ghastoolkit/utils/__init__.py create mode 100644 vendor/ghastoolkit/utils/cli.py create mode 100644 vendor/semantic_version/__init__.py create mode 100644 vendor/semantic_version/base.py create mode 100644 vendor/semantic_version/django_fields.py delete mode 100644 vendor/urllib3/contrib/_securetransport/bindings.py delete mode 100644 vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 vendor/urllib3/contrib/emscripten/__init__.py create mode 100644 vendor/urllib3/contrib/emscripten/connection.py create mode 100644 vendor/urllib3/contrib/emscripten/emscripten_fetch_worker.js create mode 100644 vendor/urllib3/contrib/emscripten/fetch.py create mode 100644 vendor/urllib3/contrib/emscripten/request.py create mode 100644 vendor/urllib3/contrib/emscripten/response.py delete mode 100644 vendor/urllib3/contrib/securetransport.py create mode 100644 vendor/urllib3/http2/__init__.py create mode 100644 vendor/urllib3/http2/connection.py create mode 100644 vendor/urllib3/http2/probe.py diff --git a/vendor/bin/normalizer b/vendor/bin/normalizer index 94eea78..77a2cce 100755 --- a/vendor/bin/normalizer +++ b/vendor/bin/normalizer @@ -1,8 +1,8 @@ -#!/usr/local/opt/python@3.11/bin/python3.11 +#!/usr/local/python/3.12.1/bin/python3 # -*- coding: utf-8 -*- import re import sys -from charset_normalizer.cli.normalizer import cli_detect +from charset_normalizer.cli import cli_detect if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(cli_detect()) diff --git a/vendor/certifi/__init__.py b/vendor/certifi/__init__.py index 705f416..f61d77f 100644 --- a/vendor/certifi/__init__.py +++ b/vendor/certifi/__init__.py @@ -1,4 +1,4 @@ from .core import contents, where __all__ = ["contents", "where"] -__version__ = "2023.05.07" +__version__ = "2024.08.30" diff --git a/vendor/certifi/cacert.pem b/vendor/certifi/cacert.pem index 5183934..3c165a1 100644 --- a/vendor/certifi/cacert.pem +++ b/vendor/certifi/cacert.pem @@ -245,34 +245,6 @@ mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK 4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 -# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 -# Label: "Security Communication Root CA" -# Serial: 0 -# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a -# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 -# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c ------BEGIN CERTIFICATE----- -MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY -MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t -dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 -WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD -VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 -9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ -DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 -Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N -QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ -xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G -A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T -AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG -kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr -Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 -Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU -JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot -RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== ------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" @@ -791,34 +763,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post -# Label: "Hongkong Post Root CA 1" -# Serial: 1000 -# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca -# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 -# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 ------BEGIN CERTIFICATE----- -MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx -FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg -Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG -A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr -b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ -jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn -PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh -ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 -nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h -q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED -MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC -mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 -7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB -oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs -EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO -fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi -AmvZWg== ------END CERTIFICATE----- - # Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Label: "SecureSign RootCA11" @@ -909,49 +853,6 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----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: 6047274297262753887 -# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 -# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa -# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE -BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h -cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy -MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg -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+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD -VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD -VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp -cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv -ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl -AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF -661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 -am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 -ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 -PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS -3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k -SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF -3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM -ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g -StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz -Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB -jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V ------END CERTIFICATE----- - # Issuer: CN=Izenpe.com O=IZENPE S.A. # Subject: CN=Izenpe.com O=IZENPE S.A. # Label: "Izenpe.com" @@ -1676,50 +1577,6 @@ HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- -# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi -# Label: "E-Tugra Certification Authority" -# Serial: 7667447206703254355 -# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 -# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 -# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c ------BEGIN CERTIFICATE----- -MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV -BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC -aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV -BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 -Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz -MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ -BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp -em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN -ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY -B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH -D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF -Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo -q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D -k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH -fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut -dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM -ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 -zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn -rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX -U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 -Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 -XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF -Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR -HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY -GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c -77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 -+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK -vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 -FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl -yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P -AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD -y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d -NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== ------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" @@ -3628,46 +3485,6 @@ DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= -----END CERTIFICATE----- -# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH -# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH -# Label: "GLOBALTRUST 2020" -# Serial: 109160994242082918454945253 -# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8 -# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2 -# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG -A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw -FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx -MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u -aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq -hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b -RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z -YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 -QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw -yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ -BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ -SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH -r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 -4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me -dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw -q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 -nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu -H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC -XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd -6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf -+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi -kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 -wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB -TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C -MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn -4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I -aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy -qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------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" @@ -4397,73 +4214,6 @@ ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR -----END CERTIFICATE----- -# Issuer: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Subject: CN=E-Tugra Global Root CA RSA v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Label: "E-Tugra Global Root CA RSA v3" -# Serial: 75951268308633135324246244059508261641472512052 -# MD5 Fingerprint: 22:be:10:f6:c2:f8:03:88:73:5f:33:29:47:28:47:a4 -# SHA1 Fingerprint: e9:a8:5d:22:14:52:1c:5b:aa:0a:b4:be:24:6a:23:8a:c9:ba:e2:a9 -# SHA256 Fingerprint: ef:66:b0:b1:0a:3c:db:9f:2e:36:48:c7:6b:d2:af:18:ea:d2:bf:e6:f1:17:65:5e:28:c4:06:0d:a1:a3:f4:c2 ------BEGIN CERTIFICATE----- -MIIF8zCCA9ugAwIBAgIUDU3FzRYilZYIfrgLfxUGNPt5EDQwDQYJKoZIhvcNAQEL -BQAwgYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUt -VHVncmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYw -JAYDVQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIFJTQSB2MzAeFw0yMDAzMTgw -OTA3MTdaFw00NTAzMTIwOTA3MTdaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMG -QW5rYXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1 -Z3JhIFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBD -QSBSU0EgdjMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCiZvCJt3J7 -7gnJY9LTQ91ew6aEOErxjYG7FL1H6EAX8z3DeEVypi6Q3po61CBxyryfHUuXCscx -uj7X/iWpKo429NEvx7epXTPcMHD4QGxLsqYxYdE0PD0xesevxKenhOGXpOhL9hd8 -7jwH7eKKV9y2+/hDJVDqJ4GohryPUkqWOmAalrv9c/SF/YP9f4RtNGx/ardLAQO/ -rWm31zLZ9Vdq6YaCPqVmMbMWPcLzJmAy01IesGykNz709a/r4d+ABs8qQedmCeFL -l+d3vSFtKbZnwy1+7dZ5ZdHPOrbRsV5WYVB6Ws5OUDGAA5hH5+QYfERaxqSzO8bG -wzrwbMOLyKSRBfP12baqBqG3q+Sx6iEUXIOk/P+2UNOMEiaZdnDpwA+mdPy70Bt4 -znKS4iicvObpCdg604nmvi533wEKb5b25Y08TVJ2Glbhc34XrD2tbKNSEhhw5oBO -M/J+JjKsBY04pOZ2PJ8QaQ5tndLBeSBrW88zjdGUdjXnXVXHt6woq0bM5zshtQoK -5EpZ3IE1S0SVEgpnpaH/WwAH0sDM+T/8nzPyAPiMbIedBi3x7+PmBvrFZhNb/FAH -nnGGstpvdDDPk1Po3CLW3iAfYY2jLqN4MpBs3KwytQXk9TwzDdbgh3cXTJ2w2Amo -DVf3RIXwyAS+XF1a4xeOVGNpf0l0ZAWMowIDAQABo2MwYTAPBgNVHRMBAf8EBTAD -AQH/MB8GA1UdIwQYMBaAFLK0ruYt9ybVqnUtdkvAG1Mh0EjvMB0GA1UdDgQWBBSy -tK7mLfcm1ap1LXZLwBtTIdBI7zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEL -BQADggIBAImocn+M684uGMQQgC0QDP/7FM0E4BQ8Tpr7nym/Ip5XuYJzEmMmtcyQ -6dIqKe6cLcwsmb5FJ+Sxce3kOJUxQfJ9emN438o2Fi+CiJ+8EUdPdk3ILY7r3y18 -Tjvarvbj2l0Upq7ohUSdBm6O++96SmotKygY/r+QLHUWnw/qln0F7psTpURs+APQ -3SPh/QMSEgj0GDSz4DcLdxEBSL9htLX4GdnLTeqjjO/98Aa1bZL0SmFQhO3sSdPk -vmjmLuMxC1QLGpLWgti2omU8ZgT5Vdps+9u1FGZNlIM7zR6mK7L+d0CGq+ffCsn9 -9t2HVhjYsCxVYJb6CH5SkPVLpi6HfMsg2wY+oF0Dd32iPBMbKaITVaA9FCKvb7jQ -mhty3QUBjYZgv6Rn7rWlDdF/5horYmbDB7rnoEgcOMPpRfunf/ztAmgayncSd6YA -VSgU7NbHEqIbZULpkejLPoeJVF3Zr52XnGnnCv8PWniLYypMfUeUP95L6VPQMPHF -9p5J3zugkaOj/s1YzOrfr28oO6Bpm4/srK4rVJ2bBLFHIK+WEj5jlB0E5y67hscM -moi/dkfv97ALl2bSRM9gUgfh1SxKOidhd8rXj+eHDjD/DLsE4mHDosiXYY60MGo8 -bcIHX0pzLz/5FooBZu+6kcpSV3uu1OYP3Qt6f4ueJiDPO++BcYNZ ------END CERTIFICATE----- - -# Issuer: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Subject: CN=E-Tugra Global Root CA ECC v3 O=E-Tugra EBG A.S. OU=E-Tugra Trust Center -# Label: "E-Tugra Global Root CA ECC v3" -# Serial: 218504919822255052842371958738296604628416471745 -# MD5 Fingerprint: 46:bc:81:bb:f1:b5:1e:f7:4b:96:bc:14:e2:e7:27:64 -# SHA1 Fingerprint: 8a:2f:af:57:53:b1:b0:e6:a1:04:ec:5b:6a:69:71:6d:f6:1c:e2:84 -# SHA256 Fingerprint: 87:3f:46:85:fa:7f:56:36:25:25:2e:6d:36:bc:d7:f1:6f:c2:49:51:f2:64:e4:7e:1b:95:4f:49:08:cd:ca:13 ------BEGIN CERTIFICATE----- -MIICpTCCAiqgAwIBAgIUJkYZdzHhT28oNt45UYbm1JeIIsEwCgYIKoZIzj0EAwMw -gYAxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHEwZBbmthcmExGTAXBgNVBAoTEEUtVHVn -cmEgRUJHIEEuUy4xHTAbBgNVBAsTFEUtVHVncmEgVHJ1c3QgQ2VudGVyMSYwJAYD -VQQDEx1FLVR1Z3JhIEdsb2JhbCBSb290IENBIEVDQyB2MzAeFw0yMDAzMTgwOTQ2 -NThaFw00NTAzMTIwOTQ2NThaMIGAMQswCQYDVQQGEwJUUjEPMA0GA1UEBxMGQW5r -YXJhMRkwFwYDVQQKExBFLVR1Z3JhIEVCRyBBLlMuMR0wGwYDVQQLExRFLVR1Z3Jh -IFRydXN0IENlbnRlcjEmMCQGA1UEAxMdRS1UdWdyYSBHbG9iYWwgUm9vdCBDQSBF -Q0MgdjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASOmCm/xxAeJ9urA8woLNheSBkQ -KczLWYHMjLiSF4mDKpL2w6QdTGLVn9agRtwcvHbB40fQWxPa56WzZkjnIZpKT4YK -fWzqTTKACrJ6CZtpS5iB4i7sAnCWH/31Rs7K3IKjYzBhMA8GA1UdEwEB/wQFMAMB -Af8wHwYDVR0jBBgwFoAU/4Ixcj75xGZsrTie0bBRiKWQzPUwHQYDVR0OBBYEFP+C -MXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNp -ADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/6 -7W4WAie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFx -vmjkI6TZraE3 ------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" @@ -4587,3 +4337,593 @@ 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----- + +# Issuer: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA CYBER Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA CYBER Root CA" +# Serial: 85076849864375384482682434040119489222 +# MD5 Fingerprint: 0b:33:a0:97:52:95:d4:a9:fd:bb:db:6e:a3:55:5b:51 +# SHA1 Fingerprint: f6:b1:1c:1a:83:38:e9:7b:db:b3:a8:c8:33:24:e0:2d:9c:7f:26:66 +# SHA256 Fingerprint: 3f:63:bb:28:14:be:17:4e:c8:b6:43:9c:f0:8d:6d:56:f0:b7:c4:05:88:3a:56:48:a3:34:42:4d:6b:3e:c5:58 +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQ +MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290 +IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5 +WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FO +LUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NBIENZQkVSIFJvb3Qg +Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1sTs6P +40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxF +avcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/ +34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i +JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfu +j3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupf +Xtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP +2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDA +S9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDA +oS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzC +kHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW +5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd +BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB +AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0t +tGlTITVX1olNc79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn +68xDiBaiA9a5F/gZbG0jAn/xX9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNn +TKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7t +RCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq/p1hvIbZv97Tujqx +f36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0RFxbI +Qh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz +8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4 +NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzX +xeSDwWrruoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6 +t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA12 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA12" +# Serial: 587887345431707215246142177076162061960426065942 +# MD5 Fingerprint: c6:89:ca:64:42:9b:62:08:49:0b:1e:7f:e9:07:3d:e8 +# SHA1 Fingerprint: 7a:22:1e:3d:de:1b:06:ac:9e:c8:47:70:16:8e:3c:e5:f7:6b:06:f4 +# SHA256 Fingerprint: 3f:03:4b:b5:70:4d:44:b2:d0:85:45:a0:20:57:de:93:eb:f3:90:5f:ce:72:1a:cb:c7:30:c0:6d:da:ee:90:4e +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgw +NTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3emhF +KxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mt +p7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zd +J1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur +FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4J +hscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+K +h9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsF +AAOCAQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6Ld +mmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJ +mBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA +8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7bgoitPQV +55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/ +yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA14 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA14" +# Serial: 575790784512929437950770173562378038616896959179 +# MD5 Fingerprint: 71:0d:72:fa:92:19:65:5e:89:04:ac:16:33:f0:bc:d5 +# SHA1 Fingerprint: dd:50:c0:f7:79:b3:64:2e:74:a2:b8:9d:9f:d3:40:dd:bb:f0:f2:4f +# SHA256 Fingerprint: 4b:00:9c:10:34:49:4f:9a:b5:6b:ba:3b:a1:d6:27:31:fc:4d:20:d8:95:5a:dc:ec:10:a9:25:60:72:61:e3:38 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEM +BQAwUTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28u +LCBMdGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgw +NzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpD +eWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBS +b290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh1oq/ +FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOg +vlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy +6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo +/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9J +kdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ +0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXib +y8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac +18izju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs +0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIAB +SMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVL +ApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk +86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E +rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ib +ed87hwriZLoAymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopT +zfFP7ELyk+OZpDc8h7hi2/DsHzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHS +DCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPGFrojutzdfhrGe0K22VoF3Jpf1d+4 +2kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6qnsb58Nn4DSEC5MUo +FlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/OfVy +K4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6 +dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl +Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB +365jJ6UeTo3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39c +JRNItX+S +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Subject: CN=SecureSign Root CA15 O=Cybertrust Japan Co., Ltd. +# Label: "SecureSign Root CA15" +# Serial: 126083514594751269499665114766174399806381178503 +# MD5 Fingerprint: 13:30:fc:c4:62:a6:a9:de:b5:c1:68:af:b5:d2:31:47 +# SHA1 Fingerprint: cb:ba:83:c8:c1:5a:5d:f1:f9:73:6f:ca:d7:ef:28:13:06:4a:07:7d +# SHA256 Fingerprint: e7:78:f0:f0:95:fe:84:37:29:cd:1a:00:82:17:9e:53:14:a9:c2:91:44:28:05:e1:fb:1d:8f:b6:b8:88:6c:3a +-----BEGIN CERTIFICATE----- +MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMw +UTELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBM +dGQuMR0wGwYDVQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMy +NTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJl +cnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290 +IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5GdCx4 +wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSR +ZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT +9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp +4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6 +bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= +-----END CERTIFICATE----- diff --git a/vendor/certifi/core.py b/vendor/certifi/core.py index de02898..91f538b 100644 --- a/vendor/certifi/core.py +++ b/vendor/certifi/core.py @@ -5,6 +5,10 @@ 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): @@ -35,6 +39,7 @@ def where() -> str: # 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 @@ -70,6 +75,7 @@ def where() -> str: # 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 diff --git a/vendor/charset_normalizer/__init__.py b/vendor/charset_normalizer/__init__.py index ebb5da8..55991fc 100644 --- a/vendor/charset_normalizer/__init__.py +++ b/vendor/charset_normalizer/__init__.py @@ -21,7 +21,7 @@ """ import logging -from .api import from_bytes, from_fp, from_path +from .api import from_bytes, from_fp, from_path, is_binary from .legacy import detect from .models import CharsetMatch, CharsetMatches from .utils import set_logging_handler @@ -31,6 +31,7 @@ "from_fp", "from_path", "from_bytes", + "is_binary", "detect", "CharsetMatch", "CharsetMatches", diff --git a/vendor/charset_normalizer/__main__.py b/vendor/charset_normalizer/__main__.py new file mode 100644 index 0000000..beae2ef --- /dev/null +++ b/vendor/charset_normalizer/__main__.py @@ -0,0 +1,4 @@ +from .cli import cli_detect + +if __name__ == "__main__": + cli_detect() diff --git a/vendor/charset_normalizer/api.py b/vendor/charset_normalizer/api.py index 9dbf420..e3f2283 100644 --- a/vendor/charset_normalizer/api.py +++ b/vendor/charset_normalizer/api.py @@ -1,6 +1,6 @@ import logging from os import PathLike -from typing import Any, BinaryIO, List, Optional, Set +from typing import BinaryIO, List, Optional, Set, Union from .cd import ( coherence_ratio, @@ -31,7 +31,7 @@ def from_bytes( - sequences: bytes, + sequences: Union[bytes, bytearray], steps: int = 5, chunk_size: int = 512, threshold: float = 0.2, @@ -40,6 +40,7 @@ def from_bytes( preemptive_behaviour: bool = True, explain: bool = False, language_threshold: float = 0.1, + enable_fallback: bool = True, ) -> CharsetMatches: """ Given a raw bytes sequence, return the best possibles charset usable to render str objects. @@ -158,6 +159,8 @@ def from_bytes( results: CharsetMatches = CharsetMatches() + early_stop_results: CharsetMatches = CharsetMatches() + sig_encoding, sig_payload = identify_sig_or_bom(sequences) if sig_encoding is not None: @@ -220,16 +223,20 @@ def from_bytes( try: if is_too_large_sequence and is_multi_byte_decoder is False: str( - sequences[: int(50e4)] - if strip_sig_or_bom is False - else sequences[len(sig_payload) : int(50e4)], + ( + sequences[: int(50e4)] + if strip_sig_or_bom is False + else sequences[len(sig_payload) : int(50e4)] + ), encoding=encoding_iana, ) else: decoded_payload = str( - sequences - if strip_sig_or_bom is False - else sequences[len(sig_payload) :], + ( + sequences + if strip_sig_or_bom is False + else sequences[len(sig_payload) :] + ), encoding=encoding_iana, ) except (UnicodeDecodeError, LookupError) as e: @@ -361,11 +368,18 @@ def from_bytes( ) # Preparing those fallbacks in case we got nothing. if ( - encoding_iana in ["ascii", "utf_8", specified_encoding] + enable_fallback + and encoding_iana in ["ascii", "utf_8", specified_encoding] and not lazy_str_hard_failure ): fallback_entry = CharsetMatch( - sequences, encoding_iana, threshold, False, [], decoded_payload + sequences, + encoding_iana, + threshold, + False, + [], + decoded_payload, + preemptive_declaration=specified_encoding, ) if encoding_iana == specified_encoding: fallback_specified = fallback_entry @@ -419,28 +433,58 @@ def from_bytes( ), ) - results.append( - CharsetMatch( - sequences, - encoding_iana, - mean_mess_ratio, - bom_or_sig_available, - cd_ratios_merged, - decoded_payload, - ) + current_match = CharsetMatch( + sequences, + encoding_iana, + mean_mess_ratio, + bom_or_sig_available, + cd_ratios_merged, + ( + decoded_payload + if ( + is_too_large_sequence is False + or encoding_iana in [specified_encoding, "ascii", "utf_8"] + ) + else None + ), + preemptive_declaration=specified_encoding, ) + results.append(current_match) + if ( encoding_iana in [specified_encoding, "ascii", "utf_8"] and mean_mess_ratio < 0.1 ): + # If md says nothing to worry about, then... stop immediately! + if mean_mess_ratio == 0.0: + logger.debug( + "Encoding detection: %s is most likely the one.", + current_match.encoding, + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([current_match]) + + early_stop_results.append(current_match) + + if ( + len(early_stop_results) + and (specified_encoding is None or specified_encoding in tested) + and "ascii" in tested + and "utf_8" in tested + ): + probable_result: CharsetMatch = early_stop_results.best() # type: ignore[assignment] logger.debug( - "Encoding detection: %s is most likely the one.", encoding_iana + "Encoding detection: %s is most likely the one.", + probable_result.encoding, ) if explain: logger.removeHandler(explain_handler) logger.setLevel(previous_logger_level) - return CharsetMatches([results[encoding_iana]]) + + return CharsetMatches([probable_result]) if encoding_iana == sig_encoding: logger.debug( @@ -507,6 +551,7 @@ def from_fp( preemptive_behaviour: bool = True, explain: bool = False, language_threshold: float = 0.1, + enable_fallback: bool = True, ) -> CharsetMatches: """ Same thing than the function from_bytes but using a file pointer that is already ready. @@ -522,11 +567,12 @@ def from_fp( preemptive_behaviour, explain, language_threshold, + enable_fallback, ) def from_path( - path: "PathLike[Any]", + path: Union[str, bytes, PathLike], # type: ignore[type-arg] steps: int = 5, chunk_size: int = 512, threshold: float = 0.20, @@ -535,6 +581,7 @@ def from_path( preemptive_behaviour: bool = True, explain: bool = False, language_threshold: float = 0.1, + enable_fallback: bool = True, ) -> CharsetMatches: """ Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. @@ -551,4 +598,71 @@ def from_path( preemptive_behaviour, explain, language_threshold, + enable_fallback, ) + + +def is_binary( + fp_or_path_or_payload: Union[PathLike, str, BinaryIO, bytes], # type: ignore[type-arg] + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.20, + cp_isolation: Optional[List[str]] = None, + cp_exclusion: Optional[List[str]] = None, + preemptive_behaviour: bool = True, + explain: bool = False, + language_threshold: float = 0.1, + enable_fallback: bool = False, +) -> bool: + """ + Detect if the given input (file, bytes, or path) points to a binary file. aka. not a string. + Based on the same main heuristic algorithms and default kwargs at the sole exception that fallbacks match + are disabled to be stricter around ASCII-compatible but unlikely to be a string. + """ + if isinstance(fp_or_path_or_payload, (str, PathLike)): + guesses = from_path( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + elif isinstance( + fp_or_path_or_payload, + ( + bytes, + bytearray, + ), + ): + guesses = from_bytes( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + else: + guesses = from_fp( + fp_or_path_or_payload, + steps=steps, + chunk_size=chunk_size, + threshold=threshold, + cp_isolation=cp_isolation, + cp_exclusion=cp_exclusion, + preemptive_behaviour=preemptive_behaviour, + explain=explain, + language_threshold=language_threshold, + enable_fallback=enable_fallback, + ) + + return not guesses diff --git a/vendor/charset_normalizer/assets/__init__.py b/vendor/charset_normalizer/assets/__init__.py deleted file mode 100644 index 9075930..0000000 --- a/vendor/charset_normalizer/assets/__init__.py +++ /dev/null @@ -1,1440 +0,0 @@ -# -*- coding: utf-8 -*- -from typing import Dict, List - -# Language label that contain the em dash "—" -# character are to be considered alternative seq to origin -FREQUENCIES: Dict[str, List[str]] = { - "English": [ - "e", - "a", - "t", - "i", - "o", - "n", - "s", - "r", - "h", - "l", - "d", - "c", - "u", - "m", - "f", - "p", - "g", - "w", - "y", - "b", - "v", - "k", - "x", - "j", - "z", - "q", - ], - "English—": [ - "e", - "a", - "t", - "i", - "o", - "n", - "s", - "r", - "h", - "l", - "d", - "c", - "m", - "u", - "f", - "p", - "g", - "w", - "b", - "y", - "v", - "k", - "j", - "x", - "z", - "q", - ], - "German": [ - "e", - "n", - "i", - "r", - "s", - "t", - "a", - "d", - "h", - "u", - "l", - "g", - "o", - "c", - "m", - "b", - "f", - "k", - "w", - "z", - "p", - "v", - "ü", - "Ƥ", - "ƶ", - "j", - ], - "French": [ - "e", - "a", - "s", - "n", - "i", - "t", - "r", - "l", - "u", - "o", - "d", - "c", - "p", - "m", - "Ć©", - "v", - "g", - "f", - "b", - "h", - "q", - "Ć ", - "x", - "ĆØ", - "y", - "j", - ], - "Dutch": [ - "e", - "n", - "a", - "i", - "r", - "t", - "o", - "d", - "s", - "l", - "g", - "h", - "v", - "m", - "u", - "k", - "c", - "p", - "b", - "w", - "j", - "z", - "f", - "y", - "x", - "Ć«", - ], - "Italian": [ - "e", - "i", - "a", - "o", - "n", - "l", - "t", - "r", - "s", - "c", - "d", - "u", - "p", - "m", - "g", - "v", - "f", - "b", - "z", - "h", - "q", - "ĆØ", - "Ć ", - "k", - "y", - "ò", - ], - "Polish": [ - "a", - "i", - "o", - "e", - "n", - "r", - "z", - "w", - "s", - "c", - "t", - "k", - "y", - "d", - "p", - "m", - "u", - "l", - "j", - "ł", - "g", - "b", - "h", - "ą", - "ę", - "ó", - ], - "Spanish": [ - "e", - "a", - "o", - "n", - "s", - "r", - "i", - "l", - "d", - "t", - "c", - "u", - "m", - "p", - "b", - "g", - "v", - "f", - "y", - "ó", - "h", - "q", - "Ć­", - "j", - "z", - "Ć”", - ], - "Russian": [ - "о", - "а", - "е", - "Šø", - "н", - "с", - "т", - "р", - "в", - "Š»", - "Šŗ", - "м", - "Š“", - "Šæ", - "у", - "г", - "я", - "ы", - "Š·", - "б", - "й", - "ь", - "ч", - "х", - "ж", - "ц", - ], - # Jap-Kanji - "Japanese": [ - "äŗŗ", - "äø€", - "大", - "äŗ…", - "丁", - "äøØ", - "竹", - "笑", - "口", - "ę—„", - "今", - "二", - "å½³", - "蔌", - "十", - "土", - "äø¶", - "寸", - "寺", - "Ꙃ", - "乙", - "äøæ", - "乂", - "갔", - "갗", - "冂", - "å·¾", - "äŗ ", - "åø‚", - "ē›®", - "儿", - "見", - "八", - "小", - "凵", - "県", - "月", - "彐", - "門", - "間", - "木", - "ę±", - "å±±", - "出", - "本", - "äø­", - "刀", - "分", - "耳", - "又", - "取", - "꜀", - "言", - "ē”°", - "心", - "ꀝ", - "刂", - "前", - "äŗ¬", - "å°¹", - "äŗ‹", - "ē”Ÿ", - "厶", - "äŗ‘", - "会", - "未", - "ę„", - "白", - "冫", - "愽", - "灬", - "馬", - "å°ø", - "å°ŗ", - "駅", - "꘎", - "耂", - "者", - "äŗ†", - "阝", - "都", - "高", - "卜", - "占", - "厂", - "广", - "åŗ—", - "子", - "申", - "å„„", - "äŗ»", - "äæŗ", - "上", - "ę–¹", - "冖", - "å­¦", - "蔣", - "艮", - "食", - "自", - ], - # Jap-Katakana - "Japanese—": [ - "ー", - "ン", - "ス", - "惻", - "惫", - "惈", - "リ", - "悤", - "ć‚¢", - "惩", - "惃", - "ク", - "惉", - "ć‚·", - "惬", - "ジ", - "タ", - "惕", - "惭", - "ć‚«", - "惆", - "惞", - "ć‚£", - "悰", - "惐", - "惠", - "惗", - "オ", - "コ", - "惇", - "惋", - "悦", - "惔", - "悵", - "惓", - "ナ", - "惖", - "ャ", - "エ", - "惄", - "惁", - "悭", - "ズ", - "惀", - "惑", - "ミ", - "悧", - "惧", - "惏", - "ć‚»", - "惙", - "悬", - "モ", - "惄", - "惍", - "ボ", - "ソ", - "惎", - "ć‚”", - "惓", - "ワ", - "惝", - "ペ", - "惔", - "悱", - "ć‚“", - "ć‚®", - "ć‚¶", - "惛", - "ゲ", - "ć‚©", - "惤", - "惒", - "惦", - "ヨ", - "惘", - "ゼ", - "ヌ", - "ć‚„", - "ゾ", - "惶", - "惂", - "ヲ", - "情", - "惵", - "惱", - "惰", - "惮", - "ヽ", - "悠", - "ヾ", - "惷", - "ヿ", - "ヸ", - "ヹ", - "ヺ", - ], - # Jap-Hiragana - "Japanese——": [ - "恮", - "恫", - "悋", - "た", - "と", - "は", - "恗", - "恄", - "悒", - "恧", - "恦", - "が", - "な", - "悌", - "恋", - "悉", - "恕", - "っ", - "悊", - "恙", - "恂", - "悂", - "恓", - "ま", - "恆", - "恏", - "悈", - "恍", - "悓", - "悁", - "お", - "恑", - "恝", - "恤", - "恠", - "悄", - "恈", - "恩", - "悏", - "恔", - "み", - "恛", - "恘", - "恰", - "へ", - "び", - "ず", - "悍", - "恻", - "恒", - "悀", - "べ", - "ひ", - "悇", - "悆", - "恶", - "恔", - "悃", - "恭", - "恵", - "恐", - "恎", - "ぼ", - "悅", - "恄", - "恖", - "恞", - "恬", - "ぜ", - "恱", - "ぽ", - "恷", - "恓", - "恃", - "恁", - "恇", - "ぺ", - "悞", - "ぢ", - "恉", - "恅", - "悐", - "悝", - "悑", - "悛", - "悜", - "悎", - "悔", - "悚", - "悟", - "悙", - "悕", - "悖", - ], - "Portuguese": [ - "a", - "e", - "o", - "s", - "i", - "r", - "d", - "n", - "t", - "m", - "u", - "c", - "l", - "p", - "g", - "v", - "b", - "f", - "h", - "Ć£", - "q", - "Ć©", - "Ƨ", - "Ć”", - "z", - "Ć­", - ], - "Swedish": [ - "e", - "a", - "n", - "r", - "t", - "s", - "i", - "l", - "d", - "o", - "m", - "k", - "g", - "v", - "h", - "f", - "u", - "p", - "Ƥ", - "c", - "b", - "ƶ", - "Ć„", - "y", - "j", - "x", - ], - "Chinese": [ - "ēš„", - "äø€", - "是", - "äø", - "äŗ†", - "在", - "äŗŗ", - "꜉", - "ꈑ", - "他", - "čæ™", - "äøŖ", - "们", - "äø­", - "ę„", - "上", - "大", - "äøŗ", - "和", - "国", - "地", - "到", - "仄", - "诓", - "ę—¶", - "要", - "å°±", - "出", - "会", - "åÆ", - "也", - "ä½ ", - "对", - "ē”Ÿ", - "能", - "而", - "子", - "那", - "得", - "äŗŽ", - "ē€", - "äø‹", - "自", - "之", - "幓", - "过", - "发", - "后", - "作", - "里", - "用", - "道", - "蔌", - "ꉀ", - "ē„¶", - "å®¶", - "ē§", - "äŗ‹", - "ꈐ", - "ę–¹", - "多", - "ē»", - "么", - "去", - "法", - "å­¦", - "如", - "都", - "同", - "ēŽ°", - "当", - "ę²”", - "动", - "面", - "čµ·", - "ēœ‹", - "定", - "天", - "分", - "还", - "čæ›", - "儽", - "小", - "部", - "其", - "äŗ›", - "äø»", - "ę ·", - "理", - "心", - "儹", - "本", - "前", - "开", - "但", - "因", - "åŖ", - "从", - "想", - "实", - ], - "Ukrainian": [ - "о", - "а", - "н", - "і", - "Šø", - "р", - "в", - "т", - "е", - "с", - "Šŗ", - "Š»", - "у", - "Š“", - "м", - "Šæ", - "Š·", - "я", - "ь", - "б", - "г", - "й", - "ч", - "х", - "ц", - "ї", - ], - "Norwegian": [ - "e", - "r", - "n", - "t", - "a", - "s", - "i", - "o", - "l", - "d", - "g", - "k", - "m", - "v", - "f", - "p", - "u", - "b", - "h", - "Ć„", - "y", - "j", - "Ćø", - "c", - "Ʀ", - "w", - ], - "Finnish": [ - "a", - "i", - "n", - "t", - "e", - "s", - "l", - "o", - "u", - "k", - "Ƥ", - "m", - "r", - "v", - "j", - "h", - "p", - "y", - "d", - "ƶ", - "g", - "c", - "b", - "f", - "w", - "z", - ], - "Vietnamese": [ - "n", - "h", - "t", - "i", - "c", - "g", - "a", - "o", - "u", - "m", - "l", - "r", - "Ć ", - "đ", - "s", - "e", - "v", - "p", - "b", - "y", - "ʰ", - "d", - "Ć”", - "k", - "į»™", - "įŗæ", - ], - "Czech": [ - "o", - "e", - "a", - "n", - "t", - "s", - "i", - "l", - "v", - "r", - "k", - "d", - "u", - "m", - "p", - "Ć­", - "c", - "h", - "z", - "Ć”", - "y", - "j", - "b", - "ě", - "Ć©", - "ř", - ], - "Hungarian": [ - "e", - "a", - "t", - "l", - "s", - "n", - "k", - "r", - "i", - "o", - "z", - "Ć”", - "Ć©", - "g", - "m", - "b", - "y", - "v", - "d", - "h", - "u", - "p", - "j", - "ƶ", - "f", - "c", - ], - "Korean": [ - "ģ“", - "다", - "에", - "ģ˜", - "ėŠ”", - "딜", - "ķ•˜", - "ģ„", - "ź°€", - "ź³ ", - "ģ§€", - "ģ„œ", - "ķ•œ", - "ģ€", - "źø°", - "으", - "ė…„", - "ėŒ€", - "사", - "ģ‹œ", - "넼", - "리", - "ė„", - "ģø", - "스", - "ģ¼", - ], - "Indonesian": [ - "a", - "n", - "e", - "i", - "r", - "t", - "u", - "s", - "d", - "k", - "m", - "l", - "g", - "p", - "b", - "o", - "h", - "y", - "j", - "c", - "w", - "f", - "v", - "z", - "x", - "q", - ], - "Turkish": [ - "a", - "e", - "i", - "n", - "r", - "l", - "ı", - "k", - "d", - "t", - "s", - "m", - "y", - "u", - "o", - "b", - "ü", - "ş", - "v", - "g", - "z", - "h", - "c", - "p", - "Ƨ", - "ğ", - ], - "Romanian": [ - "e", - "i", - "a", - "r", - "n", - "t", - "u", - "l", - "o", - "c", - "s", - "d", - "p", - "m", - "ă", - "f", - "v", - "Ć®", - "g", - "b", - "ș", - "ț", - "z", - "h", - "Ć¢", - "j", - ], - "Farsi": [ - "Ų§", - "ی", - "Ų±", - "ŲÆ", - "ن", - "ه", - "و", - "Ł…", - "ŲŖ", - "ŲØ", - "Ų³", - "Ł„", - "Ś©", - "Ų“", - "Ų²", - "ف", - "ŚÆ", - "Ų¹", - "Ų®", - "Ł‚", - "Ų¬", - "Ų¢", - "پ", - "Ų­", - "Ų·", - "Ųµ", - ], - "Arabic": [ - "Ų§", - "Ł„", - "ي", - "Ł…", - "و", - "ن", - "Ų±", - "ŲŖ", - "ŲØ", - "Ų©", - "Ų¹", - "ŲÆ", - "Ų³", - "ف", - "ه", - "ك", - "Ł‚", - "Ų£", - "Ų­", - "Ų¬", - "Ų“", - "Ų·", - "Ųµ", - "ى", - "Ų®", - "Ų„", - ], - "Danish": [ - "e", - "r", - "n", - "t", - "a", - "i", - "s", - "d", - "l", - "o", - "g", - "m", - "k", - "f", - "v", - "u", - "b", - "h", - "p", - "Ć„", - "y", - "Ćø", - "Ʀ", - "c", - "j", - "w", - ], - "Serbian": [ - "а", - "Šø", - "о", - "е", - "н", - "р", - "с", - "у", - "т", - "Šŗ", - "ј", - "в", - "Š“", - "м", - "Šæ", - "Š»", - "г", - "Š·", - "б", - "a", - "i", - "e", - "o", - "n", - "ц", - "ш", - ], - "Lithuanian": [ - "i", - "a", - "s", - "o", - "r", - "e", - "t", - "n", - "u", - "k", - "m", - "l", - "p", - "v", - "d", - "j", - "g", - "ė", - "b", - "y", - "ų", - "Å”", - "ž", - "c", - "ą", - "ÄÆ", - ], - "Slovene": [ - "e", - "a", - "i", - "o", - "n", - "r", - "s", - "l", - "t", - "j", - "v", - "k", - "d", - "p", - "m", - "u", - "z", - "b", - "g", - "h", - "č", - "c", - "Å”", - "ž", - "f", - "y", - ], - "Slovak": [ - "o", - "a", - "e", - "n", - "i", - "r", - "v", - "t", - "s", - "l", - "k", - "d", - "m", - "p", - "u", - "c", - "h", - "j", - "b", - "z", - "Ć”", - "y", - "ý", - "Ć­", - "č", - "Ć©", - ], - "Hebrew": [ - "י", - "ו", - "ה", - "ל", - "ר", - "ב", - "×Ŗ", - "מ", - "א", - "ש", - "× ", - "×¢", - "ם", - "ד", - "×§", - "ח", - "פ", - "×”", - "כ", - "ג", - "ט", - "צ", - "ן", - "ז", - "ך", - ], - "Bulgarian": [ - "а", - "Šø", - "о", - "е", - "н", - "т", - "р", - "с", - "в", - "Š»", - "Šŗ", - "Š“", - "Šæ", - "м", - "Š·", - "г", - "я", - "ъ", - "у", - "б", - "ч", - "ц", - "й", - "ж", - "щ", - "х", - ], - "Croatian": [ - "a", - "i", - "o", - "e", - "n", - "r", - "j", - "s", - "t", - "u", - "k", - "l", - "v", - "d", - "m", - "p", - "g", - "z", - "b", - "c", - "č", - "h", - "Å”", - "ž", - "ć", - "f", - ], - "Hindi": [ - "क", - "र", - "स", - "न", - "त", - "म", - "ह", - "प", - "य", - "ल", - "व", - "ज", - "द", - "ग", - "ब", - "श", - "ट", - "अ", - "ą¤", - "ऄ", - "भ", - "औ", - "च", - "ध", - "ष", - "इ", - ], - "Estonian": [ - "a", - "i", - "e", - "s", - "t", - "l", - "u", - "n", - "o", - "k", - "r", - "d", - "m", - "v", - "g", - "p", - "j", - "h", - "Ƥ", - "b", - "Ƶ", - "ü", - "f", - "c", - "ƶ", - "y", - ], - "Thai": [ - "ąø²", - "ąø™", - "ąø£", - "ąø­", - "ก", - "ą¹€", - "ąø‡", - "ąø”", - "ąø¢", - "ąø„", - "ąø§", - "ąø”", - "ąø—", - "ąøŖ", - "ąø•", - "ąø°", - "ąø›", - "บ", - "ąø„", - "ąø«", - "แ", - "จ", - "ąøž", - "ช", - "ąø‚", - "ใ", - ], - "Greek": [ - "α", - "Ļ„", - "Īæ", - "ι", - "ε", - "ν", - "ρ", - "σ", - "Īŗ", - "Ī·", - "Ļ€", - "Ļ‚", - "Ļ…", - "μ", - "Ī»", - "ĪÆ", - "ό", - "ά", - "γ", - "Ī­", - "Ī“", - "Ī®", - "ω", - "χ", - "Īø", - "Ļ", - ], - "Tamil": [ - "க", - "த", - "ப", - "ட", - "ą®°", - "ą®®", - "ல", - "ன", - "வ", - "ą®±", - "ய", - "ள", - "ச", - "ந", - "இ", - "ண", - "ą®…", - "ஆ", - "ஓ", - "ą®™", - "ą®Ž", - "உ", - "ą®’", - "ஸ", - ], - "Kazakh": [ - "а", - "ы", - "е", - "н", - "т", - "р", - "Š»", - "і", - "Š“", - "с", - "м", - "Ņ›", - "Šŗ", - "о", - "б", - "Šø", - "у", - "Ņ“", - "ж", - "Ņ£", - "Š·", - "ш", - "й", - "Šæ", - "г", - "Ó©", - ], -} diff --git a/vendor/charset_normalizer/cd.py b/vendor/charset_normalizer/cd.py index 6e56fe8..4ea6760 100644 --- a/vendor/charset_normalizer/cd.py +++ b/vendor/charset_normalizer/cd.py @@ -4,8 +4,13 @@ from functools import lru_cache from typing import Counter as TypeCounter, Dict, List, Optional, Tuple -from .assets import FREQUENCIES -from .constant import KO_NAMES, LANGUAGE_SUPPORTED_COUNT, TOO_SMALL_SEQUENCE, ZH_NAMES +from .constant import ( + FREQUENCIES, + KO_NAMES, + LANGUAGE_SUPPORTED_COUNT, + TOO_SMALL_SEQUENCE, + ZH_NAMES, +) from .md import is_suspiciously_successive_range from .models import CoherenceMatches from .utils import ( diff --git a/vendor/charset_normalizer/cli/__init__.py b/vendor/charset_normalizer/cli/__init__.py index e69de29..d95fedf 100644 --- a/vendor/charset_normalizer/cli/__init__.py +++ b/vendor/charset_normalizer/cli/__init__.py @@ -0,0 +1,6 @@ +from .__main__ import cli_detect, query_yes_no + +__all__ = ( + "cli_detect", + "query_yes_no", +) diff --git a/vendor/charset_normalizer/cli/normalizer.py b/vendor/charset_normalizer/cli/__main__.py similarity index 90% rename from vendor/charset_normalizer/cli/normalizer.py rename to vendor/charset_normalizer/cli/__main__.py index f4bcbaa..e7edd0f 100644 --- a/vendor/charset_normalizer/cli/normalizer.py +++ b/vendor/charset_normalizer/cli/__main__.py @@ -109,6 +109,14 @@ def cli_detect(argv: Optional[List[str]] = None) -> int: dest="force", help="Replace file without asking if you are sure, use this flag with caution.", ) + parser.add_argument( + "-i", + "--no-preemptive", + action="store_true", + default=False, + dest="no_preemptive", + help="Disable looking at a charset declaration to hint the detector.", + ) parser.add_argument( "-t", "--threshold", @@ -133,21 +141,35 @@ def cli_detect(argv: Optional[List[str]] = None) -> int: args = parser.parse_args(argv) if args.replace is True and args.normalize is False: + if args.files: + for my_file in args.files: + my_file.close() print("Use --replace in addition of --normalize only.", file=sys.stderr) return 1 if args.force is True and args.replace is False: + if args.files: + for my_file in args.files: + my_file.close() print("Use --force in addition of --replace only.", file=sys.stderr) return 1 if args.threshold < 0.0 or args.threshold > 1.0: + if args.files: + for my_file in args.files: + my_file.close() print("--threshold VALUE should be between 0. AND 1.", file=sys.stderr) return 1 x_ = [] for my_file in args.files: - matches = from_fp(my_file, threshold=args.threshold, explain=args.verbose) + matches = from_fp( + my_file, + threshold=args.threshold, + explain=args.verbose, + preemptive_behaviour=args.no_preemptive is False, + ) best_guess = matches.best() @@ -155,9 +177,11 @@ def cli_detect(argv: Optional[List[str]] = None) -> int: print( 'Unable to identify originating encoding for "{}". {}'.format( my_file.name, - "Maybe try increasing maximum amount of chaos." - if args.threshold < 1.0 - else "", + ( + "Maybe try increasing maximum amount of chaos." + if args.threshold < 1.0 + else "" + ), ), file=sys.stderr, ) @@ -258,8 +282,8 @@ def cli_detect(argv: Optional[List[str]] = None) -> int: try: x_[0].unicode_path = join(dir_path, ".".join(o_)) - with open(x_[0].unicode_path, "w", encoding="utf-8") as fp: - fp.write(str(best_guess)) + with open(x_[0].unicode_path, "wb") as fp: + fp.write(best_guess.output()) except IOError as e: print(str(e), file=sys.stderr) if my_file.closed is False: diff --git a/vendor/charset_normalizer/constant.py b/vendor/charset_normalizer/constant.py index 3188108..f8f2a81 100644 --- a/vendor/charset_normalizer/constant.py +++ b/vendor/charset_normalizer/constant.py @@ -1,10 +1,9 @@ +# -*- coding: utf-8 -*- from codecs import BOM_UTF8, BOM_UTF16_BE, BOM_UTF16_LE, BOM_UTF32_BE, BOM_UTF32_LE from encodings.aliases import aliases from re import IGNORECASE, compile as re_compile from typing import Dict, List, Set, Union -from .assets import FREQUENCIES - # Contain for each eligible encoding a list of/item bytes SIG/BOM ENCODING_MARKS: Dict[str, Union[bytes, List[bytes]]] = { "utf_8": BOM_UTF8, @@ -23,288 +22,338 @@ TOO_SMALL_SEQUENCE: int = 32 TOO_BIG_SEQUENCE: int = int(10e6) -UTF8_MAXIMAL_ALLOCATION: int = 1112064 +UTF8_MAXIMAL_ALLOCATION: int = 1_112_064 +# Up-to-date Unicode ucd/15.0.0 UNICODE_RANGES_COMBINED: Dict[str, range] = { - "Control character": range(31 + 1), - "Basic Latin": range(32, 127 + 1), - "Latin-1 Supplement": range(128, 255 + 1), - "Latin Extended-A": range(256, 383 + 1), - "Latin Extended-B": range(384, 591 + 1), - "IPA Extensions": range(592, 687 + 1), - "Spacing Modifier Letters": range(688, 767 + 1), - "Combining Diacritical Marks": range(768, 879 + 1), - "Greek and Coptic": range(880, 1023 + 1), - "Cyrillic": range(1024, 1279 + 1), - "Cyrillic Supplement": range(1280, 1327 + 1), - "Armenian": range(1328, 1423 + 1), - "Hebrew": range(1424, 1535 + 1), - "Arabic": range(1536, 1791 + 1), - "Syriac": range(1792, 1871 + 1), - "Arabic Supplement": range(1872, 1919 + 1), - "Thaana": range(1920, 1983 + 1), - "NKo": range(1984, 2047 + 1), - "Samaritan": range(2048, 2111 + 1), - "Mandaic": range(2112, 2143 + 1), - "Syriac Supplement": range(2144, 2159 + 1), - "Arabic Extended-A": range(2208, 2303 + 1), - "Devanagari": range(2304, 2431 + 1), - "Bengali": range(2432, 2559 + 1), - "Gurmukhi": range(2560, 2687 + 1), - "Gujarati": range(2688, 2815 + 1), - "Oriya": range(2816, 2943 + 1), - "Tamil": range(2944, 3071 + 1), - "Telugu": range(3072, 3199 + 1), - "Kannada": range(3200, 3327 + 1), - "Malayalam": range(3328, 3455 + 1), - "Sinhala": range(3456, 3583 + 1), - "Thai": range(3584, 3711 + 1), - "Lao": range(3712, 3839 + 1), - "Tibetan": range(3840, 4095 + 1), - "Myanmar": range(4096, 4255 + 1), - "Georgian": range(4256, 4351 + 1), - "Hangul Jamo": range(4352, 4607 + 1), - "Ethiopic": range(4608, 4991 + 1), - "Ethiopic Supplement": range(4992, 5023 + 1), - "Cherokee": range(5024, 5119 + 1), - "Unified Canadian Aboriginal Syllabics": range(5120, 5759 + 1), - "Ogham": range(5760, 5791 + 1), - "Runic": range(5792, 5887 + 1), - "Tagalog": range(5888, 5919 + 1), - "Hanunoo": range(5920, 5951 + 1), - "Buhid": range(5952, 5983 + 1), - "Tagbanwa": range(5984, 6015 + 1), - "Khmer": range(6016, 6143 + 1), - "Mongolian": range(6144, 6319 + 1), - "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6399 + 1), - "Limbu": range(6400, 6479 + 1), - "Tai Le": range(6480, 6527 + 1), - "New Tai Lue": range(6528, 6623 + 1), - "Khmer Symbols": range(6624, 6655 + 1), - "Buginese": range(6656, 6687 + 1), - "Tai Tham": range(6688, 6831 + 1), - "Combining Diacritical Marks Extended": range(6832, 6911 + 1), - "Balinese": range(6912, 7039 + 1), - "Sundanese": range(7040, 7103 + 1), - "Batak": range(7104, 7167 + 1), - "Lepcha": range(7168, 7247 + 1), - "Ol Chiki": range(7248, 7295 + 1), - "Cyrillic Extended C": range(7296, 7311 + 1), - "Sundanese Supplement": range(7360, 7375 + 1), - "Vedic Extensions": range(7376, 7423 + 1), - "Phonetic Extensions": range(7424, 7551 + 1), - "Phonetic Extensions Supplement": range(7552, 7615 + 1), - "Combining Diacritical Marks Supplement": range(7616, 7679 + 1), - "Latin Extended Additional": range(7680, 7935 + 1), - "Greek Extended": range(7936, 8191 + 1), - "General Punctuation": range(8192, 8303 + 1), - "Superscripts and Subscripts": range(8304, 8351 + 1), - "Currency Symbols": range(8352, 8399 + 1), - "Combining Diacritical Marks for Symbols": range(8400, 8447 + 1), - "Letterlike Symbols": range(8448, 8527 + 1), - "Number Forms": range(8528, 8591 + 1), - "Arrows": range(8592, 8703 + 1), - "Mathematical Operators": range(8704, 8959 + 1), - "Miscellaneous Technical": range(8960, 9215 + 1), - "Control Pictures": range(9216, 9279 + 1), - "Optical Character Recognition": range(9280, 9311 + 1), - "Enclosed Alphanumerics": range(9312, 9471 + 1), - "Box Drawing": range(9472, 9599 + 1), - "Block Elements": range(9600, 9631 + 1), - "Geometric Shapes": range(9632, 9727 + 1), - "Miscellaneous Symbols": range(9728, 9983 + 1), - "Dingbats": range(9984, 10175 + 1), - "Miscellaneous Mathematical Symbols-A": range(10176, 10223 + 1), - "Supplemental Arrows-A": range(10224, 10239 + 1), - "Braille Patterns": range(10240, 10495 + 1), - "Supplemental Arrows-B": range(10496, 10623 + 1), - "Miscellaneous Mathematical Symbols-B": range(10624, 10751 + 1), - "Supplemental Mathematical Operators": range(10752, 11007 + 1), - "Miscellaneous Symbols and Arrows": range(11008, 11263 + 1), - "Glagolitic": range(11264, 11359 + 1), - "Latin Extended-C": range(11360, 11391 + 1), - "Coptic": range(11392, 11519 + 1), - "Georgian Supplement": range(11520, 11567 + 1), - "Tifinagh": range(11568, 11647 + 1), - "Ethiopic Extended": range(11648, 11743 + 1), - "Cyrillic Extended-A": range(11744, 11775 + 1), - "Supplemental Punctuation": range(11776, 11903 + 1), - "CJK Radicals Supplement": range(11904, 12031 + 1), - "Kangxi Radicals": range(12032, 12255 + 1), - "Ideographic Description Characters": range(12272, 12287 + 1), - "CJK Symbols and Punctuation": range(12288, 12351 + 1), - "Hiragana": range(12352, 12447 + 1), - "Katakana": range(12448, 12543 + 1), - "Bopomofo": range(12544, 12591 + 1), - "Hangul Compatibility Jamo": range(12592, 12687 + 1), - "Kanbun": range(12688, 12703 + 1), - "Bopomofo Extended": range(12704, 12735 + 1), - "CJK Strokes": range(12736, 12783 + 1), - "Katakana Phonetic Extensions": range(12784, 12799 + 1), - "Enclosed CJK Letters and Months": range(12800, 13055 + 1), - "CJK Compatibility": range(13056, 13311 + 1), - "CJK Unified Ideographs Extension A": range(13312, 19903 + 1), - "Yijing Hexagram Symbols": range(19904, 19967 + 1), - "CJK Unified Ideographs": range(19968, 40959 + 1), - "Yi Syllables": range(40960, 42127 + 1), - "Yi Radicals": range(42128, 42191 + 1), - "Lisu": range(42192, 42239 + 1), - "Vai": range(42240, 42559 + 1), - "Cyrillic Extended-B": range(42560, 42655 + 1), - "Bamum": range(42656, 42751 + 1), - "Modifier Tone Letters": range(42752, 42783 + 1), - "Latin Extended-D": range(42784, 43007 + 1), - "Syloti Nagri": range(43008, 43055 + 1), - "Common Indic Number Forms": range(43056, 43071 + 1), - "Phags-pa": range(43072, 43135 + 1), - "Saurashtra": range(43136, 43231 + 1), - "Devanagari Extended": range(43232, 43263 + 1), - "Kayah Li": range(43264, 43311 + 1), - "Rejang": range(43312, 43359 + 1), - "Hangul Jamo Extended-A": range(43360, 43391 + 1), - "Javanese": range(43392, 43487 + 1), - "Myanmar Extended-B": range(43488, 43519 + 1), - "Cham": range(43520, 43615 + 1), - "Myanmar Extended-A": range(43616, 43647 + 1), - "Tai Viet": range(43648, 43743 + 1), - "Meetei Mayek Extensions": range(43744, 43775 + 1), - "Ethiopic Extended-A": range(43776, 43823 + 1), - "Latin Extended-E": range(43824, 43887 + 1), - "Cherokee Supplement": range(43888, 43967 + 1), - "Meetei Mayek": range(43968, 44031 + 1), - "Hangul Syllables": range(44032, 55215 + 1), - "Hangul Jamo Extended-B": range(55216, 55295 + 1), - "High Surrogates": range(55296, 56191 + 1), - "High Private Use Surrogates": range(56192, 56319 + 1), - "Low Surrogates": range(56320, 57343 + 1), - "Private Use Area": range(57344, 63743 + 1), - "CJK Compatibility Ideographs": range(63744, 64255 + 1), - "Alphabetic Presentation Forms": range(64256, 64335 + 1), - "Arabic Presentation Forms-A": range(64336, 65023 + 1), - "Variation Selectors": range(65024, 65039 + 1), - "Vertical Forms": range(65040, 65055 + 1), - "Combining Half Marks": range(65056, 65071 + 1), - "CJK Compatibility Forms": range(65072, 65103 + 1), - "Small Form Variants": range(65104, 65135 + 1), - "Arabic Presentation Forms-B": range(65136, 65279 + 1), - "Halfwidth and Fullwidth Forms": range(65280, 65519 + 1), - "Specials": range(65520, 65535 + 1), - "Linear B Syllabary": range(65536, 65663 + 1), - "Linear B Ideograms": range(65664, 65791 + 1), - "Aegean Numbers": range(65792, 65855 + 1), - "Ancient Greek Numbers": range(65856, 65935 + 1), - "Ancient Symbols": range(65936, 65999 + 1), - "Phaistos Disc": range(66000, 66047 + 1), - "Lycian": range(66176, 66207 + 1), - "Carian": range(66208, 66271 + 1), - "Coptic Epact Numbers": range(66272, 66303 + 1), - "Old Italic": range(66304, 66351 + 1), - "Gothic": range(66352, 66383 + 1), - "Old Permic": range(66384, 66431 + 1), - "Ugaritic": range(66432, 66463 + 1), - "Old Persian": range(66464, 66527 + 1), - "Deseret": range(66560, 66639 + 1), - "Shavian": range(66640, 66687 + 1), - "Osmanya": range(66688, 66735 + 1), - "Osage": range(66736, 66815 + 1), - "Elbasan": range(66816, 66863 + 1), - "Caucasian Albanian": range(66864, 66927 + 1), - "Linear A": range(67072, 67455 + 1), - "Cypriot Syllabary": range(67584, 67647 + 1), - "Imperial Aramaic": range(67648, 67679 + 1), - "Palmyrene": range(67680, 67711 + 1), - "Nabataean": range(67712, 67759 + 1), - "Hatran": range(67808, 67839 + 1), - "Phoenician": range(67840, 67871 + 1), - "Lydian": range(67872, 67903 + 1), - "Meroitic Hieroglyphs": range(67968, 67999 + 1), - "Meroitic Cursive": range(68000, 68095 + 1), - "Kharoshthi": range(68096, 68191 + 1), - "Old South Arabian": range(68192, 68223 + 1), - "Old North Arabian": range(68224, 68255 + 1), - "Manichaean": range(68288, 68351 + 1), - "Avestan": range(68352, 68415 + 1), - "Inscriptional Parthian": range(68416, 68447 + 1), - "Inscriptional Pahlavi": range(68448, 68479 + 1), - "Psalter Pahlavi": range(68480, 68527 + 1), - "Old Turkic": range(68608, 68687 + 1), - "Old Hungarian": range(68736, 68863 + 1), - "Rumi Numeral Symbols": range(69216, 69247 + 1), - "Brahmi": range(69632, 69759 + 1), - "Kaithi": range(69760, 69839 + 1), - "Sora Sompeng": range(69840, 69887 + 1), - "Chakma": range(69888, 69967 + 1), - "Mahajani": range(69968, 70015 + 1), - "Sharada": range(70016, 70111 + 1), - "Sinhala Archaic Numbers": range(70112, 70143 + 1), - "Khojki": range(70144, 70223 + 1), - "Multani": range(70272, 70319 + 1), - "Khudawadi": range(70320, 70399 + 1), - "Grantha": range(70400, 70527 + 1), - "Newa": range(70656, 70783 + 1), - "Tirhuta": range(70784, 70879 + 1), - "Siddham": range(71040, 71167 + 1), - "Modi": range(71168, 71263 + 1), - "Mongolian Supplement": range(71264, 71295 + 1), - "Takri": range(71296, 71375 + 1), - "Ahom": range(71424, 71487 + 1), - "Warang Citi": range(71840, 71935 + 1), - "Zanabazar Square": range(72192, 72271 + 1), - "Soyombo": range(72272, 72367 + 1), - "Pau Cin Hau": range(72384, 72447 + 1), - "Bhaiksuki": range(72704, 72815 + 1), - "Marchen": range(72816, 72895 + 1), - "Masaram Gondi": range(72960, 73055 + 1), - "Cuneiform": range(73728, 74751 + 1), - "Cuneiform Numbers and Punctuation": range(74752, 74879 + 1), - "Early Dynastic Cuneiform": range(74880, 75087 + 1), - "Egyptian Hieroglyphs": range(77824, 78895 + 1), - "Anatolian Hieroglyphs": range(82944, 83583 + 1), - "Bamum Supplement": range(92160, 92735 + 1), - "Mro": range(92736, 92783 + 1), - "Bassa Vah": range(92880, 92927 + 1), - "Pahawh Hmong": range(92928, 93071 + 1), - "Miao": range(93952, 94111 + 1), - "Ideographic Symbols and Punctuation": range(94176, 94207 + 1), - "Tangut": range(94208, 100351 + 1), - "Tangut Components": range(100352, 101119 + 1), - "Kana Supplement": range(110592, 110847 + 1), - "Kana Extended-A": range(110848, 110895 + 1), - "Nushu": range(110960, 111359 + 1), - "Duployan": range(113664, 113823 + 1), - "Shorthand Format Controls": range(113824, 113839 + 1), - "Byzantine Musical Symbols": range(118784, 119039 + 1), - "Musical Symbols": range(119040, 119295 + 1), - "Ancient Greek Musical Notation": range(119296, 119375 + 1), - "Tai Xuan Jing Symbols": range(119552, 119647 + 1), - "Counting Rod Numerals": range(119648, 119679 + 1), - "Mathematical Alphanumeric Symbols": range(119808, 120831 + 1), - "Sutton SignWriting": range(120832, 121519 + 1), - "Glagolitic Supplement": range(122880, 122927 + 1), - "Mende Kikakui": range(124928, 125151 + 1), - "Adlam": range(125184, 125279 + 1), - "Arabic Mathematical Alphabetic Symbols": range(126464, 126719 + 1), - "Mahjong Tiles": range(126976, 127023 + 1), - "Domino Tiles": range(127024, 127135 + 1), - "Playing Cards": range(127136, 127231 + 1), - "Enclosed Alphanumeric Supplement": range(127232, 127487 + 1), - "Enclosed Ideographic Supplement": range(127488, 127743 + 1), - "Miscellaneous Symbols and Pictographs": range(127744, 128511 + 1), - "Emoticons range(Emoji)": range(128512, 128591 + 1), - "Ornamental Dingbats": range(128592, 128639 + 1), - "Transport and Map Symbols": range(128640, 128767 + 1), - "Alchemical Symbols": range(128768, 128895 + 1), - "Geometric Shapes Extended": range(128896, 129023 + 1), - "Supplemental Arrows-C": range(129024, 129279 + 1), - "Supplemental Symbols and Pictographs": range(129280, 129535 + 1), - "CJK Unified Ideographs Extension B": range(131072, 173791 + 1), - "CJK Unified Ideographs Extension C": range(173824, 177983 + 1), - "CJK Unified Ideographs Extension D": range(177984, 178207 + 1), - "CJK Unified Ideographs Extension E": range(178208, 183983 + 1), - "CJK Unified Ideographs Extension F": range(183984, 191471 + 1), - "CJK Compatibility Ideographs Supplement": range(194560, 195103 + 1), - "Tags": range(917504, 917631 + 1), - "Variation Selectors Supplement": range(917760, 917999 + 1), + "Control character": range(32), + "Basic Latin": range(32, 128), + "Latin-1 Supplement": range(128, 256), + "Latin Extended-A": range(256, 384), + "Latin Extended-B": range(384, 592), + "IPA Extensions": range(592, 688), + "Spacing Modifier Letters": range(688, 768), + "Combining Diacritical Marks": range(768, 880), + "Greek and Coptic": range(880, 1024), + "Cyrillic": range(1024, 1280), + "Cyrillic Supplement": range(1280, 1328), + "Armenian": range(1328, 1424), + "Hebrew": range(1424, 1536), + "Arabic": range(1536, 1792), + "Syriac": range(1792, 1872), + "Arabic Supplement": range(1872, 1920), + "Thaana": range(1920, 1984), + "NKo": range(1984, 2048), + "Samaritan": range(2048, 2112), + "Mandaic": range(2112, 2144), + "Syriac Supplement": range(2144, 2160), + "Arabic Extended-B": range(2160, 2208), + "Arabic Extended-A": range(2208, 2304), + "Devanagari": range(2304, 2432), + "Bengali": range(2432, 2560), + "Gurmukhi": range(2560, 2688), + "Gujarati": range(2688, 2816), + "Oriya": range(2816, 2944), + "Tamil": range(2944, 3072), + "Telugu": range(3072, 3200), + "Kannada": range(3200, 3328), + "Malayalam": range(3328, 3456), + "Sinhala": range(3456, 3584), + "Thai": range(3584, 3712), + "Lao": range(3712, 3840), + "Tibetan": range(3840, 4096), + "Myanmar": range(4096, 4256), + "Georgian": range(4256, 4352), + "Hangul Jamo": range(4352, 4608), + "Ethiopic": range(4608, 4992), + "Ethiopic Supplement": range(4992, 5024), + "Cherokee": range(5024, 5120), + "Unified Canadian Aboriginal Syllabics": range(5120, 5760), + "Ogham": range(5760, 5792), + "Runic": range(5792, 5888), + "Tagalog": range(5888, 5920), + "Hanunoo": range(5920, 5952), + "Buhid": range(5952, 5984), + "Tagbanwa": range(5984, 6016), + "Khmer": range(6016, 6144), + "Mongolian": range(6144, 6320), + "Unified Canadian Aboriginal Syllabics Extended": range(6320, 6400), + "Limbu": range(6400, 6480), + "Tai Le": range(6480, 6528), + "New Tai Lue": range(6528, 6624), + "Khmer Symbols": range(6624, 6656), + "Buginese": range(6656, 6688), + "Tai Tham": range(6688, 6832), + "Combining Diacritical Marks Extended": range(6832, 6912), + "Balinese": range(6912, 7040), + "Sundanese": range(7040, 7104), + "Batak": range(7104, 7168), + "Lepcha": range(7168, 7248), + "Ol Chiki": range(7248, 7296), + "Cyrillic Extended-C": range(7296, 7312), + "Georgian Extended": range(7312, 7360), + "Sundanese Supplement": range(7360, 7376), + "Vedic Extensions": range(7376, 7424), + "Phonetic Extensions": range(7424, 7552), + "Phonetic Extensions Supplement": range(7552, 7616), + "Combining Diacritical Marks Supplement": range(7616, 7680), + "Latin Extended Additional": range(7680, 7936), + "Greek Extended": range(7936, 8192), + "General Punctuation": range(8192, 8304), + "Superscripts and Subscripts": range(8304, 8352), + "Currency Symbols": range(8352, 8400), + "Combining Diacritical Marks for Symbols": range(8400, 8448), + "Letterlike Symbols": range(8448, 8528), + "Number Forms": range(8528, 8592), + "Arrows": range(8592, 8704), + "Mathematical Operators": range(8704, 8960), + "Miscellaneous Technical": range(8960, 9216), + "Control Pictures": range(9216, 9280), + "Optical Character Recognition": range(9280, 9312), + "Enclosed Alphanumerics": range(9312, 9472), + "Box Drawing": range(9472, 9600), + "Block Elements": range(9600, 9632), + "Geometric Shapes": range(9632, 9728), + "Miscellaneous Symbols": range(9728, 9984), + "Dingbats": range(9984, 10176), + "Miscellaneous Mathematical Symbols-A": range(10176, 10224), + "Supplemental Arrows-A": range(10224, 10240), + "Braille Patterns": range(10240, 10496), + "Supplemental Arrows-B": range(10496, 10624), + "Miscellaneous Mathematical Symbols-B": range(10624, 10752), + "Supplemental Mathematical Operators": range(10752, 11008), + "Miscellaneous Symbols and Arrows": range(11008, 11264), + "Glagolitic": range(11264, 11360), + "Latin Extended-C": range(11360, 11392), + "Coptic": range(11392, 11520), + "Georgian Supplement": range(11520, 11568), + "Tifinagh": range(11568, 11648), + "Ethiopic Extended": range(11648, 11744), + "Cyrillic Extended-A": range(11744, 11776), + "Supplemental Punctuation": range(11776, 11904), + "CJK Radicals Supplement": range(11904, 12032), + "Kangxi Radicals": range(12032, 12256), + "Ideographic Description Characters": range(12272, 12288), + "CJK Symbols and Punctuation": range(12288, 12352), + "Hiragana": range(12352, 12448), + "Katakana": range(12448, 12544), + "Bopomofo": range(12544, 12592), + "Hangul Compatibility Jamo": range(12592, 12688), + "Kanbun": range(12688, 12704), + "Bopomofo Extended": range(12704, 12736), + "CJK Strokes": range(12736, 12784), + "Katakana Phonetic Extensions": range(12784, 12800), + "Enclosed CJK Letters and Months": range(12800, 13056), + "CJK Compatibility": range(13056, 13312), + "CJK Unified Ideographs Extension A": range(13312, 19904), + "Yijing Hexagram Symbols": range(19904, 19968), + "CJK Unified Ideographs": range(19968, 40960), + "Yi Syllables": range(40960, 42128), + "Yi Radicals": range(42128, 42192), + "Lisu": range(42192, 42240), + "Vai": range(42240, 42560), + "Cyrillic Extended-B": range(42560, 42656), + "Bamum": range(42656, 42752), + "Modifier Tone Letters": range(42752, 42784), + "Latin Extended-D": range(42784, 43008), + "Syloti Nagri": range(43008, 43056), + "Common Indic Number Forms": range(43056, 43072), + "Phags-pa": range(43072, 43136), + "Saurashtra": range(43136, 43232), + "Devanagari Extended": range(43232, 43264), + "Kayah Li": range(43264, 43312), + "Rejang": range(43312, 43360), + "Hangul Jamo Extended-A": range(43360, 43392), + "Javanese": range(43392, 43488), + "Myanmar Extended-B": range(43488, 43520), + "Cham": range(43520, 43616), + "Myanmar Extended-A": range(43616, 43648), + "Tai Viet": range(43648, 43744), + "Meetei Mayek Extensions": range(43744, 43776), + "Ethiopic Extended-A": range(43776, 43824), + "Latin Extended-E": range(43824, 43888), + "Cherokee Supplement": range(43888, 43968), + "Meetei Mayek": range(43968, 44032), + "Hangul Syllables": range(44032, 55216), + "Hangul Jamo Extended-B": range(55216, 55296), + "High Surrogates": range(55296, 56192), + "High Private Use Surrogates": range(56192, 56320), + "Low Surrogates": range(56320, 57344), + "Private Use Area": range(57344, 63744), + "CJK Compatibility Ideographs": range(63744, 64256), + "Alphabetic Presentation Forms": range(64256, 64336), + "Arabic Presentation Forms-A": range(64336, 65024), + "Variation Selectors": range(65024, 65040), + "Vertical Forms": range(65040, 65056), + "Combining Half Marks": range(65056, 65072), + "CJK Compatibility Forms": range(65072, 65104), + "Small Form Variants": range(65104, 65136), + "Arabic Presentation Forms-B": range(65136, 65280), + "Halfwidth and Fullwidth Forms": range(65280, 65520), + "Specials": range(65520, 65536), + "Linear B Syllabary": range(65536, 65664), + "Linear B Ideograms": range(65664, 65792), + "Aegean Numbers": range(65792, 65856), + "Ancient Greek Numbers": range(65856, 65936), + "Ancient Symbols": range(65936, 66000), + "Phaistos Disc": range(66000, 66048), + "Lycian": range(66176, 66208), + "Carian": range(66208, 66272), + "Coptic Epact Numbers": range(66272, 66304), + "Old Italic": range(66304, 66352), + "Gothic": range(66352, 66384), + "Old Permic": range(66384, 66432), + "Ugaritic": range(66432, 66464), + "Old Persian": range(66464, 66528), + "Deseret": range(66560, 66640), + "Shavian": range(66640, 66688), + "Osmanya": range(66688, 66736), + "Osage": range(66736, 66816), + "Elbasan": range(66816, 66864), + "Caucasian Albanian": range(66864, 66928), + "Vithkuqi": range(66928, 67008), + "Linear A": range(67072, 67456), + "Latin Extended-F": range(67456, 67520), + "Cypriot Syllabary": range(67584, 67648), + "Imperial Aramaic": range(67648, 67680), + "Palmyrene": range(67680, 67712), + "Nabataean": range(67712, 67760), + "Hatran": range(67808, 67840), + "Phoenician": range(67840, 67872), + "Lydian": range(67872, 67904), + "Meroitic Hieroglyphs": range(67968, 68000), + "Meroitic Cursive": range(68000, 68096), + "Kharoshthi": range(68096, 68192), + "Old South Arabian": range(68192, 68224), + "Old North Arabian": range(68224, 68256), + "Manichaean": range(68288, 68352), + "Avestan": range(68352, 68416), + "Inscriptional Parthian": range(68416, 68448), + "Inscriptional Pahlavi": range(68448, 68480), + "Psalter Pahlavi": range(68480, 68528), + "Old Turkic": range(68608, 68688), + "Old Hungarian": range(68736, 68864), + "Hanifi Rohingya": range(68864, 68928), + "Rumi Numeral Symbols": range(69216, 69248), + "Yezidi": range(69248, 69312), + "Arabic Extended-C": range(69312, 69376), + "Old Sogdian": range(69376, 69424), + "Sogdian": range(69424, 69488), + "Old Uyghur": range(69488, 69552), + "Chorasmian": range(69552, 69600), + "Elymaic": range(69600, 69632), + "Brahmi": range(69632, 69760), + "Kaithi": range(69760, 69840), + "Sora Sompeng": range(69840, 69888), + "Chakma": range(69888, 69968), + "Mahajani": range(69968, 70016), + "Sharada": range(70016, 70112), + "Sinhala Archaic Numbers": range(70112, 70144), + "Khojki": range(70144, 70224), + "Multani": range(70272, 70320), + "Khudawadi": range(70320, 70400), + "Grantha": range(70400, 70528), + "Newa": range(70656, 70784), + "Tirhuta": range(70784, 70880), + "Siddham": range(71040, 71168), + "Modi": range(71168, 71264), + "Mongolian Supplement": range(71264, 71296), + "Takri": range(71296, 71376), + "Ahom": range(71424, 71504), + "Dogra": range(71680, 71760), + "Warang Citi": range(71840, 71936), + "Dives Akuru": range(71936, 72032), + "Nandinagari": range(72096, 72192), + "Zanabazar Square": range(72192, 72272), + "Soyombo": range(72272, 72368), + "Unified Canadian Aboriginal Syllabics Extended-A": range(72368, 72384), + "Pau Cin Hau": range(72384, 72448), + "Devanagari Extended-A": range(72448, 72544), + "Bhaiksuki": range(72704, 72816), + "Marchen": range(72816, 72896), + "Masaram Gondi": range(72960, 73056), + "Gunjala Gondi": range(73056, 73136), + "Makasar": range(73440, 73472), + "Kawi": range(73472, 73568), + "Lisu Supplement": range(73648, 73664), + "Tamil Supplement": range(73664, 73728), + "Cuneiform": range(73728, 74752), + "Cuneiform Numbers and Punctuation": range(74752, 74880), + "Early Dynastic Cuneiform": range(74880, 75088), + "Cypro-Minoan": range(77712, 77824), + "Egyptian Hieroglyphs": range(77824, 78896), + "Egyptian Hieroglyph Format Controls": range(78896, 78944), + "Anatolian Hieroglyphs": range(82944, 83584), + "Bamum Supplement": range(92160, 92736), + "Mro": range(92736, 92784), + "Tangsa": range(92784, 92880), + "Bassa Vah": range(92880, 92928), + "Pahawh Hmong": range(92928, 93072), + "Medefaidrin": range(93760, 93856), + "Miao": range(93952, 94112), + "Ideographic Symbols and Punctuation": range(94176, 94208), + "Tangut": range(94208, 100352), + "Tangut Components": range(100352, 101120), + "Khitan Small Script": range(101120, 101632), + "Tangut Supplement": range(101632, 101760), + "Kana Extended-B": range(110576, 110592), + "Kana Supplement": range(110592, 110848), + "Kana Extended-A": range(110848, 110896), + "Small Kana Extension": range(110896, 110960), + "Nushu": range(110960, 111360), + "Duployan": range(113664, 113824), + "Shorthand Format Controls": range(113824, 113840), + "Znamenny Musical Notation": range(118528, 118736), + "Byzantine Musical Symbols": range(118784, 119040), + "Musical Symbols": range(119040, 119296), + "Ancient Greek Musical Notation": range(119296, 119376), + "Kaktovik Numerals": range(119488, 119520), + "Mayan Numerals": range(119520, 119552), + "Tai Xuan Jing Symbols": range(119552, 119648), + "Counting Rod Numerals": range(119648, 119680), + "Mathematical Alphanumeric Symbols": range(119808, 120832), + "Sutton SignWriting": range(120832, 121520), + "Latin Extended-G": range(122624, 122880), + "Glagolitic Supplement": range(122880, 122928), + "Cyrillic Extended-D": range(122928, 123024), + "Nyiakeng Puachue Hmong": range(123136, 123216), + "Toto": range(123536, 123584), + "Wancho": range(123584, 123648), + "Nag Mundari": range(124112, 124160), + "Ethiopic Extended-B": range(124896, 124928), + "Mende Kikakui": range(124928, 125152), + "Adlam": range(125184, 125280), + "Indic Siyaq Numbers": range(126064, 126144), + "Ottoman Siyaq Numbers": range(126208, 126288), + "Arabic Mathematical Alphabetic Symbols": range(126464, 126720), + "Mahjong Tiles": range(126976, 127024), + "Domino Tiles": range(127024, 127136), + "Playing Cards": range(127136, 127232), + "Enclosed Alphanumeric Supplement": range(127232, 127488), + "Enclosed Ideographic Supplement": range(127488, 127744), + "Miscellaneous Symbols and Pictographs": range(127744, 128512), + "Emoticons range(Emoji)": range(128512, 128592), + "Ornamental Dingbats": range(128592, 128640), + "Transport and Map Symbols": range(128640, 128768), + "Alchemical Symbols": range(128768, 128896), + "Geometric Shapes Extended": range(128896, 129024), + "Supplemental Arrows-C": range(129024, 129280), + "Supplemental Symbols and Pictographs": range(129280, 129536), + "Chess Symbols": range(129536, 129648), + "Symbols and Pictographs Extended-A": range(129648, 129792), + "Symbols for Legacy Computing": range(129792, 130048), + "CJK Unified Ideographs Extension B": range(131072, 173792), + "CJK Unified Ideographs Extension C": range(173824, 177984), + "CJK Unified Ideographs Extension D": range(177984, 178208), + "CJK Unified Ideographs Extension E": range(178208, 183984), + "CJK Unified Ideographs Extension F": range(183984, 191472), + "CJK Compatibility Ideographs Supplement": range(194560, 195104), + "CJK Unified Ideographs Extension G": range(196608, 201552), + "CJK Unified Ideographs Extension H": range(201552, 205744), + "Tags": range(917504, 917632), + "Variation Selectors Supplement": range(917760, 918000), + "Supplementary Private Use Area-A": range(983040, 1048576), + "Supplementary Private Use Area-B": range(1048576, 1114112), } @@ -331,11 +380,23 @@ IGNORECASE, ) +IANA_NO_ALIASES = [ + "cp720", + "cp737", + "cp856", + "cp874", + "cp875", + "cp1006", + "koi8_r", + "koi8_t", + "koi8_u", +] + IANA_SUPPORTED: List[str] = sorted( filter( lambda x: x.endswith("_codec") is False and x not in {"rot_13", "tactis", "mbcs"}, - list(set(aliases.values())), + list(set(aliases.values())) + IANA_NO_ALIASES, ) ) @@ -483,13 +544,1454 @@ "|", '"', "-", + "(", + ")", } KO_NAMES: Set[str] = {"johab", "cp949", "euc_kr"} ZH_NAMES: Set[str] = {"big5", "cp950", "big5hkscs", "hz"} -LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) - # Logging LEVEL below DEBUG TRACE: int = 5 + + +# Language label that contain the em dash "—" +# character are to be considered alternative seq to origin +FREQUENCIES: Dict[str, List[str]] = { + "English": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "u", + "m", + "f", + "p", + "g", + "w", + "y", + "b", + "v", + "k", + "x", + "j", + "z", + "q", + ], + "English—": [ + "e", + "a", + "t", + "i", + "o", + "n", + "s", + "r", + "h", + "l", + "d", + "c", + "m", + "u", + "f", + "p", + "g", + "w", + "b", + "y", + "v", + "k", + "j", + "x", + "z", + "q", + ], + "German": [ + "e", + "n", + "i", + "r", + "s", + "t", + "a", + "d", + "h", + "u", + "l", + "g", + "o", + "c", + "m", + "b", + "f", + "k", + "w", + "z", + "p", + "v", + "ü", + "Ƥ", + "ƶ", + "j", + ], + "French": [ + "e", + "a", + "s", + "n", + "i", + "t", + "r", + "l", + "u", + "o", + "d", + "c", + "p", + "m", + "Ć©", + "v", + "g", + "f", + "b", + "h", + "q", + "Ć ", + "x", + "ĆØ", + "y", + "j", + ], + "Dutch": [ + "e", + "n", + "a", + "i", + "r", + "t", + "o", + "d", + "s", + "l", + "g", + "h", + "v", + "m", + "u", + "k", + "c", + "p", + "b", + "w", + "j", + "z", + "f", + "y", + "x", + "Ć«", + ], + "Italian": [ + "e", + "i", + "a", + "o", + "n", + "l", + "t", + "r", + "s", + "c", + "d", + "u", + "p", + "m", + "g", + "v", + "f", + "b", + "z", + "h", + "q", + "ĆØ", + "Ć ", + "k", + "y", + "ò", + ], + "Polish": [ + "a", + "i", + "o", + "e", + "n", + "r", + "z", + "w", + "s", + "c", + "t", + "k", + "y", + "d", + "p", + "m", + "u", + "l", + "j", + "ł", + "g", + "b", + "h", + "ą", + "ę", + "ó", + ], + "Spanish": [ + "e", + "a", + "o", + "n", + "s", + "r", + "i", + "l", + "d", + "t", + "c", + "u", + "m", + "p", + "b", + "g", + "v", + "f", + "y", + "ó", + "h", + "q", + "Ć­", + "j", + "z", + "Ć”", + ], + "Russian": [ + "о", + "а", + "е", + "Šø", + "н", + "с", + "т", + "р", + "в", + "Š»", + "Šŗ", + "м", + "Š“", + "Šæ", + "у", + "г", + "я", + "ы", + "Š·", + "б", + "й", + "ь", + "ч", + "х", + "ж", + "ц", + ], + # Jap-Kanji + "Japanese": [ + "äŗŗ", + "äø€", + "大", + "äŗ…", + "丁", + "äøØ", + "竹", + "笑", + "口", + "ę—„", + "今", + "二", + "å½³", + "蔌", + "十", + "土", + "äø¶", + "寸", + "寺", + "Ꙃ", + "乙", + "äøæ", + "乂", + "갔", + "갗", + "冂", + "å·¾", + "äŗ ", + "åø‚", + "ē›®", + "儿", + "見", + "八", + "小", + "凵", + "県", + "月", + "彐", + "門", + "間", + "木", + "ę±", + "å±±", + "出", + "本", + "äø­", + "刀", + "分", + "耳", + "又", + "取", + "꜀", + "言", + "ē”°", + "心", + "ꀝ", + "刂", + "前", + "äŗ¬", + "å°¹", + "äŗ‹", + "ē”Ÿ", + "厶", + "äŗ‘", + "会", + "未", + "ę„", + "白", + "冫", + "愽", + "灬", + "馬", + "å°ø", + "å°ŗ", + "駅", + "꘎", + "耂", + "者", + "äŗ†", + "阝", + "都", + "高", + "卜", + "占", + "厂", + "广", + "åŗ—", + "子", + "申", + "å„„", + "äŗ»", + "äæŗ", + "上", + "ę–¹", + "冖", + "å­¦", + "蔣", + "艮", + "食", + "自", + ], + # Jap-Katakana + "Japanese—": [ + "ー", + "ン", + "ス", + "惻", + "惫", + "惈", + "リ", + "悤", + "ć‚¢", + "惩", + "惃", + "ク", + "惉", + "ć‚·", + "惬", + "ジ", + "タ", + "惕", + "惭", + "ć‚«", + "惆", + "惞", + "ć‚£", + "悰", + "惐", + "惠", + "惗", + "オ", + "コ", + "惇", + "惋", + "悦", + "惔", + "悵", + "惓", + "ナ", + "惖", + "ャ", + "エ", + "惄", + "惁", + "悭", + "ズ", + "惀", + "惑", + "ミ", + "悧", + "惧", + "惏", + "ć‚»", + "惙", + "悬", + "モ", + "惄", + "惍", + "ボ", + "ソ", + "惎", + "ć‚”", + "惓", + "ワ", + "惝", + "ペ", + "惔", + "悱", + "ć‚“", + "ć‚®", + "ć‚¶", + "惛", + "ゲ", + "ć‚©", + "惤", + "惒", + "惦", + "ヨ", + "惘", + "ゼ", + "ヌ", + "ć‚„", + "ゾ", + "惶", + "惂", + "ヲ", + "情", + "惵", + "惱", + "惰", + "惮", + "ヽ", + "悠", + "ヾ", + "惷", + "ヿ", + "ヸ", + "ヹ", + "ヺ", + ], + # Jap-Hiragana + "Japanese——": [ + "恮", + "恫", + "悋", + "た", + "と", + "は", + "恗", + "恄", + "悒", + "恧", + "恦", + "が", + "な", + "悌", + "恋", + "悉", + "恕", + "っ", + "悊", + "恙", + "恂", + "悂", + "恓", + "ま", + "恆", + "恏", + "悈", + "恍", + "悓", + "悁", + "お", + "恑", + "恝", + "恤", + "恠", + "悄", + "恈", + "恩", + "悏", + "恔", + "み", + "恛", + "恘", + "恰", + "へ", + "び", + "ず", + "悍", + "恻", + "恒", + "悀", + "べ", + "ひ", + "悇", + "悆", + "恶", + "恔", + "悃", + "恭", + "恵", + "恐", + "恎", + "ぼ", + "悅", + "恄", + "恖", + "恞", + "恬", + "ぜ", + "恱", + "ぽ", + "恷", + "恓", + "恃", + "恁", + "恇", + "ぺ", + "悞", + "ぢ", + "恉", + "恅", + "悐", + "悝", + "悑", + "悛", + "悜", + "悎", + "悔", + "悚", + "悟", + "悙", + "悕", + "悖", + ], + "Portuguese": [ + "a", + "e", + "o", + "s", + "i", + "r", + "d", + "n", + "t", + "m", + "u", + "c", + "l", + "p", + "g", + "v", + "b", + "f", + "h", + "Ć£", + "q", + "Ć©", + "Ƨ", + "Ć”", + "z", + "Ć­", + ], + "Swedish": [ + "e", + "a", + "n", + "r", + "t", + "s", + "i", + "l", + "d", + "o", + "m", + "k", + "g", + "v", + "h", + "f", + "u", + "p", + "Ƥ", + "c", + "b", + "ƶ", + "Ć„", + "y", + "j", + "x", + ], + "Chinese": [ + "ēš„", + "äø€", + "是", + "äø", + "äŗ†", + "在", + "äŗŗ", + "꜉", + "ꈑ", + "他", + "čæ™", + "äøŖ", + "们", + "äø­", + "ę„", + "上", + "大", + "äøŗ", + "和", + "国", + "地", + "到", + "仄", + "诓", + "ę—¶", + "要", + "å°±", + "出", + "会", + "åÆ", + "也", + "ä½ ", + "对", + "ē”Ÿ", + "能", + "而", + "子", + "那", + "得", + "äŗŽ", + "ē€", + "äø‹", + "自", + "之", + "幓", + "过", + "发", + "后", + "作", + "里", + "用", + "道", + "蔌", + "ꉀ", + "ē„¶", + "å®¶", + "ē§", + "äŗ‹", + "ꈐ", + "ę–¹", + "多", + "ē»", + "么", + "去", + "法", + "å­¦", + "如", + "都", + "同", + "ēŽ°", + "当", + "ę²”", + "动", + "面", + "čµ·", + "ēœ‹", + "定", + "天", + "分", + "还", + "čæ›", + "儽", + "小", + "部", + "其", + "äŗ›", + "äø»", + "ę ·", + "理", + "心", + "儹", + "本", + "前", + "开", + "但", + "因", + "åŖ", + "从", + "想", + "实", + ], + "Ukrainian": [ + "о", + "а", + "н", + "і", + "Šø", + "р", + "в", + "т", + "е", + "с", + "Šŗ", + "Š»", + "у", + "Š“", + "м", + "Šæ", + "Š·", + "я", + "ь", + "б", + "г", + "й", + "ч", + "х", + "ц", + "ї", + ], + "Norwegian": [ + "e", + "r", + "n", + "t", + "a", + "s", + "i", + "o", + "l", + "d", + "g", + "k", + "m", + "v", + "f", + "p", + "u", + "b", + "h", + "Ć„", + "y", + "j", + "Ćø", + "c", + "Ʀ", + "w", + ], + "Finnish": [ + "a", + "i", + "n", + "t", + "e", + "s", + "l", + "o", + "u", + "k", + "Ƥ", + "m", + "r", + "v", + "j", + "h", + "p", + "y", + "d", + "ƶ", + "g", + "c", + "b", + "f", + "w", + "z", + ], + "Vietnamese": [ + "n", + "h", + "t", + "i", + "c", + "g", + "a", + "o", + "u", + "m", + "l", + "r", + "Ć ", + "đ", + "s", + "e", + "v", + "p", + "b", + "y", + "ʰ", + "d", + "Ć”", + "k", + "į»™", + "įŗæ", + ], + "Czech": [ + "o", + "e", + "a", + "n", + "t", + "s", + "i", + "l", + "v", + "r", + "k", + "d", + "u", + "m", + "p", + "Ć­", + "c", + "h", + "z", + "Ć”", + "y", + "j", + "b", + "ě", + "Ć©", + "ř", + ], + "Hungarian": [ + "e", + "a", + "t", + "l", + "s", + "n", + "k", + "r", + "i", + "o", + "z", + "Ć”", + "Ć©", + "g", + "m", + "b", + "y", + "v", + "d", + "h", + "u", + "p", + "j", + "ƶ", + "f", + "c", + ], + "Korean": [ + "ģ“", + "다", + "에", + "ģ˜", + "ėŠ”", + "딜", + "ķ•˜", + "ģ„", + "ź°€", + "ź³ ", + "ģ§€", + "ģ„œ", + "ķ•œ", + "ģ€", + "źø°", + "으", + "ė…„", + "ėŒ€", + "사", + "ģ‹œ", + "넼", + "리", + "ė„", + "ģø", + "스", + "ģ¼", + ], + "Indonesian": [ + "a", + "n", + "e", + "i", + "r", + "t", + "u", + "s", + "d", + "k", + "m", + "l", + "g", + "p", + "b", + "o", + "h", + "y", + "j", + "c", + "w", + "f", + "v", + "z", + "x", + "q", + ], + "Turkish": [ + "a", + "e", + "i", + "n", + "r", + "l", + "ı", + "k", + "d", + "t", + "s", + "m", + "y", + "u", + "o", + "b", + "ü", + "ş", + "v", + "g", + "z", + "h", + "c", + "p", + "Ƨ", + "ğ", + ], + "Romanian": [ + "e", + "i", + "a", + "r", + "n", + "t", + "u", + "l", + "o", + "c", + "s", + "d", + "p", + "m", + "ă", + "f", + "v", + "Ć®", + "g", + "b", + "ș", + "ț", + "z", + "h", + "Ć¢", + "j", + ], + "Farsi": [ + "Ų§", + "ی", + "Ų±", + "ŲÆ", + "ن", + "ه", + "و", + "Ł…", + "ŲŖ", + "ŲØ", + "Ų³", + "Ł„", + "Ś©", + "Ų“", + "Ų²", + "ف", + "ŚÆ", + "Ų¹", + "Ų®", + "Ł‚", + "Ų¬", + "Ų¢", + "پ", + "Ų­", + "Ų·", + "Ųµ", + ], + "Arabic": [ + "Ų§", + "Ł„", + "ي", + "Ł…", + "و", + "ن", + "Ų±", + "ŲŖ", + "ŲØ", + "Ų©", + "Ų¹", + "ŲÆ", + "Ų³", + "ف", + "ه", + "ك", + "Ł‚", + "Ų£", + "Ų­", + "Ų¬", + "Ų“", + "Ų·", + "Ųµ", + "ى", + "Ų®", + "Ų„", + ], + "Danish": [ + "e", + "r", + "n", + "t", + "a", + "i", + "s", + "d", + "l", + "o", + "g", + "m", + "k", + "f", + "v", + "u", + "b", + "h", + "p", + "Ć„", + "y", + "Ćø", + "Ʀ", + "c", + "j", + "w", + ], + "Serbian": [ + "а", + "Šø", + "о", + "е", + "н", + "р", + "с", + "у", + "т", + "Šŗ", + "ј", + "в", + "Š“", + "м", + "Šæ", + "Š»", + "г", + "Š·", + "б", + "a", + "i", + "e", + "o", + "n", + "ц", + "ш", + ], + "Lithuanian": [ + "i", + "a", + "s", + "o", + "r", + "e", + "t", + "n", + "u", + "k", + "m", + "l", + "p", + "v", + "d", + "j", + "g", + "ė", + "b", + "y", + "ų", + "Å”", + "ž", + "c", + "ą", + "ÄÆ", + ], + "Slovene": [ + "e", + "a", + "i", + "o", + "n", + "r", + "s", + "l", + "t", + "j", + "v", + "k", + "d", + "p", + "m", + "u", + "z", + "b", + "g", + "h", + "č", + "c", + "Å”", + "ž", + "f", + "y", + ], + "Slovak": [ + "o", + "a", + "e", + "n", + "i", + "r", + "v", + "t", + "s", + "l", + "k", + "d", + "m", + "p", + "u", + "c", + "h", + "j", + "b", + "z", + "Ć”", + "y", + "ý", + "Ć­", + "č", + "Ć©", + ], + "Hebrew": [ + "י", + "ו", + "ה", + "ל", + "ר", + "ב", + "×Ŗ", + "מ", + "א", + "ש", + "× ", + "×¢", + "ם", + "ד", + "×§", + "ח", + "פ", + "×”", + "כ", + "ג", + "ט", + "צ", + "ן", + "ז", + "ך", + ], + "Bulgarian": [ + "а", + "Šø", + "о", + "е", + "н", + "т", + "р", + "с", + "в", + "Š»", + "Šŗ", + "Š“", + "Šæ", + "м", + "Š·", + "г", + "я", + "ъ", + "у", + "б", + "ч", + "ц", + "й", + "ж", + "щ", + "х", + ], + "Croatian": [ + "a", + "i", + "o", + "e", + "n", + "r", + "j", + "s", + "t", + "u", + "k", + "l", + "v", + "d", + "m", + "p", + "g", + "z", + "b", + "c", + "č", + "h", + "Å”", + "ž", + "ć", + "f", + ], + "Hindi": [ + "क", + "र", + "स", + "न", + "त", + "म", + "ह", + "प", + "य", + "ल", + "व", + "ज", + "द", + "ग", + "ब", + "श", + "ट", + "अ", + "ą¤", + "ऄ", + "भ", + "औ", + "च", + "ध", + "ष", + "इ", + ], + "Estonian": [ + "a", + "i", + "e", + "s", + "t", + "l", + "u", + "n", + "o", + "k", + "r", + "d", + "m", + "v", + "g", + "p", + "j", + "h", + "Ƥ", + "b", + "Ƶ", + "ü", + "f", + "c", + "ƶ", + "y", + ], + "Thai": [ + "ąø²", + "ąø™", + "ąø£", + "ąø­", + "ก", + "ą¹€", + "ąø‡", + "ąø”", + "ąø¢", + "ąø„", + "ąø§", + "ąø”", + "ąø—", + "ąøŖ", + "ąø•", + "ąø°", + "ąø›", + "บ", + "ąø„", + "ąø«", + "แ", + "จ", + "ąøž", + "ช", + "ąø‚", + "ใ", + ], + "Greek": [ + "α", + "Ļ„", + "Īæ", + "ι", + "ε", + "ν", + "ρ", + "σ", + "Īŗ", + "Ī·", + "Ļ€", + "Ļ‚", + "Ļ…", + "μ", + "Ī»", + "ĪÆ", + "ό", + "ά", + "γ", + "Ī­", + "Ī“", + "Ī®", + "ω", + "χ", + "Īø", + "Ļ", + ], + "Tamil": [ + "க", + "த", + "ப", + "ட", + "ą®°", + "ą®®", + "ல", + "ன", + "வ", + "ą®±", + "ய", + "ள", + "ச", + "ந", + "இ", + "ண", + "ą®…", + "ஆ", + "ஓ", + "ą®™", + "ą®Ž", + "உ", + "ą®’", + "ஸ", + ], + "Kazakh": [ + "а", + "ы", + "е", + "н", + "т", + "р", + "Š»", + "і", + "Š“", + "с", + "м", + "Ņ›", + "Šŗ", + "о", + "б", + "Šø", + "у", + "Ņ“", + "ж", + "Ņ£", + "Š·", + "ш", + "й", + "Šæ", + "г", + "Ó©", + ], +} + +LANGUAGE_SUPPORTED_COUNT: int = len(FREQUENCIES) diff --git a/vendor/charset_normalizer/legacy.py b/vendor/charset_normalizer/legacy.py index 43aad21..3f6d490 100644 --- a/vendor/charset_normalizer/legacy.py +++ b/vendor/charset_normalizer/legacy.py @@ -1,13 +1,24 @@ -from typing import Any, Dict, Optional, Union +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Optional from warnings import warn from .api import from_bytes from .constant import CHARDET_CORRESPONDENCE +# TODO: remove this check when dropping Python 3.7 support +if TYPE_CHECKING: + from typing_extensions import TypedDict + + class ResultDict(TypedDict): + encoding: Optional[str] + language: str + confidence: Optional[float] + def detect( byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any -) -> Dict[str, Optional[Union[str, float]]]: +) -> ResultDict: """ chardet legacy method Detect the encoding of the given byte string. It should be mostly backward-compatible. diff --git a/vendor/charset_normalizer/md.py b/vendor/charset_normalizer/md.py index 56e9321..d834db0 100644 --- a/vendor/charset_normalizer/md.py +++ b/vendor/charset_normalizer/md.py @@ -9,7 +9,8 @@ ) from .utils import ( is_accentuated, - is_ascii, + is_arabic, + is_arabic_isolated_form, is_case_variable, is_cjk, is_emoticon, @@ -128,8 +129,9 @@ def reset(self) -> None: # pragma: no cover @property def ratio(self) -> float: - if self._character_count == 0 or self._character_count < 8: + if self._character_count < 8: return 0.0 + ratio_of_accentuation: float = self._accentuated_count / self._character_count return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0 @@ -234,16 +236,13 @@ def reset(self) -> None: # pragma: no cover @property def ratio(self) -> float: - if self._character_count == 0: + if self._character_count <= 13: return 0.0 ratio_of_suspicious_range_usage: float = ( self._suspicious_successive_range_count * 2 ) / self._character_count - if ratio_of_suspicious_range_usage < 0.1: - return 0.0 - return ratio_of_suspicious_range_usage @@ -261,6 +260,7 @@ def __init__(self) -> None: self._buffer: str = "" self._buffer_accent_count: int = 0 + self._buffer_glyph_count: int = 0 def eligible(self, character: str) -> bool: return True @@ -280,6 +280,14 @@ def feed(self, character: str) -> None: and is_thai(character) is False ): self._foreign_long_watch = True + if ( + is_cjk(character) + or is_hangul(character) + or is_katakana(character) + or is_hiragana(character) + or is_thai(character) + ): + self._buffer_glyph_count += 1 return if not self._buffer: return @@ -292,16 +300,34 @@ def feed(self, character: str) -> None: self._character_count += buffer_length if buffer_length >= 4: - if self._buffer_accent_count / buffer_length > 0.34: + if self._buffer_accent_count / buffer_length >= 0.5: self._is_current_word_bad = True - # Word/Buffer ending with a upper case accentuated letter are so rare, + # Word/Buffer ending with an upper case accentuated letter are so rare, # that we will consider them all as suspicious. Same weight as foreign_long suspicious. - if is_accentuated(self._buffer[-1]) and self._buffer[-1].isupper(): + elif ( + is_accentuated(self._buffer[-1]) + and self._buffer[-1].isupper() + and all(_.isupper() for _ in self._buffer) is False + ): self._foreign_long_count += 1 self._is_current_word_bad = True + elif self._buffer_glyph_count == 1: + self._is_current_word_bad = True + self._foreign_long_count += 1 if buffer_length >= 24 and self._foreign_long_watch: - self._foreign_long_count += 1 - self._is_current_word_bad = True + camel_case_dst = [ + i + for c, i in zip(self._buffer, range(0, buffer_length)) + if c.isupper() + ] + probable_camel_cased: bool = False + + if camel_case_dst and (len(camel_case_dst) / buffer_length <= 0.3): + probable_camel_cased = True + + if not probable_camel_cased: + self._foreign_long_count += 1 + self._is_current_word_bad = True if self._is_current_word_bad: self._bad_word_count += 1 @@ -311,6 +337,7 @@ def feed(self, character: str) -> None: self._foreign_long_watch = False self._buffer = "" self._buffer_accent_count = 0 + self._buffer_glyph_count = 0 elif ( character not in {"<", ">", "-", "=", "~", "|", "_"} and character.isdigit() is False @@ -408,7 +435,7 @@ def feed(self, character: str) -> None: return - if self._current_ascii_only is True and is_ascii(character) is False: + if self._current_ascii_only is True and character.isascii() is False: self._current_ascii_only = False if self._last_alpha_seen is not None: @@ -444,6 +471,34 @@ def ratio(self) -> float: return self._successive_upper_lower_count_final / self._character_count +class ArabicIsolatedFormPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._character_count: int = 0 + self._isolated_form_count: int = 0 + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._isolated_form_count = 0 + + def eligible(self, character: str) -> bool: + return is_arabic(character) + + def feed(self, character: str) -> None: + self._character_count += 1 + + if is_arabic_isolated_form(character): + self._isolated_form_count += 1 + + @property + def ratio(self) -> float: + if self._character_count < 8: + return 0.0 + + isolated_form_usage: float = self._isolated_form_count / self._character_count + + return isolated_form_usage + + @lru_cache(maxsize=1024) def is_suspiciously_successive_range( unicode_range_a: Optional[str], unicode_range_b: Optional[str] @@ -511,6 +566,8 @@ def is_suspiciously_successive_range( return False if "Forms" in unicode_range_a or "Forms" in unicode_range_b: return False + if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin": + return False return True diff --git a/vendor/charset_normalizer/models.py b/vendor/charset_normalizer/models.py index 7f8ca38..6f6b86b 100644 --- a/vendor/charset_normalizer/models.py +++ b/vendor/charset_normalizer/models.py @@ -1,9 +1,10 @@ from encodings.aliases import aliases from hashlib import sha256 from json import dumps +from re import sub from typing import Any, Dict, Iterator, List, Optional, Tuple, Union -from .constant import TOO_BIG_SEQUENCE +from .constant import RE_POSSIBLE_ENCODING_INDICATION, TOO_BIG_SEQUENCE from .utils import iana_name, is_multi_byte_encoding, unicode_range @@ -16,6 +17,7 @@ def __init__( has_sig_or_bom: bool, languages: "CoherenceMatches", decoded_payload: Optional[str] = None, + preemptive_declaration: Optional[str] = None, ): self._payload: bytes = payload @@ -33,13 +35,13 @@ def __init__( self._string: Optional[str] = decoded_payload + self._preemptive_declaration: Optional[str] = preemptive_declaration + def __eq__(self, other: object) -> bool: if not isinstance(other, CharsetMatch): - raise TypeError( - "__eq__ cannot be invoked on {} and {}.".format( - str(other.__class__), str(self.__class__) - ) - ) + if isinstance(other, str): + return iana_name(other) == self.encoding + return False return self.encoding == other.encoding and self.fingerprint == other.fingerprint def __lt__(self, other: object) -> bool: @@ -54,16 +56,19 @@ def __lt__(self, other: object) -> bool: # Below 1% difference --> Use Coherence if chaos_difference < 0.01 and coherence_difference > 0.02: - # When having a tough decision, use the result that decoded as many multi-byte as possible. - if chaos_difference == 0.0 and self.coherence == other.coherence: - return self.multi_byte_usage > other.multi_byte_usage return self.coherence > other.coherence + elif chaos_difference < 0.01 and coherence_difference <= 0.02: + # When having a difficult decision, use the result that decoded as many multi-byte as possible. + # preserve RAM usage! + if len(self._payload) >= TOO_BIG_SEQUENCE: + return self.chaos < other.chaos + return self.multi_byte_usage > other.multi_byte_usage return self.chaos < other.chaos @property def multi_byte_usage(self) -> float: - return 1.0 - len(str(self)) / len(self.raw) + return 1.0 - (len(str(self)) / len(self.raw)) def __str__(self) -> str: # Lazy Str Loading @@ -207,7 +212,24 @@ def output(self, encoding: str = "utf_8") -> bytes: """ if self._output_encoding is None or self._output_encoding != encoding: self._output_encoding = encoding - self._output_payload = str(self).encode(encoding, "replace") + decoded_string = str(self) + if ( + self._preemptive_declaration is not None + and self._preemptive_declaration.lower() + not in ["utf-8", "utf8", "utf_8"] + ): + patched_header = sub( + RE_POSSIBLE_ENCODING_INDICATION, + lambda m: m.string[m.span()[0] : m.span()[1]].replace( + m.groups()[0], iana_name(self._output_encoding) # type: ignore[arg-type] + ), + decoded_string[:8192], + 1, + ) + + decoded_string = patched_header + decoded_string[8192:] + + self._output_payload = decoded_string.encode(encoding, "replace") return self._output_payload # type: ignore @@ -263,7 +285,7 @@ def append(self, item: CharsetMatch) -> None: ) ) # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) - if len(item.raw) <= TOO_BIG_SEQUENCE: + if len(item.raw) < TOO_BIG_SEQUENCE: for match in self._results: if match.fingerprint == item.fingerprint and match.chaos == item.chaos: match.add_submatch(item) diff --git a/vendor/charset_normalizer/utils.py b/vendor/charset_normalizer/utils.py index 76eafc6..e5cbbf4 100644 --- a/vendor/charset_normalizer/utils.py +++ b/vendor/charset_normalizer/utils.py @@ -32,6 +32,8 @@ def is_accentuated(character: str) -> bool: or "WITH DIAERESIS" in description or "WITH CIRCUMFLEX" in description or "WITH TILDE" in description + or "WITH MACRON" in description + or "WITH RING ABOVE" in description ) @@ -69,15 +71,6 @@ def is_latin(character: str) -> bool: return "LATIN" in description -@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) -def is_ascii(character: str) -> bool: - try: - character.encode("ascii") - except UnicodeEncodeError: - return False - return True - - @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) def is_punctuation(character: str) -> bool: character_category: str = unicodedata.category(character) @@ -105,7 +98,7 @@ def is_symbol(character: str) -> bool: if character_range is None: return False - return "Forms" in character_range + return "Forms" in character_range and character_category != "Lo" @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) @@ -115,17 +108,17 @@ def is_emoticon(character: str) -> bool: if character_range is None: return False - return "Emoticons" in character_range + return "Emoticons" in character_range or "Pictographs" in character_range @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) def is_separator(character: str) -> bool: - if character.isspace() or character in {"|", "+", ",", ";", "<", ">"}: + if character.isspace() or character in {"|", "+", "<", ">"}: return True character_category: str = unicodedata.category(character) - return "Z" in character_category + return "Z" in character_category or character_category in {"Po", "Pd", "Pc"} @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) @@ -133,12 +126,6 @@ def is_case_variable(character: str) -> bool: return character.islower() != character.isupper() -def is_private_use_only(character: str) -> bool: - character_category: str = unicodedata.category(character) - - return character_category == "Co" - - @lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) def is_cjk(character: str) -> bool: try: @@ -189,6 +176,26 @@ def is_thai(character: str) -> bool: return "THAI" in character_name +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_arabic(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "ARABIC" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_arabic_isolated_form(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "ARABIC" in character_name and "ISOLATED FORM" in character_name + + @lru_cache(maxsize=len(UNICODE_RANGES_COMBINED)) def is_unicode_range_secondary(range_name: str) -> bool: return any(keyword in range_name for keyword in UNICODE_SECONDARY_RANGE_KEYWORD) @@ -205,7 +212,7 @@ def is_unprintable(character: str) -> bool: ) -def any_specified_encoding(sequence: bytes, search_zone: int = 4096) -> Optional[str]: +def any_specified_encoding(sequence: bytes, search_zone: int = 8192) -> Optional[str]: """ Extract using ASCII-only decoder any specified encoding in the first n-bytes. """ diff --git a/vendor/charset_normalizer/version.py b/vendor/charset_normalizer/version.py index b74c264..699990e 100644 --- a/vendor/charset_normalizer/version.py +++ b/vendor/charset_normalizer/version.py @@ -2,5 +2,5 @@ Expose version """ -__version__ = "3.1.0" +__version__ = "3.4.0" VERSION = __version__.split(".") diff --git a/vendor/ghastoolkit/__init__.py b/vendor/ghastoolkit/__init__.py index 24d6c26..5518678 100644 --- a/vendor/ghastoolkit/__init__.py +++ b/vendor/ghastoolkit/__init__.py @@ -1,7 +1,9 @@ +"""GitHub Advanced Security Toolkit.""" + __name__ = "ghastoolkit" __title__ = "GHAS Toolkit" -__version__ = "0.3.1" +__version__ = "0.15.1" __description__ = "GitHub Advanced Security Python Toolkit" __summary__ = """\ @@ -17,23 +19,29 @@ __banner__ = f"""\ _____ _ _ ___ _____ _____ _ _ _ _ -| __ \| | | | / _ \ / ___|_ _| | | | (_) | -| | \/| |_| |/ /_\ \\\\ `--. | | ___ ___ | | | ___| |_ -| | __ | _ || _ | `--. \ | |/ _ \ / _ \| | |/ / | __| -| |_\ \| | | || | | |/\__/ / | | (_) | (_) | | <| | |_ - \____/\_| |_/\_| |_/\____/ \_/\___/ \___/|_|_|\_\_|\__| v{__version__} +| __ \\| | | | / _ \\ / ___|_ _| | | | (_) | +| | \\/| |_| |/ /_\\ \\\\ `--. | | ___ ___ | | | ___| |_ +| | __ | _ || _ | `--. \\ | |/ _ \\ / _ \\| | |/ / | __| +| |_\\ \\| | | || | | |/\\__/ / | | (_) | (_) | | <| | |_ + \\____/\\_| |_/\\_| |_/\\____/ \\_/\\___/ \\___/|_|_|\\_\\_|\\__| v{__version__} """ +from ghastoolkit.errors import * + # Octokit -from ghastoolkit.octokit.github import GitHub, Repository +from ghastoolkit.octokit.github import GitHub +from ghastoolkit.octokit.repository import Repository +from ghastoolkit.octokit.enterprise import Enterprise, Organization from ghastoolkit.octokit.octokit import Octokit, RestRequest, GraphQLRequest from ghastoolkit.octokit.codescanning import CodeScanning, CodeAlert from ghastoolkit.octokit.secretscanning import SecretScanning, SecretAlert from ghastoolkit.octokit.dependencygraph import DependencyGraph +from ghastoolkit.octokit.dependabot import Dependabot +from ghastoolkit.octokit.advisories import SecurityAdvisories # Supply Chain -from ghastoolkit.supplychain.advisories import Advisory +from ghastoolkit.supplychain.advisories import Advisory, Advisories from ghastoolkit.supplychain.dependencyalert import DependencyAlert from ghastoolkit.supplychain.dependencies import Dependency, Dependencies from ghastoolkit.supplychain.licensing import Licenses @@ -41,4 +49,9 @@ # CodeQL from ghastoolkit.codeql.databases import CodeQLDatabases, CodeQLDatabase from ghastoolkit.codeql.cli import CodeQL -from ghastoolkit.codeql.results import CodeQLResults +from ghastoolkit.codeql.packs.pack import CodeQLPack +from ghastoolkit.codeql.packs.packs import CodeQLPacks +from ghastoolkit.codeql.results import CodeQLResults, CodeLocation, CodeResult + +# CodeQL Data Extensions / Models as Data +from ghastoolkit.codeql.dataextensions.ext import DataExtensions diff --git a/vendor/ghastoolkit/__main__.py b/vendor/ghastoolkit/__main__.py index c5040a6..5042517 100644 --- a/vendor/ghastoolkit/__main__.py +++ b/vendor/ghastoolkit/__main__.py @@ -1,104 +1,78 @@ -import json -import os +"""ghastoolkit main workflow.""" + +from argparse import Namespace import logging -import argparse -from ghastoolkit import __name__ as name, __banner__ -from ghastoolkit.octokit.github import GitHub +from ghastoolkit import __name__ as name, __banner__, __version__ from ghastoolkit.octokit.codescanning import CodeScanning -from ghastoolkit.octokit.dependencygraph import ( - DependencyGraph, -) - -# Arguments -parser = argparse.ArgumentParser(name) -parser.add_argument("--debug", action="store_true") - -parser.add_argument( - "mode", choices=["all", "codescanning", "codeql", "dependencygraph"] -) - -parser.add_argument("-sha", default=os.environ.get("GITHUB_SHA"), help="Commit SHA") -parser.add_argument("-ref", default=os.environ.get("GITHUB_REF"), help="Commit ref") - -parser_github = parser.add_argument_group("GitHub") -parser_github.add_argument( - "-r", - "--github-repository", - default=os.environ.get("GITHUB_REPOSITORY"), - help="GitHub Repository", -) -parser_github.add_argument( - "--github-instance", - default=os.environ.get("GITHUB_SERVER_URL", "https://github.com"), - help="GitHub Instance", -) -parser_github.add_argument( - "-t", - "--github-token", - default=os.environ.get("GITHUB_TOKEN"), - help="GitHub API Token", -) - -arguments = parser.parse_args() - - -def header(name: str): - print("#" * 32) - print(f" {name}") - print("#" * 32) - print("") - - -# logger -logging.basicConfig( - level=logging.DEBUG if arguments.debug or os.environ.get("DEBUG") else logging.INFO, - format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", +from ghastoolkit.octokit.dependencygraph import DependencyGraph +from ghastoolkit.octokit.github import GitHub +from ghastoolkit.utils.cli import CommandLine +from ghastoolkit.supplychain.__main__ import ( + runDefault as runSCDefault, + runOrgAudit as runSCOrgAudit, ) -print(__banner__) -# GitHub Init -GitHub.init( - repository=arguments.github_repository, - instance=arguments.github_instance, - token=arguments.github_token, -) +def header(name: str, width: int = 32): + logging.info("#" * width) + logging.info(f"{name:^32}") + logging.info("#" * width) + logging.info("") -if not GitHub.repository: - raise Exception(f"GitHub Repository must be set") -if arguments.mode in ["all", "codescanning"]: - header("Code Scanning") +def runCodeScanning(arguments): codescanning = CodeScanning(GitHub.repository) alerts = codescanning.getAlerts() - print(f"Total Alerts :: {len(alerts)}") + logging.info(f"Total Alerts :: {len(alerts)}") analyses = codescanning.getLatestAnalyses(GitHub.repository.reference) - print(f"\nTools: ({len(analyses)})") + logging.info(f"\nTools:") for analyse in analyses: tool = analyse.get("tool", {}).get("name") version = analyse.get("tool", {}).get("version") created_at = analyse.get("created_at") - print(f" - {tool} v{version} ({created_at})") + logging.info(f" - {tool} v{version} ({created_at})") + + +class MainCli(CommandLine): + """Main CLI.""" + + def arguments(self): + """Adding additional parsers from submodules.""" + self.addModes(["all"]) + + def run(self, arguments: Namespace): + """Run main CLI.""" + if arguments.version: + logging.info(f"v{__version__}") + return + + logging.info(__banner__) + if arguments.mode in ["all", "codescanning"]: + logging.info("") + header("Code Scanning") + runCodeScanning(arguments) -if arguments.mode in ["all", "dependencygraph"]: - header("Dependency Graph") + if arguments.mode in ["all", "dependencygraph"]: + logging.info("") + header("Dependency Graph") + runSCDefault(arguments) - depgraph = DependencyGraph(GitHub.repository) - bom = depgraph.exportBOM() - packages = bom.get("sbom", {}).get("packages", []) + if arguments.mode == "org-audit": + # run org audit with all products + # supplychain + runSCOrgAudit(arguments) + return - print(f"Total Dependencies :: {len(packages)}") - info = bom.get("sbom", {}).get("creationInfo", {}) - print(f"Created :: {info.get('created')}") +if __name__ == "__main__": + # Arguments + parser = MainCli(name) - print("\nTools:") - for tool in info.get("creators", []): - print(f" - {tool}") + parser.run(parser.parse_args()) diff --git a/vendor/ghastoolkit/codeql/__init__.py b/vendor/ghastoolkit/codeql/__init__.py index 8f78b4c..e69de29 100644 --- a/vendor/ghastoolkit/codeql/__init__.py +++ b/vendor/ghastoolkit/codeql/__init__.py @@ -1,2 +0,0 @@ -from ghastoolkit.codeql.consts import * -from ghastoolkit.codeql.databases import CodeQLDatabase diff --git a/vendor/ghastoolkit/codeql/__main__.py b/vendor/ghastoolkit/codeql/__main__.py new file mode 100644 index 0000000..60788ac --- /dev/null +++ b/vendor/ghastoolkit/codeql/__main__.py @@ -0,0 +1,38 @@ +"""CodeQL CLI for ghastoolkit.""" + +import logging +from argparse import Namespace +from ghastoolkit.codeql.cli import CodeQL +from ghastoolkit.utils.cli import CommandLine + + +class CodeQLCommandLine(CommandLine): + """CodeQL CLI.""" + + def arguments(self): + """CodeQL arguments.""" + if self.subparser: + self.addModes(["init", "analyze", "update"]) + + parser = self.parser.add_argument_group("codeql") + parser.add_argument("-b", "--binary") + parser.add_argument("-c", "--command", type=str) + + def run(self, arguments: Namespace): + codeql = CodeQL() + + if not codeql.exists(): + logging.error(f"Failed to find codeql on system") + exit(1) + + logging.debug(f"Found codeql on system :: '{' '.join(codeql.path_binary)}'") + + if arguments.version: + logging.info(f"CodeQL Version :: v{codeql.version}") + exit(0) + + +if __name__ == "__main__": + parser = CodeQLCommandLine("ghastoolkit-codeql") + parser.run(parser.parse_args()) + logging.info(f"Finished!") diff --git a/vendor/ghastoolkit/codeql/cli.py b/vendor/ghastoolkit/codeql/cli.py index 1c1098e..5c9070f 100644 --- a/vendor/ghastoolkit/codeql/cli.py +++ b/vendor/ghastoolkit/codeql/cli.py @@ -1,72 +1,247 @@ +"""This is the CodeQL CLI Module.""" + +import os +import csv import json import logging -import os -import subprocess -from sys import stdout +import shutil import tempfile -from typing import Optional +import subprocess +from glob import glob +from typing import List, Optional, Union from ghastoolkit.codeql.databases import CodeQLDatabase from ghastoolkit.codeql.results import CodeQLResults -from ghastoolkit.codeql.utils import findCodeBinary logger = logging.getLogger("ghastoolkit.codeql.cli") +def findCodeQLBinary() -> Optional[List[str]]: + """Find CodeQL Binary on current system.""" + actions_location = glob( + os.path.join( + os.environ.get("RUNNER_TOOL_CACHE", ""), + "CodeQL", + "*", + "x64", + "codeql", + "codeql", + ) + ) + logger.debug(f"CodeQL Action Location :: {actions_location}") + locations = [ + # generic + ["codeql"], + # local bin + ["/usr/bin/codeql/codeql"], + # gh cli + ["gh", "codeql"], + ] + # actions + if actions_location: + locations.append([actions_location[0]]) + + for location in locations: + try: + cmd = location + ["version"] + with open(os.devnull, "w") as null: + subprocess.check_call(cmd, stdout=null, stderr=null) + logger.debug(f"Found CodeQL :: {location}") + return location + except Exception as err: + logger.debug(f"Failed to find codeql :: {err}") + return [] + + class CodeQL: + """CodeQL CLI.""" + + CODEQL_BINARY: Optional[list[str]] = None + """CodeQL Binary""" + + CODEQL_EXTRACTOR_PATH: str = os.path.expanduser("~/.codeql/extractors") + """CodeQL Extractor Path""" + def __init__(self, binary: Optional[str] = None) -> None: + """Initialise CodeQL CLI Class.""" if binary: - self.path_binary = [binary] - else: - self.path_binary: Optional[list[str]] = findCodeBinary() + CodeQL.CODEQL_BINARY = [binary] + elif not CodeQL.CODEQL_BINARY: + CodeQL.CODEQL_BINARY = findCodeQLBinary() def exists(self) -> bool: - return self.path_binary != None + """Check codeql is present on the system.""" + return CodeQL.CODEQL_BINARY != None def runCommand(self, *argvs, display: bool = False) -> Optional[str]: - if not self.path_binary: + """Run CodeQL command without the binary / path.""" + logger.debug(f"Running CodeQL Command :: {argvs[0]}...") + if not CodeQL.CODEQL_BINARY: raise Exception("CodeQL binary / path was not found") cmd = [] - cmd.extend(self.path_binary) + cmd.extend(CodeQL.CODEQL_BINARY) cmd.extend(argvs) - if not display: - with open(os.devnull, "w") as null: - result = subprocess.run(cmd, stdout=null, stderr=null) + + logger.debug(f"Running Command :: {cmd}") + + if display: + subprocess.check_output(cmd) else: - result = subprocess.check_output(cmd) - return result.decode().strip() + result = subprocess.run(cmd, capture_output=True) + return result.stdout.decode().strip() @property def version(self) -> str: - return self.runCommand("version", "--format", "terse", display=True) + """Get CodeQL Version from the CLI binary.""" + version = self.runCommand("version", "--format", "terse") + if not version: + raise Exception("CodeQL version not found") + return version + + @property + def extractor_path(self) -> str: + """Third-Party extractor path location. Automatically created if the path does not exist.""" + if not os.path.exists(CodeQL.CODEQL_EXTRACTOR_PATH): + os.mkdir(CodeQL.CODEQL_EXTRACTOR_PATH) + return CodeQL.CODEQL_EXTRACTOR_PATH + + def createDatabase( + self, + database: CodeQLDatabase, + output: Optional[str] = None, + source: Optional[str] = None, + command: Optional[str] = None, + display: bool = False, + ) -> str: + """Create a CodeQL Database.""" + cmd = [ + "database", + "create", + "--search-path", + self.extractor_path, + "--overwrite", + "-j", + "0", + "-v", + "-l", + database.language, + ] + + if source: + cmd.extend(["-s", source]) + if command: + cmd.extend(["-c", command]) + + # TODO + output = output or database.path or database.path_download + if not output: + raise Exception("Unknown output location for creating CodeQL database") + + cmd.append(output) + + self.runCommand(*cmd, display=display) + + return output def runQuery( - self, database: CodeQLDatabase, path: Optional[str] = None + self, + database: CodeQLDatabase, + path: Optional[str] = None, + cpu: Optional[int] = None, + display: bool = False, + xterm_progress: str = "auto", + save_sarif: bool = False, ) -> CodeQLResults: + """Run a CodeQL Query on a CodeQL Database. + + This function will use all CPU cores by default. + """ if not database.path: raise Exception("CodeQL Database path is not set") path = path or database.default_pack - self.runCommand("database", "run-queries", database.path, path) - return self.getResults(database, path) + if path in [ + "security-extended", + "security-and-quality", + "security-experimental", + ]: + path = database.getSuite(path) + + logger.debug(f"Query path :: {path}") - def runRawQuery(self, path: str, database: CodeQLDatabase) -> list: + cores = str(cpu) if cpu else "0" + + self.runCommand( + "database", + "run-queries", + f"--xterm-progress={xterm_progress}", + "--search-path", + self.extractor_path, + "-j", + cores, + database.path, + path, + display=display, + ) + if path.endswith(".ql") or path.endswith(".qls"): + return self.getResults(database, path, save_sarif) + return self.getResults(database, save_sarif) + + def runQueryWithParameters(self, database: CodeQLDatabase, path: str, **kwargs): + """Run a CodeQL query with parameters.""" + return + + def runRawQuery( + self, + path: str, + database: CodeQLDatabase, + display: bool = False, + outputtype: str = "sarif", + ) -> Union[list, CodeQLResults]: + """Run raw query on a CodeQL Database.""" if not database.path: raise Exception("CodeQL Database path is not set") if not path.endswith(".ql"): raise Exception("runRawQuery requires a QL file") - self.runCommand("database", "run-queries", database.path, path) - bqrs = os.path.join( - database.path, "results", path.replace(":", "/").replace(".ql", ".bqrs") - ) - return self.readBqrs(bqrs).get("#select", {}).get("tuples", []) + self.runCommand("database", "run-queries", database.path, path, display=display) + + from ghastoolkit.codeql.packs.pack import CodeQLPack + + if ":" in path: + logger.debug("Running in pack mode") + pack_name, query_path = path.split(":", 1) + else: + logger.debug("Running in path mode") + + pack = CodeQLPack.findByQuery(path) + pack_name = pack.name + query_path = path.replace(pack.path + "/", "") + + logger.debug(f"Pack Name for query :: {pack_name} -> {query_path}") + + bqrs_query_path = query_path.replace(".ql", ".bqrs") + bqrs = os.path.join(database.path, "results", pack_name, bqrs_query_path) + + logger.debug(f"BQRS File location :: {bqrs}") + + if outputtype == "bqrs": + if not os.path.exists(bqrs): + raise Exception(f"BQRS file does not exist") + return self.readBqrs(bqrs, display=display) + elif outputtype == "sarif": + return self.getResults(database, path) + return [] def getResults( - self, database: CodeQLDatabase, path: Optional[str] = None + self, + database: CodeQLDatabase, + path: Optional[str] = None, + save_sarif: bool = False, ) -> CodeQLResults: + """Get the interpreted results from CodeQL.""" sarif = os.path.join(tempfile.gettempdir(), "codeql-result.sarif") cmd = [ "database", @@ -85,20 +260,48 @@ def getResults( with open(sarif, "r") as handle: data = json.load(handle) + if save_sarif: + shutil.copyfile( + sarif, os.path.join(database.path, f"{database.language}-results.sarif") + ) + # clean up + os.remove(sarif) + results = data.get("runs", [])[0].get("results", []) return CodeQLResults.loadSarifResults(results) - def readBqrs(self, bqrsfile: str) -> dict: - output = os.path.join(tempfile.gettempdir(), "codeql-result.bqrs") + def readBqrs( + self, + bqrsfile: str, + display: bool = False, + ) -> list[list[str]]: + """Read a BQRS file to get the raw results.""" + output = os.path.join(tempfile.gettempdir(), "codeql-result.csv") + logger.debug(f"Reading BQRS file :: {bqrsfile}") self.runCommand( - "bqrs", "decode", "--format", "json", "--output", output, bqrsfile + "bqrs", + "decode", + "--no-titles", + "--format", + "csv", + "--output", + output, + bqrsfile, + display=display, ) - + results = [] with open(output, "r") as handle: - return json.load(handle) + data = csv.reader(handle, delimiter=",") + for row in data: + results.append(row) + + # clean up + os.remove(output) + return results def __str__(self) -> str: - if self.path_binary: + """To String.""" + if CodeQL.CODEQL_BINARY: return f"CodeQL('{self.version}')" return "CodeQL()" diff --git a/vendor/ghastoolkit/codeql/databases.py b/vendor/ghastoolkit/codeql/databases.py index bd966dd..116d735 100644 --- a/vendor/ghastoolkit/codeql/databases.py +++ b/vendor/ghastoolkit/codeql/databases.py @@ -1,4 +1,5 @@ -from datetime import date, datetime +from datetime import datetime +from logging import log import os import shutil import zipfile @@ -29,17 +30,24 @@ @dataclass class CodeQLDatabase: + """CodeQL Database Abstraction to make our lives easier""" + name: str + """Name""" language: str + """CodeQL Langauge""" repository: Optional[Repository] = None - - # path to when the DB should be + """GitHub Repository (optional)""" path: Optional[str] = None + """Path to the CodeQL Database""" path_download: Optional[str] = None + """Path to download CodeQL DB if not path is set""" loc_baseline: int = 0 + """Lines of Code baseline in DB""" created: Optional[datetime] = None + """Created datetime infomation""" def __post_init__(self): if self.path: @@ -73,17 +81,25 @@ def check(self) -> bool: return False def exists(self) -> bool: + """Checks if the CodeQL Database exists""" return False if not self.path else os.path.exists(self.path) + @property + def root(self) -> str: + """Get the standard root location.""" + return __CODEQL_DATABASE_PATHS__[0] + @property def default_pack(self) -> str: + """Gets the default query pack for language""" return f"codeql/{self.language}-queries" def getSuite(self, name: str) -> str: + """Gets suite based on default pack""" return f"{self.default_pack}:codeql-suites/{self.language}-{name}.qls" def display_name(self, owner: Optional[str] = None) -> str: - """Display Name""" + """Get the display name""" if self.repository: own = self.repository.owner repo = self.repository.repo @@ -96,6 +112,7 @@ def display_name(self, owner: Optional[str] = None) -> str: return new_name.title().replace(" ", "") def createPath(self) -> Optional[str]: + """Create a path for CodeQL Database""" for root in __CODEQL_DATABASE_PATHS__: if not os.path.exists(root): continue @@ -115,6 +132,7 @@ def createDownloadPath(self, root: Optional[str] = None) -> str: @property def database_folder(self) -> str: + """Get CodeQL Database folder""" if self.repository: result = f"{self.language}-{self.repository.owner}-{self.repository.repo}" if self.repository.sha: @@ -126,7 +144,12 @@ def database_folder(self) -> str: @staticmethod def loadFromYml(path: str) -> "CodeQLDatabase": - """Load from YAML / YML file""" + """Load from YAML / YML file. + + **Example:** + >>> db = CodeQLDatabase.loadFromYml("codeql-db") + + """ if not os.path.exists(path): raise Exception("CodeQL Database YML does not exist") if not path.endswith(".yml"): @@ -141,7 +164,7 @@ def loadFromYml(path: str) -> "CodeQLDatabase": return db def loadDatabaseYml(self, path: str): - """Load content from YML""" + """Load content from YML file.""" if not os.path.exists(path): raise Exception("CodeQL Database YML does not exist") if not path.endswith(".yml"): @@ -162,9 +185,11 @@ def loadDatabaseYml(self, path: str): creation_time, _ = creation_time.split(".", 1) self.created = datetime.fromisoformat(creation_time) - def downloadDatabase(self, output: Optional[str], use_cache: bool = True) -> str: - """Download CodeQL database""" - output = output or self.path or self.path_download + def downloadDatabase( + self, output: Optional[str] = None, use_cache: bool = True + ) -> str: + """Download CodeQL Database.""" + output = output or self.path or self.root if not output: raise Exception(f"CodeQL Database path not set") @@ -183,8 +208,10 @@ def downloadDatabase(self, output: Optional[str], use_cache: bool = True) -> str logger.debug(f"Creating path: {output}") os.makedirs(output) - output_zip = os.path.join(output, self.database_folder + ".tar.gz") - output_db = os.path.join(output, self.database_folder) + output_zip = os.path.join( + tempfile.gettempdir(), self.database_folder + ".tar.gz" + ) + output_db = os.path.join(tempfile.gettempdir(), self.database_folder) # Deleting cached files if not use_cache: @@ -196,7 +223,7 @@ def downloadDatabase(self, output: Optional[str], use_cache: bool = True) -> str os.remove(output_zip) if not os.path.exists(output_zip): - logger.info("Downloading CodeQL Database from GitHub") + logger.debug("Downloading CodeQL Database from GitHub") headers = { "Accept": "application/zip", @@ -210,31 +237,42 @@ def downloadDatabase(self, output: Optional[str], use_cache: bool = True) -> str f.write(chunk) else: - logger.info("Database archive is present on system, skipping download...") + logger.debug("Database archive is present on system, skipping download...") - logger.info(f"Extracting archive data :: {output_zip}") + logger.debug(f"Extracting archive data :: {output_zip}") # SECURITY: Do we trust this DB? with zipfile.ZipFile(output_zip) as zf: zf.extractall(output_db) - logger.info(f" >>> {output_db}") - codeql_lang_path = os.path.join(output_db, self.language) + logger.debug(f" >>> {output_db}") + # CodeQL DB is in a folder called `codeql_db` or the language name + lang_path = os.path.join(output_db, self.language) + codeql_db_path = ( + lang_path + if os.path.exists(lang_path) + else os.path.join(output_db, "codeql_db") + ) - if os.path.exists(codeql_lang_path): - return codeql_lang_path + if os.path.exists(codeql_db_path): + logger.debug(f"Moving Database...") - for codeql_dir in os.listdir(output_db): - codeql_dir = os.path.join(output_db, codeql_dir) - if os.path.isdir(codeql_dir): - return codeql_dir + if os.path.exists(output): + logger.debug(f"Removing old DB :: {output}") + shutil.rmtree(output) + + shutil.move(codeql_db_path, output) + self.path = output + return output raise Exception(f"Database downloaded but not DB files...") class CodeQLDatabases(list[CodeQLDatabase]): + """List of CodeQL Databases.""" + def loadDefault(self): - """Load Databases from standard locations""" + """Load Databases from standard locations.""" for location in __CODEQL_DATABASE_PATHS__: if not os.path.exists(location): continue @@ -242,13 +280,13 @@ def loadDefault(self): @staticmethod def loadLocalDatabase() -> "CodeQLDatabases": - """Load all Local Databases""" + """Load all Local Databases.""" db = CodeQLDatabases() db.loadDefault() return db def getRemoteDatabases(self, repository: Repository): - """Find all remote databases and return a list of them""" + """Find all remote databases and return a list of them.""" cs = CodeScanning(repository) databases = cs.getCodeQLDatabases() for db in databases: @@ -256,20 +294,18 @@ def getRemoteDatabases(self, repository: Repository): if not lang: raise Exception(f"CodeQL remote language is not set") self.append( - CodeQLDatabase( - f"{repository.repo}-{lang}", language=lang, repository=repository - ) + CodeQLDatabase(repository.repo, language=lang, repository=repository) ) @staticmethod def loadRemoteDatabases(repository: Repository) -> "CodeQLDatabases": - """Use API to find all the databases and return a list of them""" + """Use API to find all the databases and return a list of them.""" dbs = CodeQLDatabases() dbs.getRemoteDatabases(repository) return dbs def findDatabases(self, path: str): - """Find databases based on a path (recursive)""" + """Find databases based on a path (recursive).""" if not os.path.exists(path): raise Exception(f"Path does not exist: {path}") @@ -280,14 +316,14 @@ def findDatabases(self, path: str): self.append(CodeQLDatabase.loadFromYml(path)) def get(self, name: str) -> Optional[CodeQLDatabase]: - """Get a database by name""" + """Get a database by name.""" for db in self: if db.name == name: return db return def getLanguages(self, language: str) -> "CodeQLDatabases": - """Get a list of databases by language""" + """Get a list of databases by language.""" dbs = CodeQLDatabases() for db in dbs: if db.language == language: @@ -295,6 +331,6 @@ def getLanguages(self, language: str) -> "CodeQLDatabases": return dbs def downloadDatabases(self): - """Download all databases from GitHub""" + """Download all databases from GitHub.""" for db in self: db.downloadDatabase(None) diff --git a/vendor/ghastoolkit/codeql/dataextensions/__init__.py b/vendor/ghastoolkit/codeql/dataextensions/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/ghastoolkit/codeql/dataextensions/__init__.py @@ -0,0 +1 @@ + diff --git a/vendor/ghastoolkit/codeql/dataextensions/__main__.py b/vendor/ghastoolkit/codeql/dataextensions/__main__.py new file mode 100644 index 0000000..ed8558c --- /dev/null +++ b/vendor/ghastoolkit/codeql/dataextensions/__main__.py @@ -0,0 +1,30 @@ +import logging +import os +import argparse +from ghastoolkit.codeql.dataextensions.ext import DataExtensions + +logging.basicConfig(format="%(message)s") +parser = argparse.ArgumentParser("ghastoolkit-codeql-dataextensions") +parser.add_argument("-l", "--language", required=True) +parser.add_argument("-i", "--input", required=True) + +args = parser.parse_args() + +de = DataExtensions(args.language) + +if os.path.isfile(args.input): + de.load(args.input) +elif os.path.isdir(args.input): + for root, dirs, files in os.walk(args.input): + for fl in files: + path = os.path.join(root, fl) + _, ext = os.path.splitext(fl) + if ext in [".yml", ".yaml"]: + de.load(path) + +logging.info(f" Language :: {args.language} (loaded: {len(de.paths)})") +logging.info(f" Sources :: {len(de.sources)}") +logging.info(f" Sinks :: {len(de.sinks)}") +logging.info(f" Summaries :: {len(de.summaries)}") +logging.info(f" Types :: {len(de.types)}") +logging.info(f" Neutrals :: {len(de.neutrals)}") diff --git a/vendor/ghastoolkit/codeql/dataextensions/ext.py b/vendor/ghastoolkit/codeql/dataextensions/ext.py new file mode 100644 index 0000000..d2985b1 --- /dev/null +++ b/vendor/ghastoolkit/codeql/dataextensions/ext.py @@ -0,0 +1,87 @@ +import os +import logging +from typing import List, Optional, Union +from dataclasses import dataclass, field + +import yaml + +from ghastoolkit.codeql.dataextensions.models import ( + CompiledSinks, + CompiledSources, + CompiledSummaries, + CompiledNeutrals, + __MODELES__, + InterpretedSink, + InterpretedSource, + InterpretedSummary, + InterpretedType, + InterpretedTypeVariable, +) + +LANGUAGE_TYPES = {"csharp": "Compiled", "java": "Compiled", "javascript": "Interpreted"} + +logger = logging.getLogger("ghastoolkit.codeql.dataextensions") + + +@dataclass +class DataExtensions: + language: str + pack: Optional[str] = None + paths: List[str] = field(default_factory=list) + + sources: List[Union[CompiledSources, InterpretedSource]] = field( + default_factory=list + ) + + sinks: List[Union[CompiledSinks, InterpretedSink]] = field(default_factory=list) + + summaries: List[Union[CompiledSummaries, InterpretedSummary]] = field( + default_factory=list + ) + + types: List[Union[InterpretedType, InterpretedTypeVariable]] = field( + default_factory=list + ) + + neutrals: List[CompiledNeutrals] = field(default_factory=list) + + def __post_init__(self): + if not self.pack: + self.pack = f"codeql/{self.language}-queries" + + def load(self, path: str): + if not os.path.exists(path): + raise Exception(f"Path does not exist :: {path}") + logger.debug(f"Loading data extension from path :: '{path}'") + with open(path, "r") as handle: + data = yaml.safe_load(handle) + + language_type = LANGUAGE_TYPES.get(self.language) + + for ext in data.get("extensions"): + extensible = ext.get("addsTo", {}).get("extensible", "") + ext_name = extensible.replace("Model", "") + class_name = f"{language_type}{ext_name.title()}" + clss = __MODELES__.get(class_name) + if not clss: + logger.error(f"Unknown class :: {class_name}") + continue + + for data_ext in ext.get("data", []): + i = clss(*data_ext) + if ext_name == "source": + self.sources.append(i) + elif ext_name == "sink": + self.sinks.append(i) + elif ext_name == "summary": + self.summaries.append(i) + elif ext_name == "neutral": + self.neutrals.append(i) + elif ext_name == "type": + self.types.append(i) + elif ext_name == "typeVariable": + self.types.append(i) + else: + logger.warning(f"Unknown data extension :: {ext_name}") + + self.paths.append(path) diff --git a/vendor/ghastoolkit/codeql/dataextensions/models.py b/vendor/ghastoolkit/codeql/dataextensions/models.py new file mode 100644 index 0000000..338770c --- /dev/null +++ b/vendor/ghastoolkit/codeql/dataextensions/models.py @@ -0,0 +1,171 @@ +from dataclasses import dataclass +from typing import List + +MODELS_AS_DATA = { + "CompiledSources": [ + "package", + "type", + "subtypes", + "name", + "signature", + "ext", + "output", + "kind", + "provenance", + ], + "CompiledSinks": [ + "package", + "type", + "subtypes", + "name", + "signature", + "ext", + "input", + "kind", + "provenance", + ], + "CompiledSummaries": [ + "package", + "type", + "subtypes", + "name", + "signature", + "ext", + "input", + "output", + "kind", + "provenance", + ], + "CompiledNeutrals": ["package", "type", "name", "signature", "kind", "provenance"], +} + + +class ModelAsData: + def generateMad(self, headers: List[str]) -> List[str]: + result = [] + for header in headers: + if hasattr(self, header): + result.append(getattr(self, header)) + elif hasattr(self, f"object_{header}"): + result.append(getattr(self, f"object_{header}")) + return result + + def generate(self) -> List[str]: + return self.generateMad(MODELS_AS_DATA.get(self.__class__.__name__, [])) + + +@dataclass +class CompiledSources(ModelAsData): + """Compile Sources""" + + package: str + object_type: str + subtypes: bool + name: str + signature: str + ext: str + output: str + kind: str + provenance: str = "manual" + + +@dataclass +class CompiledSinks(ModelAsData): + """Compile Sources""" + + package: str + object_type: str + subtypes: bool + name: str + signature: str + ext: str + object_input: str + kind: str + provenance: str = "manual" + + +@dataclass +class CompiledSummaries(ModelAsData): + """Compiled Summaries""" + + package: str + object_type: str + subtypes: bool + name: str + signature: str + ext: str + object_input: str + output: str + kind: str + provenance: str = "manual" + + +@dataclass +class CompiledNeutrals(ModelAsData): + """Compiled Neutrals""" + + package: str + object_type: str + name: str + signature: str + kind: str + provenance: str = "manual" + + +@dataclass +class InterpretedSource(ModelAsData): + """Interpreted Source""" + + object_type: str + path: str + kind: str + + +@dataclass +class InterpretedSink(ModelAsData): + """Interpreted Sink""" + + object_type: str + path: str + kind: str + + +@dataclass +class InterpretedSummary(ModelAsData): + """Interpreted Summary""" + + object_type: str + path: str + object_input: str + output: str + kind: str + + +@dataclass +class InterpretedType(ModelAsData): + """Interpreted Type""" + + object_type1: str + object_type2: str + path: str + + +@dataclass +class InterpretedTypeVariable(ModelAsData): + """Interpreted Type""" + + object_type1: str + object_type2: str + + +__MODELES__ = { + "CompiledSink": CompiledSinks, + "CompiledSource": CompiledSources, + "CompiledSummary": CompiledSummaries, + "CompiledNeutral": CompiledNeutrals, + "InterpretedSource": InterpretedSource, + "InterpretedSink": InterpretedSink, + "InterpretedSummary": InterpretedSummary, + "InterpretedType": InterpretedType, + "InterpretedTypevariable": InterpretedTypeVariable, +} diff --git a/vendor/urllib3/contrib/_securetransport/__init__.py b/vendor/ghastoolkit/codeql/packs/__init__.py similarity index 100% rename from vendor/urllib3/contrib/_securetransport/__init__.py rename to vendor/ghastoolkit/codeql/packs/__init__.py diff --git a/vendor/ghastoolkit/codeql/packs/__main__.py b/vendor/ghastoolkit/codeql/packs/__main__.py new file mode 100644 index 0000000..cbba5c0 --- /dev/null +++ b/vendor/ghastoolkit/codeql/packs/__main__.py @@ -0,0 +1,117 @@ +"""GitHub CodeQL Packs CLI.""" + +import os +import logging +from argparse import Namespace +from typing import Optional + +from yaml import parse +from ghastoolkit.codeql.packs.packs import CodeQLPacks +from ghastoolkit.utils.cli import CommandLine + + +def codeqlPackPublish(arguments: Namespace, packs: CodeQLPacks): + if not arguments.packs or arguments.packs == "": + logging.error(f"CodeQL Pack path must be provided") + exit(1) + + for pack in packs: + remote = pack.remote_version + logging.info(f"CodeQL Pack Remote Version :: {remote}") + + if pack.version != remote: + logging.info("Publishing CodeQL Pack...") + pack.publish() + logging.info(f"CodeQL Pack published :: {pack}") + else: + logging.info(f"CodeQL Pack is up to date :: {pack}") + + +class CodeQLPacksCommandLine(CommandLine): + def arguments(self): + self.addModes(["publish", "queries", "compile", "version"]) + default_pack_path = os.path.expanduser("~/.codeql/packages") + + parser = self.parser.add_argument_group("codeql-packs") + parser.add_argument( + "--packs", + type=str, + default=os.environ.get("CODEQL_PACKS_PATH", default_pack_path), + help="CodeQL Packs Path", + ) + parser.add_argument( + "--bump", + type=str, + default="patch", + help="CodeQL Pack Version Bump", + ) + parser.add_argument( + "--suite", + type=str, + default="default", + help="CodeQL Pack Suite", + ) + parser.add_argument( + "--latest", + action="store_true", + help="Update to latest CodeQL Pack Dependencies", + ) + parser.add_argument("--warnings", action="store_true", help="Enable Warnings") + + def run(self, arguments: Optional[Namespace] = None): + if not arguments: + arguments = self.parse_args() + + logging.info(f"CodeQL Packs Path :: {arguments.packs}") + packs = CodeQLPacks(arguments.packs) + + if arguments.latest: + logging.info("Updating CodeQL Pack Dependencies...") + for pack in packs: + pack.updateDependencies() + + if arguments.mode == "publish": + codeqlPackPublish(arguments, packs) + + elif arguments.mode == "version": + logging.info(f"Loading packs from :: {arguments.packs}") + + for pack in packs: + old_version = pack.version + pack.updateVersion(arguments.bump) + pack.updatePack() + logging.info( + f"CodeQL Pack :: {pack.name} :: {old_version} -> {pack.version}" + ) + + elif arguments.mode == "queries": + suite = arguments.suite or "code-scanning" + for pack in packs: + logging.info(f"CodeQL Pack :: {pack}") + + if not pack.library: + if suite == "default" and pack.default_suite: + suite = pack.default_suite + + queries = pack.resolveQueries(suite) + logging.info(f"Queries: {len(queries)}") + for query in queries: + logging.info(f"- {query}") + + elif arguments.mode == "compile": + for pack in packs: + logging.info(f"CodeQL Pack :: {pack}") + + else: + logging.info("CodeQL Packs") + for pack in packs: + logging.info(f"- {pack}") + + for dep in pack.dependencies: + logging.info(f" |-> {dep}") + + +if __name__ == "__main__": + parser = CodeQLPacksCommandLine("ghastoolkit-codeql-packs") + parser.run(parser.parse_args()) + logging.info(f"Finished!") diff --git a/vendor/ghastoolkit/codeql/packs/pack.py b/vendor/ghastoolkit/codeql/packs/pack.py new file mode 100644 index 0000000..eb763a1 --- /dev/null +++ b/vendor/ghastoolkit/codeql/packs/pack.py @@ -0,0 +1,230 @@ +"""CodeQL Packs.""" + +import os +import json +import glob +import logging +from typing import Any, List, Optional +from semantic_version import Version +import yaml + +from ghastoolkit.codeql.cli import CodeQL + + +logger = logging.getLogger("ghastoolkit.codeql.packs") + + +class CodeQLPack: + """CodeQL Pack class.""" + + codeql_packages: str = os.path.join(os.path.expanduser("~"), ".codeql", "packages") + """CodeQL Packages Location""" + + def __init__( + self, + path: Optional[str] = None, + library: Optional[bool] = None, + name: Optional[str] = None, + version: Optional[str] = None, + cli: Optional[CodeQL] = None, + ) -> None: + """Initialise CodeQL Pack.""" + self.cli = cli or CodeQL() + + self.path = path # dir + self.library: bool = library or False + self.name: str = name or "" + self.version: str = version or "0.0.0" + self.dependencies: List["CodeQLPack"] = [] + + self.default_suite: Optional[str] = None + self.warnOnImplicitThis: Optional[bool] = None + self.dbscheme: Optional[str] = None + self.extractor: Optional[str] = None + self.upgrades: Optional[str] = None + self.groups: Optional[list[str]] = None + + if path: + # if its a file + if os.path.isfile(path) and path.endswith("qlpack.yml"): + path = os.path.realpath(os.path.dirname(path)) + + self.path = os.path.realpath(os.path.expanduser(path)) + + if os.path.exists(self.qlpack): + self.load() + + logger.debug(f"Finished loading Pack :: {self}") + + @property + def qlpack(self) -> str: + """QL Pack Location.""" + if self.path: + return os.path.join(self.path, "qlpack.yml") + return "qlpack.yml" + + def validate(self) -> bool: + """Validate and check if the path is a valid CodeQL Pack.""" + return os.path.exists(self.qlpack) + + def load(self): + """Load QLPack file.""" + if not os.path.exists(self.qlpack): + logger.warning(f"Pack Path :: {self.path}") + raise Exception(f"Failed to find qlpack file") + + logger.debug(f"Loading Pack from path :: {self.path}") + with open(self.qlpack, "r") as handle: + data = yaml.safe_load(handle) + + self.library = bool(data.get("library")) + self.name = data.get("name", "") + self.version = data.get("version", "") + self.default_suite = data.get("defaultSuiteFile") + + self.warnOnImplicitThis = data.get("warnOnImplicitThis") + self.dbscheme = data.get("dbscheme") + self.extractor = data.get("extractor") + self.upgrades = data.get("upgrades") + self.groups = data.get("groups") + + for name, version in data.get("dependencies", {}).items(): + self.dependencies.append(CodeQLPack(name=name, version=version)) + + @staticmethod + def findByQuery(query_path: str) -> Optional["CodeQLPack"]: + """Find Pack by query path.""" + stack = query_path.split("/") + if query_path.startswith("/"): + stack.insert(0, "/") + + while len(stack) != 0: + path = os.path.join(*stack, "qlpack.yml") + if os.path.exists(path): + return CodeQLPack(path) + + stack.pop(-1) + return + + def run(self, *args, display: bool = False) -> Optional[str]: + """Run Pack command.""" + return self.cli.runCommand("pack", *args, display=display) + + def create(self) -> str: + """Create / Compile a CodeQL Pack.""" + logger.debug(f"Creating CodeQL Pack :: {self.name}") + home = os.path.expanduser("~") + packages = os.path.join(home, ".codeql", "packages") + self.run("create", "--output", packages, self.path) + return os.path.join(packages, self.name, self.version) + + def publish(self): + """Publish a CodeQL Pack to a remote registry.""" + self.run("publish", self.path) + + @staticmethod + def download(name: str, version: Optional[str] = None) -> "CodeQLPack": + """Download a CodeQL Pack.""" + cli = CodeQL() + full_name = f"{name}@{version}" if version else name + logger.debug(f"Download Pack :: {full_name}") + + cli.runCommand("pack", "download", full_name) + base = os.path.join(CodeQLPack.codeql_packages, name) + if version: + return CodeQLPack(os.path.join(base, version)) + else: + return CodeQLPack(glob.glob(f"{base}/**/")[0]) + + def install(self, display: bool = False): + """Install Dependencies for a CodeQL Pack.""" + self.run("install", self.path, display=display) + + def updateDependencies(self, version: str = "latest"): + for dep in self.dependencies: + if version == "latest": + dep.version = dep.remote_version + self.updatePack() + + def resolveQueries(self, suite: Optional[str] = None) -> List[str]: + """Resolve all the queries in a Pack and return them.""" + results = [] + if self.path: + pack = os.path.join(self.path, suite) if suite else self.path + else: + pack = f"{self.name}:{suite}" if suite else self.name + + result = self.cli.runCommand( + "resolve", "queries", "--format", "bylanguage", pack + ) + if result: + for _, queries in json.loads(result).get("byLanguage", {}).items(): + results.extend(list(queries.keys())) + return results + + @property + def remote_version(self) -> Optional[str]: + """Gets the remote version of the pack if possible.""" + from ghastoolkit import CodeScanning + + try: + cs = CodeScanning() + latest_remote = cs.getLatestPackVersion(self.name) + latest_version = ( + latest_remote.get("metadata", {}) + .get("container", {}) + .get("tags", ["NA"])[0] + ) + return latest_version + except Exception: + logging.debug(f"Error getting remote version") + return None + + def updatePack(self) -> dict[str, Any]: + """Update Local CodeQL Pack.""" + data = { + "library": self.library, + "name": self.name, + "version": self.version, + "defaultSuiteFile": self.default_suite, + "warnOnImplicitThis": self.warnOnImplicitThis, + "dbscheme": self.dbscheme, + "extractor": self.extractor, + "upgrades": self.upgrades, + "groups": self.groups, + } + data = {k: v for k, v in data.items() if v is not None} + + if self.dependencies: + data["dependencies"] = {} + for dep in self.dependencies: + data["dependencies"][dep.name] = dep.version + + if self.path: + logger.debug(f"Saving pack to path :: {self.path}") + with open(self.qlpack, "w") as handle: + yaml.safe_dump(data, handle, sort_keys=False) + + return data + + def updateVersion(self, name: str = "patch", version: Optional[str] = None) -> str: + """Update CodeQL Pack version.""" + if version: + self.version = version + return version + + v = Version(self.version) + if name == "major": + v = v.next_major() + elif name == "minor": + v = v.next_minor() + elif name == "patch": + v = v.next_patch() + self.version = str(v) + return self.version + + def __str__(self) -> str: + """To String.""" + if self.name != "": + return f"CodeQLPack('{self.name}', '{self.version}')" + return f"CodeQLPack('{self.path}')" diff --git a/vendor/ghastoolkit/codeql/packs/packs.py b/vendor/ghastoolkit/codeql/packs/packs.py new file mode 100644 index 0000000..28d40e7 --- /dev/null +++ b/vendor/ghastoolkit/codeql/packs/packs.py @@ -0,0 +1,53 @@ +"""CodeQL Packs.""" + +import os +import logging +from typing import List, Optional + +from ghastoolkit.codeql.packs.pack import CodeQLPack + + +logger = logging.getLogger("ghastoolkit.codeql.packs") + + +class CodeQLPacks: + """CodeQL List of Packs.""" + + def __init__(self, path: Optional[str] = None) -> None: + """Initialise CodeQLPacks.""" + self.packs: List[CodeQLPack] = [] + + if path: + self.load(os.path.realpath(os.path.expanduser(path))) + + def append(self, pack: CodeQLPack): + """Append a CodeQLPack.""" + self.packs.append(pack) + + def load(self, path: str): + """Load packs from path.""" + if not os.path.exists(path): + raise Exception("Path does not exist") + + logger.debug(f"Loading from path :: {path}") + lib_path = os.path.join(".codeql", "libraries") + + for root, _, files in os.walk(path): + for file in files: + if file == "qlpack.yml": + fpath = os.path.join(root, file) + + if lib_path in fpath: + continue + self.append(CodeQLPack(fpath)) + + def __iter__(self): + return self.packs.__iter__() + + def __len__(self) -> int: + """Get length / amount of loaded packs.""" + return len(self.packs) + + def __str__(self) -> str: + """To String.""" + return f"CodeQLPacks('{len(self)}')" diff --git a/vendor/ghastoolkit/codeql/results.py b/vendor/ghastoolkit/codeql/results.py index db2af9b..d3ce462 100644 --- a/vendor/ghastoolkit/codeql/results.py +++ b/vendor/ghastoolkit/codeql/results.py @@ -1,34 +1,51 @@ +"""CodeQL Results.""" + from dataclasses import dataclass, field from typing import Optional @dataclass class CodeLocation: + """Code Location Module.""" + uri: str + """URI to the location where the result occurs""" start_line: int + """Start line of the result""" start_column: Optional[int] = None + """Start column of the result""" end_line: Optional[int] = None + """End line of the result""" end_column: Optional[int] = None + """End line of the result""" def __str__(self) -> str: + """To String.""" return f"{self.uri}#{self.start_line}" @dataclass class CodeResult: + """Code Result.""" + rule_id: str + """Rule ID""" message: str + """Message of the result""" locations: list[CodeLocation] = field(default_factory=list) + """Locations of the results""" def __str__(self) -> str: + """To String.""" if len(self.locations) == 1: return f"CodeResult('{self.rule_id}', '{self.locations[0]}')" return f"CodeResult('{self.rule_id}', {len(self.locations)})" @staticmethod def loadSarifLocations(data: list[dict]) -> list["CodeLocation"]: + """Load SARIF Locations.""" locations = [] for loc in data: physical = loc.get("physicalLocation", {}) @@ -46,8 +63,11 @@ def loadSarifLocations(data: list[dict]) -> list["CodeLocation"]: class CodeQLResults(list): + """CodeQL Results.""" + @staticmethod def loadSarifResults(results: list[dict]) -> "CodeQLResults": + """Load SARIF Results.""" result = CodeQLResults() for alert in results: diff --git a/vendor/ghastoolkit/codeql/utils.py b/vendor/ghastoolkit/codeql/utils.py deleted file mode 100644 index 43ad461..0000000 --- a/vendor/ghastoolkit/codeql/utils.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -import subprocess -from typing import Optional - - -def findCodeBinary() -> Optional[list[str]]: - locations = [["codeql"], ["gh", "codeql"], ["/usr/bin/codeql/codeql"]] - - for location in locations: - try: - cmd = location + ["version"] - with open(os.devnull, "w") as null: - subprocess.check_call(cmd, stdout=null, stderr=null) - - return location - except Exception as err: - print(err) - - return diff --git a/vendor/ghastoolkit/errors.py b/vendor/ghastoolkit/errors.py new file mode 100644 index 0000000..970ec20 --- /dev/null +++ b/vendor/ghastoolkit/errors.py @@ -0,0 +1,50 @@ +# GHASToolkit Errors + + +from typing import List, Optional + + +class GHASToolkitError(Exception): + """Base class for GHASToolkit errors.""" + + def __init__( + self, + message: Optional[str] = None, + docs: Optional[str] = None, + permissions: Optional[List[str]] = [], + status: Optional[int] = None, + ) -> None: + self.message = message + self.docs = docs + self.permissions = permissions + self.status = status + + super().__init__(message) + + def __str__(self) -> str: + msg = "" + + if hasattr(self, "message"): + msg = self.message + else: + msg = "An error occurred" + + if status := self.status: + msg += f" (status code: {status})" + + if permissions := self.permissions: + msg += "\n\nPermissions Required:" + for perm in permissions: + msg += f"\n- {perm}" + if docs := self.docs: + msg += f"\n\nFor more information, see: {docs}" + + return msg + + +class GHASToolkitTypeError(GHASToolkitError): + """Raised when an invalid type is passed.""" + + +class GHASToolkitAuthenticationError(GHASToolkitError): + """Raised when an authentication error occurs.""" diff --git a/vendor/ghastoolkit/octokit/advisories.py b/vendor/ghastoolkit/octokit/advisories.py new file mode 100644 index 0000000..473b792 --- /dev/null +++ b/vendor/ghastoolkit/octokit/advisories.py @@ -0,0 +1,120 @@ +"""GitHub Security Advisories API.""" + +from typing import Dict, Optional +from ghastoolkit.errors import GHASToolkitError, GHASToolkitTypeError +from ghastoolkit.octokit.github import GitHub, Repository +from ghastoolkit.octokit.octokit import RestRequest +from ghastoolkit.supplychain.advisories import Advisories, Advisory, AdvisoryAffect + + +class SecurityAdvisories: + """Security Advisories.""" + + def __init__(self, repository: Optional[Repository] = None) -> None: + """Security Advisories REST API. + + https://docs.github.com/en/rest/security-advisories/repository-advisories + """ + self.repository = repository or GitHub.repository + if not self.repository: + raise Exception("SecurityAdvisories requires Repository to be set") + self.rest = RestRequest(self.repository) + + def getAdvisories(self) -> Advisories: + """Get list of security advisories from a repository. + + https://docs.github.com/en/rest/security-advisories/repository-advisories#list-repository-security-advisories + """ + results = self.rest.get( + "/repos/{owner}/{repo}/security-advisories", authenticated=True + ) + if isinstance(results, list): + advisories = Advisories() + for advisory in results: + advisories.append(self.loadAdvisoryData(advisory)) + return advisories + + raise GHASToolkitTypeError( + f"Error getting advisories from repository", + docs="https://docs.github.com/en/rest/security-advisories/repository-advisories#list-repository-security-advisories", + ) + + def getAdvisory(self, ghsa_id: str) -> Advisory: + """Get advisory by ghsa id. + + https://docs.github.com/en/rest/security-advisories/repository-advisories#get-a-repository-security-advisory + """ + result = self.rest.get( + "/repos/{owner}/{repo}/security-advisories/{ghsa_id}", + {"ghsa_id": ghsa_id}, + authenticated=True, + ) + if isinstance(result, dict): + return self.loadAdvisoryData(result) + + raise GHASToolkitTypeError( + f"Error getting advisory by id", + docs="https://docs.github.com/en/rest/security-advisories/repository-advisories#get-a-repository-security-advisory", + ) + + def createAdvisory( + self, advisory: Advisory, repository: Optional[Repository] = None + ): + """Create a GitHub Security Advisories for a repository. + + https://docs.github.com/en/rest/security-advisories/repository-advisories#create-a-repository-security-advisory + """ + raise GHASToolkitError("Unsupported feature") + + def createPrivateAdvisory( + self, advisory: Advisory, repository: Optional[Repository] = None + ): + """Create a GitHub Security Advisories for a repository.""" + raise Exception("Unsupported feature") + + def updateAdvisory( + self, advisory: Advisory, repository: Optional[Repository] = None + ): + """Update GitHub Security Advisory. + + https://docs.github.com/en/rest/security-advisories/repository-advisories#update-a-repository-security-advisory + """ + raise GHASToolkitError("Unsupported feature") + + def loadAdvisoryData(self, data: Dict) -> Advisory: + """Load Advisory from API data.""" + ghsa_id = data.get("ghsa_id") + severity = data.get("severity") + + if not ghsa_id or not severity: + raise Exception("Data is not an advisory") + + aliases = [] + if data.get("cve_id"): + aliases.append(data.get("cve_id")) + + adv = Advisory( + ghsa_id, + severity, + aliases=aliases, + summary=data.get("summary", ""), + cwes=data.get("cwe_ids", []), + ) + # affected + for vuln in data.get("vulnerabilities", []): + introduced = vuln.get("vulnerable_version_range") + if introduced == "": + introduced = None + fixed = vuln.get("patched_versions") + if fixed == "": + fixed = None + + affect = AdvisoryAffect( + ecosystem=vuln.get("package", {}).get("ecosystem", ""), + package=vuln.get("package", {}).get("name", ""), + introduced=introduced, + fixed=fixed, + ) + adv.affected.append(affect) + + return adv diff --git a/vendor/ghastoolkit/octokit/clearlydefined.py b/vendor/ghastoolkit/octokit/clearlydefined.py new file mode 100644 index 0000000..8724332 --- /dev/null +++ b/vendor/ghastoolkit/octokit/clearlydefined.py @@ -0,0 +1,72 @@ +import logging +from typing import Any, Optional +from requests import Session + +from ghastoolkit.errors import GHASToolkitError +from ghastoolkit.supplychain.dependencies import Dependency + + +logger = logging.getLogger("ghastoolkit.octokit.clearlydefined") + +PROVIDEDERS = { + "cocoapods": "cocoapods", + "cratesio": "cratesio", + "deb": "debian", + "github": "github", + "githubactions": "github", + "gitlab": "gitlab", + "maven": "mavencentral", + "npm": "npmjs", + "nuget": "nuget", + # packagist, + "pypi": "pypi", + "gems": "rubygems", +} + + +class ClearlyDefined: + def __init__(self) -> None: + self.api = "https://api.clearlydefined.io" + self.session = Session() + self.session.headers = {"Accept": "*/*"} + + def createCurationUrl(self, dependency: Dependency) -> Optional[str]: + if not dependency.manager: + return + provider = PROVIDEDERS.get(dependency.manager, dependency.manager) + + url = f"{self.api}/curations/{dependency.manager}/{provider}/" + url += dependency.namespace or "-" + url += f"/{dependency.name}" + return url + + def getCurations(self, dependency: Dependency) -> dict[str, Any]: + if not dependency.manager: + raise GHASToolkitError(f"Dependency manager / type must be set") + + url = self.createCurationUrl(dependency) + if not url: + logger.warning(f"Url failed to be created from dependency :: {dependency}") + return {} + + resp = self.session.get(url) + if resp.status_code != 200: + raise Exception(f"Failed to access API") + + return resp.json() + + def getLicenses(self, dependency: Dependency) -> list[str]: + licenses = set() + try: + data = self.getCurations(dependency) + for _, curation in data.get("curations", {}).items(): + curlicense = curation.get("licensed", {}).get("declared") + if curlicense: + licenses.add(curlicense) + except KeyboardInterrupt: + raise Exception("Keyboard Interrupt") + except Exception as err: + logger.warning(f"Error getting curation data :: {dependency}") + logger.warning(f"Error :: {err}") + + return list(licenses) diff --git a/vendor/ghastoolkit/octokit/codescanning.py b/vendor/ghastoolkit/octokit/codescanning.py index 717dc84..991c1e3 100644 --- a/vendor/ghastoolkit/octokit/codescanning.py +++ b/vendor/ghastoolkit/octokit/codescanning.py @@ -1,69 +1,293 @@ +"""GitHub Code Scanning API Module.""" + from dataclasses import dataclass import json +import time import logging -from typing import Any, Optional +from typing import Any, List, Optional, Union +from ghastoolkit.errors import GHASToolkitError, GHASToolkitTypeError from ghastoolkit.octokit.github import GitHub, Repository -from ghastoolkit.octokit.octokit import OctoItem, RestRequest +from ghastoolkit.octokit.octokit import OctoItem, RestRequest, loadOctoItem logger = logging.getLogger("ghastoolkit.octokit.codescanning") @dataclass class CodeAlert(OctoItem): + """Code Alert from Code Scanning API.""" + number: int + """Unique Identifier""" state: str + """State of the alert. States can be `open`, `closed`, `dismissed`, or `fixed`.""" created_at: str + """Alert Creation date and time.""" rule: dict + """Rule Data (rule_id, severity, description, etc).""" tool: dict + """Tool information (name, version, guid).""" _instances: Optional[list[dict]] = None @property - def rule_id(self): - return self.rule.get("id") + def rule_id(self) -> str: + """Rule Identifier.""" + return self.rule.get("id", "NA") @property - def description(self): + def description(self) -> Optional[str]: + """Rule Description / Title.""" return self.rule.get("description") @property - def tool_name(self): - return self.tool.get("name") + def tool_name(self) -> str: + """Tool name.""" + return self.tool.get("name", "NA") @property - def tool_fullname(self): + def tool_fullname(self) -> str: + """Full tool name with version information.""" version = self.tool.get("version") return f"{self.tool_name}@{version}" @property - def severity(self): - return self.rule.get("severity") + def severity(self) -> str: + """Severity of the alert using `security_severity_level`.""" + return self.rule.get("security_severity_level", "NA") @property def instances(self) -> list[dict]: + """Get list of instances of the alert.""" if not self._instances: self._instances = CodeScanning().getAlertInstances(self.number) return self._instances def __str__(self) -> str: + """To String.""" return f"CodeAlert({self.number}, '{self.state}', '{self.tool_name}', '{self.rule_id}')" +@dataclass +class CodeScanningTool(OctoItem): + """Code Scanning Tool. + + https://docs.github.com/rest/code-scanning/code-scanning#list-code-scanning-analyses-for-a-repository + """ + + name: str + """Tool Name""" + guid: Optional[str] = None + """Tool GUID""" + version: Optional[str] = None + """Tool Version""" + + def __str__(self) -> str: + """To String.""" + if self.version: + return f"CodeScanningTool({self.name}, '{self.version}')" + else: + return f"CodeScanningTool({self.name})" + + def __repr__(self) -> str: + return self.__str__() + + +@dataclass +class CodeScanningAnalysisEnvironment(OctoItem): + """Code Scanning Analysis Environment. + + https://docs.github.com/rest/code-scanning/code-scanning + """ + + language: Optional[str] = None + """Language""" + + build_mode: Optional[str] = None + """CodeQL Build Mode""" + + def __str__(self) -> str: + """To String.""" + if self.language: + return f"CodeScanningAnalysisEnvironment({self.language})" + return "CodeScanningAnalysisEnvironment()" + + +@dataclass +class CodeScanningAnalysis(OctoItem): + """Code Scanning Analysis. + + https://docs.github.com/rest/code-scanning/code-scanning#list-code-scanning-analyses-for-a-repository + """ + + id: int + """Unique Identifier""" + ref: str + """Reference (branch, tag, etc)""" + commit_sha: str + """Commit SHA""" + analysis_key: str + """Analysis Key""" + environment: CodeScanningAnalysisEnvironment + """Environment""" + error: str + """Error""" + created_at: str + """Created At""" + results_count: int + """Results Count""" + rules_count: int + """Rules Count""" + url: str + """URL""" + sarif_id: str + """SARIF ID""" + tool: CodeScanningTool + """Tool Information""" + deletable: bool + """Deletable""" + warning: str + """Warning""" + + category: Optional[str] = None + """Category""" + + def __post_init__(self) -> None: + if isinstance(self.environment, str): + # Load the environment as JSON + self.environment = loadOctoItem( + CodeScanningAnalysisEnvironment, json.loads(self.environment) + ) + if isinstance(self.tool, dict): + # Load the tool as JSON + self.tool = loadOctoItem(CodeScanningTool, self.tool) + + @property + def language(self) -> Optional[str]: + """Language from the Environment.""" + return self.environment.language + + @property + def build_mode(self) -> Optional[str]: + """Build Mode from the Environment.""" + return self.environment.build_mode + + def __str__(self) -> str: + """To String.""" + return f"CodeScanningAnalysis({self.id}, '{self.ref}', '{self.tool.name}')" + + +@dataclass +class CodeScanningConfiguration(OctoItem): + """Code Scanning Configuration for Default Setup. + + https://docs.github.com/rest/code-scanning/code-scanning#get-a-code-scanning-default-setup-configuration--parameters + """ + + state: str + """State of the Configuration""" + query_suite: str + """Query Suite""" + languages: list[str] + """Languages""" + updated_at: str + """Updated At""" + schedule: str + """Scheduled (weekly)""" + + def __str__(self) -> str: + """To String.""" + return f"CodeScanningConfiguration('{self.state}', '{self.query_suite}', '{self.languages}')" + + def __repr__(self) -> str: + return self.__str__() + + class CodeScanning: - def __init__(self, repository: Optional[Repository] = None) -> None: - """GitHub Code Scanning REST API + """Code Scanning.""" + + def __init__( + self, + repository: Optional[Repository] = None, + retry_count: int = 1, + retry_sleep: Union[int, float] = 15, + ) -> None: + """Code Scanning REST API. + + Retries currently are only for fetching the analyses by default is only done once. + If you want to retry more than once you can set the `retry_count` to a higher number. + You can also set the `retry_sleep` to a higher number to sleep longer between + each retry. https://docs.github.com/en/rest/code-scanning """ self.repository = repository or GitHub.repository + self.tools: List[str] = [] + + self.setup: Optional[CodeScanningConfiguration] = None + if not self.repository: - raise Exception("CodeScanning requires Repository to be set") + raise GHASToolkitError("CodeScanning requires Repository to be set") + + self.retry_count = retry_count + self.retry_sleep = retry_sleep self.rest = RestRequest(self.repository) - def getOrganizationAlerts(self, state: str = "open") -> list[dict[Any, Any]]: - """Get Organization Alerts + def isEnabled(self) -> bool: + """Check to see if Code Scanning is enabled or not on a repository level. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning#list-code-scanning-analyses-for-a-repository + """ + try: + self.getLatestAnalyses() + return True + except: + logger.debug(f"Failed to get any analyses...") + return False + + def isCodeQLDefaultSetup(self) -> bool: + """Check if Code Scanning is using the Default CodeQL Setup. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning + """ + if not self.setup: + self.setup = self.getDefaultConfiguration() + + return self.setup.state == "configured" + + def enableDefaultSetup( + self, + state: str = "configured", + query_suite: str = "default", + languages: list[str] = [], + ) -> dict[str, Any]: + """Enable Code Scanning using Default Setup using CodeQL. + + Permissions: + - "Administration" repository permissions (write) + + https://docs.github.com/en/rest/code-scanning#set-up-code-scanning + """ + data = {"state": state, "query_suite": query_suite, "languages": languages} + result = self.rest.patchJson( + "/repos/{owner}/{repo}/code-scanning/default-setup", + data, + expected=[200, 202], + ) + return result + + def getOrganizationAlerts(self, state: str = "open") -> list[CodeAlert]: + """Get list of Organization Alerts. + + Permissions: + - "Code scanning alerts" repository permissions (read) https://docs.github.com/en/rest/code-scanning#list-code-scanning-alerts-for-an-organization """ @@ -71,37 +295,93 @@ def getOrganizationAlerts(self, state: str = "open") -> list[dict[Any, Any]]: "/orgs/{org}/code-scanning/alerts", {"state": state}, authenticated=True ) if isinstance(results, list): - return results - raise Exception(f"Error getting alerts from Organization") + return [loadOctoItem(CodeAlert, alert) for alert in results] + + raise GHASToolkitTypeError( + f"Error getting alerts from Organization", + docs="https://docs.github.com/en/rest/code-scanning#list-code-scanning-alerts-for-an-organization", + ) + + def getDefaultConfiguration(self) -> CodeScanningConfiguration: + """Get Default Code Scanning Configuration. + + Permissions: + - "Administration" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-default-setup-configuration--parameters + """ + result = self.rest.get("/repos/{owner}/{repo}/code-scanning/default-setup") + if isinstance(result, dict): + self.setup = loadOctoItem(CodeScanningConfiguration, result) + return self.setup + + raise GHASToolkitTypeError( + "Error getting default configuration", + docs="https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-default-setup-configuration--parameters", + ) - @RestRequest.restGet( - "/repos/{owner}/{repo}/code-scanning/alerts", authenticated=True - ) def getAlerts( self, state: str = "open", tool_name: Optional[str] = None, ref: Optional[str] = None, + sort: Optional[str] = None, + severity: Optional[str] = None, ) -> list[CodeAlert]: - """Get all code scanning alerts + """Get all code scanning alerts. + + Permissions: + - "Code scanning alerts" repository permissions (read) + https://docs.github.com/en/rest/code-scanning#list-code-scanning-alerts-for-a-repository """ - return [] + results = self.rest.get( + "/repos/{owner}/{repo}/code-scanning/alerts", + { + "state": state, + "tool_name": tool_name, + "ref": ref, + "sort": sort, + "severity": severity, + }, + authenticated=True, + ) + if isinstance(results, list): + return [loadOctoItem(CodeAlert, alert) for alert in results] + + raise GHASToolkitTypeError( + f"Error getting alerts from Repository", + docs="https://docs.github.com/en/rest/code-scanning#list-code-scanning-alerts-for-a-repository", + ) - def getAlertsInPR(self, base: str) -> list[dict]: + def getAlertsInPR(self, base: str) -> list[CodeAlert]: """Get the open alerts in a Pull Request (delta / diff). Note this operation is slow due to it needing to lookup each alert instance information. - base: str - Base reference + Permissions: + - "Code scanning alerts" repository permissions (read) + - "Pull Requests" repository permissions (read) + https://docs.github.com/en/rest/code-scanning#list-instances-of-a-code-scanning-alert """ + results = [] + if not self.repository.reference or not self.repository.isInPullRequest(): - return [] + raise GHASToolkitError("Repository is not in a Pull Request") - results = [] - alerts = self.getAlerts("open", ref=self.repository.reference) + # Try merge and then head + analysis = self.getAnalyses(reference=self.repository.reference) + if len(analysis) == 0: + raise GHASToolkitError("No analyses found for the PR") + + # For CodeQL results using Default Setup + reference = analysis[0].get("ref") + if not reference: + raise GHASToolkitError("No ref found in the analysis") + + alerts = self.getAlerts("open", ref=reference) for alert in alerts: number = alert.get("number") @@ -110,61 +390,193 @@ def getAlertsInPR(self, base: str) -> list[dict]: results.append(alert) return results - @RestRequest.restGet( - "/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}", authenticated=True - ) - def getAlert(self, alert_number: int) -> dict: - """Get Single Alert + def getAlert(self, alert_number: int) -> CodeAlert: + """Get Single Alert information from Code Scanning. + + Permissions: + - "Code scanning alerts" repository permissions (read) + https://docs.github.com/en/rest/code-scanning#get-a-code-scanning-alert """ - return {} + result = self.rest.get( + "/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}", + {"alert_number": alert_number}, + ) + if isinstance(result, dict): + return loadOctoItem(CodeAlert, result) + raise GHASToolkitTypeError("Error getting alert from Repository") def getAlertInstances( self, alert_number: int, ref: Optional[str] = None ) -> list[dict]: + """Get a list of alert instances. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning#list-instances-of-a-code-scanning-alert + """ result = self.rest.get( "/repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", {"alert_number": alert_number, "ref": ref}, ) - return result + if isinstance(result, list): + return result + + raise GHASToolkitTypeError( + "Error getting alert instances from Repository", + docs="https://docs.github.com/en/rest/code-scanning/code-scanning#list-instances-of-a-code-scanning-alert", + ) def getAnalyses( self, reference: Optional[str] = None, tool: Optional[str] = None - ) -> list[dict]: - """Get a list of analyses for a repository + ) -> list[CodeScanningAnalysis]: + """Get a list of all the analyses for a given repository. + + This function will retry X times with a Y second sleep between each retry to + make sure the analysis is ready. This is primarily used for CodeQL Default Setup + in Pull Requests where the analysis might not be ready yet. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + Thrown Exceptions: + - GHASToolkitError on retry limit reached + - GHASToolkitTypeError on error getting analyses + https://docs.github.com/en/enterprise-cloud@latest/rest/code-scanning#list-code-scanning-analyses-for-a-repository """ - results = self.rest.get( - "/repos/{org}/{repo}/code-scanning/analyses", - {"tool_name": tool, "ref": reference or self.repository.reference}, + ref = reference or self.repository.reference + logger.debug(f"Getting Analyses for {ref}") + if ref is None: + raise GHASToolkitError("Reference is required for getting analyses") + + counter = 0 + + logger.debug( + f"Fetching Analyses (retries {self.retry_count} every {self.retry_sleep}s)" + ) + + while counter < self.retry_count: + counter += 1 + + results = self.rest.get( + "/repos/{org}/{repo}/code-scanning/analyses", + {"tool_name": tool, "ref": ref}, + ) + if not isinstance(results, list): + raise GHASToolkitTypeError( + "Error getting analyses from Repository", + permissions=[ + '"Code scanning alerts" repository permissions (read)' + ], + docs="https://docs.github.com/en/enterprise-cloud@latest/rest/code-scanning#list-code-scanning-analyses-for-a-repository", + ) + + # Try default setup `head` if no results (required for default setup) + if ( + len(results) == 0 + and self.repository.isInPullRequest() + and (ref.endswith("/merge") or ref.endswith("/head")) + ): + logger.debug("No analyses found for `merge`, trying `head`") + results = self.rest.get( + "/repos/{org}/{repo}/code-scanning/analyses", + {"tool_name": tool, "ref": ref.replace("/merge", "/head")}, + ) + if not isinstance(results, list): + raise GHASToolkitTypeError( + "Error getting analyses from Repository", + permissions=[ + '"Code scanning alerts" repository permissions (read)' + ], + docs="https://docs.github.com/en/enterprise-cloud@latest/rest/code-scanning#list-code-scanning-analyses-for-a-repository", + ) + + if len(results) == 0: + # If the retry count is less than 1, we don't retry + if self.retry_count > 1: + logger.debug( + f"No analyses found, retrying ({counter}/{self.retry_count})" + ) + time.sleep(self.retry_sleep) + else: + return [ + loadOctoItem(CodeScanningAnalysis, analysis) for analysis in results + ] + + # If we get here, we have retried the max number of times and still no results + raise GHASToolkitError( + "Error getting analyses from Repository (retry limit reached)", + permissions=['"Code scanning alerts" repository permissions (read)'], + docs="https://docs.github.com/en/enterprise-cloud@latest/rest/code-scanning#list-code-scanning-analyses-for-a-repository", ) - if isinstance(results, list): - return results - raise Exception(f"") def getLatestAnalyses( self, reference: Optional[str] = None, tool: Optional[str] = None - ) -> list[dict]: - """Get Latest Analyses for every tool""" + ) -> list[CodeScanningAnalysis]: + """Get Latest Analyses for every tool. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-analysis-for-a-repository + """ tools = set() results = [] + for analysis in self.getAnalyses(reference, tool): - name = analysis.get("tool", {}).get("name") - if name in tools: + if analysis.tool.name in tools: continue - tools.add(name) + tools.add(analysis.tool.name) results.append(analysis) + self.tools = list(tools) + return results + def getFailedAnalyses( + self, reference: Optional[str] = None + ) -> list[CodeScanningAnalysis]: + """Get Failed Analyses for a given reference. This will return all analyses with errors or warnings. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning + """ + return [ + analysis + for analysis in self.getAnalyses(reference) + if analysis.error != "" or analysis.warning != "" + ] + + def getTools(self, reference: Optional[str] = None) -> List[str]: + """Get list of tools from the latest analyses. + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-analysis-for-a-repository + """ + if len(self.tools) == 0: + self.getLatestAnalyses(reference) + return self.tools + def getSarifId(self, url: str) -> int: - """Get the latest SARIF ID from a URL""" + """Get the latest SARIF ID from a URL.""" if url and "/" in url: return int(url.split("/")[-1]) return -1 def downloadSARIF(self, output: str, sarif_id: int) -> bool: - """Get SARIF by ID (UUID)""" + """Get SARIF by ID (UUID). + + Permissions: + - "Code scanning alerts" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning/code-scanning#get-a-code-scanning-analysis-for-a-repository + """ logger.debug(f"Downloading SARIF file :: {sarif_id}") # need to change "Accept" and then reset @@ -185,17 +597,88 @@ def downloadSARIF(self, output: str, sarif_id: int) -> bool: # CodeQL def getCodeQLDatabases(self) -> list[dict]: - """List CodeQL databases for a repository + """List CodeQL databases for a repository. + + Permissions: + - "Contents" repository permissions (read) - https://docs.github.com/en/rest/code-scanning?apiVersion=2022-11-28#list-codeql-databases-for-a-repository + https://docs.github.com/en/rest/code-scanning#list-codeql-databases-for-a-repository """ - return self.rest.get("/repos/{owner}/{repo}/code-scanning/codeql/databases") + result = self.rest.get("/repos/{owner}/{repo}/code-scanning/codeql/databases") + if isinstance(result, list): + return result + + raise GHASToolkitTypeError( + "Error getting CodeQL databases", + docs="https://docs.github.com/en/rest/code-scanning#list-codeql-databases-for-a-repository", + ) def getCodeQLDatabase(self, language: str) -> dict: - """Get a CodeQL database for a repository - https://docs.github.com/en/rest/code-scanning?apiVersion=2022-11-28#get-a-codeql-database-for-a-repository + """Get a CodeQL database for a repository. + + Permissions: + - "Contents" repository permissions (read) + + https://docs.github.com/en/rest/code-scanning#get-a-codeql-database-for-a-repository """ - return self.rest.get( + result = self.rest.get( "/repos/{owner}/{repo}/code-scanning/codeql/databases/{language}", {"language": language}, ) + if isinstance(result, dict): + return result + raise GHASToolkitTypeError( + "Error getting CodeQL database", + docs="https://docs.github.com/en/rest/code-scanning#get-a-codeql-database-for-a-repository", + ) + + def getPacks(self, visibility: str = "internal") -> List[dict]: + """Get all CodeQL Packs from remote GitHub instance. + + CodeQL Packs are stored in GitHub's container registry so this function might + return other container images. + """ + result = self.rest.get( + "/orgs/{org}/packages", + {"package_type": "container", "visibility": visibility}, + ) + if isinstance(result, list): + return result + raise GHASToolkitTypeError("Error getting CodeQL packs") + + def getPackVersions(self, pack_name: str) -> list[dict]: + """Get a list of all remote pack versions.""" + if "/" in pack_name: + # full name + org, pack_name = pack_name.split("/") + else: + org = self.repository.owner + + result = self.rest.get( + "/orgs/{pack_org}/packages/{package_type}/{package_name}/versions", + {"pack_org": org, "package_type": "container", "package_name": pack_name}, + ) + if isinstance(result, list): + return result + raise GHASToolkitTypeError("Error getting CodeQL pack versions") + + def getLatestPackVersion(self, pack_name: str) -> dict: + """Get the current remote CodeQL pack version.""" + versions = self.getPackVersions(pack_name) + if len(versions) != 0: + return versions[0] + return {} + + def downloadExtractorPack(self, repository_name: str, output: str) -> Optional[str]: + """Download Extractor Packs from GitHub Releases.""" + owner, repo = repository_name.split("/", 1) + + latest_release = self.rest.get( + f"/repos/{owner}/{repo}/releases/latest", + ) + if not isinstance(latest_release, dict): + raise GHASToolkitTypeError("Error getting latest release") + version = latest_release.get("tag_name", "0.0.0") + logger.debug(f"Latest Releases :: {version}") + + # for asset in latest_release.get("assets", []): diff --git a/vendor/ghastoolkit/octokit/dependabot.py b/vendor/ghastoolkit/octokit/dependabot.py index 77c5863..05e86fb 100644 --- a/vendor/ghastoolkit/octokit/dependabot.py +++ b/vendor/ghastoolkit/octokit/dependabot.py @@ -1,8 +1,11 @@ +"""Dependabot API.""" + import logging from typing import Optional +from ghastoolkit.errors import GHASToolkitError, GHASToolkitTypeError from ghastoolkit.octokit.github import GitHub, Repository -from ghastoolkit.octokit.octokit import GraphQLRequest +from ghastoolkit.octokit.octokit import GraphQLRequest, RestRequest from ghastoolkit.supplychain.advisories import Advisory from ghastoolkit.supplychain.dependencyalert import DependencyAlert @@ -11,37 +14,173 @@ class Dependabot: + """Dependabot API instance.""" + def __init__(self, repository: Optional[Repository] = None) -> None: + """Initialise Dependabot API class.""" self.repository = repository or GitHub.repository self.graphql = GraphQLRequest(repository) - def getAlerts(self) -> list[DependencyAlert]: - """Get Dependabot alerts from GraphQL API""" - results = [] + self.rest = RestRequest(repository) - while True: + def isEnabled(self) -> bool: + """Is Dependabot enabled.""" + try: data = self.graphql.query( - "GetDependencyAlerts", + "GetDependencyStatus", options={"owner": self.repository.owner, "repo": self.repository.repo}, ) - alerts = ( + return ( data.get("data", {}) .get("repository", {}) - .get("vulnerabilityAlerts", {}) + .get("hasVulnerabilityAlertsEnabled", False) + ) + except: + logger.debug(f"Failed to get alert count") + return False + + def isSecurityUpdatesEnabled(self) -> bool: + """Is Security Updates for Dependabot enabled. + + https://docs.github.com/en/rest/reference/repos#get-a-repository + """ + result = self.rest.get("get/repos/{owner}/{repo}") + if not isinstance(result, dict): + raise GHASToolkitTypeError( + "Unable to get repository info", + permissions=["Repository Administration (read)"], + docs="https://docs.github.com/en/rest/reference/repos#get-a-repository", + ) + saa = result.get("source", {}).get("security_and_analysis", {}) + status = saa.get("dependabot_security_updates", {}).get("status", "disabled") + return status == "enabled" + + def getAlerts( + self, + state: str = "open", + severity: Optional[str] = None, + ecosystem: Optional[str] = None, + package: Optional[str] = None, + manifest: Optional[str] = None, + scope: Optional[str] = None, + ) -> list[DependencyAlert]: + """Get All Dependabot alerts from REST API. + + https://docs.github.com/en/rest/dependabot/alerts + """ + if state not in ["auto_dismissed", "dismissed", "fixed", "open"]: + raise GHASToolkitError( + f"Invalid state provided: {state}", + docs="https://docs.github.com/en/rest/reference/repos#get-a-repository", + ) + + logger.debug(f"Getting Dependabot alerts with state: {state}") + + results = self.rest.get( + "/repos/{owner}/{repo}/dependabot/alerts", + { + "state": state, + "severity": severity, + "ecosystem": ecosystem, + "package": package, + "manifest": manifest, + "scope": scope, + }, + ) + if isinstance(results, list): + retval = [] + for alert in results: + advisory_data = alert.get("security_advisory", {}) + # Fix issues between GraphQL and Advisory class + advisory_data["affected"] = advisory_data.pop("vulnerabilities") + advisory = Advisory(**advisory_data) + + package = alert.get("dependency", {}).get("package", {}) + + retval.append( + DependencyAlert( + number=alert.get("number"), + state=alert.get("state"), + severity=alert.get("security_advisory", {}).get( + "severity", "unknown" + ), + advisory=advisory, + purl=f"pkg:{package.get('ecosystem')}/{package.get('name')}".lower(), + manifest=alert.get("manifest_path"), + ) + ) + + return retval + raise GHASToolkitTypeError( + f"Error getting Dependabot alerts", + docs="https://docs.github.com/en/rest/dependabot/alerts", + ) + + def getAlertsInPR(self) -> list[DependencyAlert]: + """Get All Dependabot alerts from REST API in Pull Request.""" + logger.debug("Dependabot Alerts from Pull Request using DependencyGraph API") + + from ghastoolkit import DependencyGraph + + depgraph = DependencyGraph(repository=self.repository) + + pr_info = self.repository.getPullRequestInfo() + pr_base = pr_info.get("base", {}).get("ref", "") + pr_head = pr_info.get("head", {}).get("ref", "") + + if pr_base == "" or pr_head == "": + raise GHASToolkitError( + "Failed to get base and head branch of pull request", + permissions=[ + '"Contents" repository permissions (read)', + '"Pull requests" permissions (read)', + ], + docs="https://docs.github.com/en/rest/reference/repos#get-a-repository", + ) + + dependencies = depgraph.getDependenciesInPR(pr_base, pr_head) + alerts = [] + for dep in dependencies: + alerts.extend(dep.alerts) + return alerts + + def getAlertsGraphQL(self) -> list[DependencyAlert]: + """Get All Dependabot alerts from GraphQL API using the `GetDependencyAlerts` query.""" + results = [] + + while True: + data = self.graphql.query( + "GetDependencyAlerts", + options={"owner": self.repository.owner, "repo": self.repository.repo}, ) + repo = data.get("data", {}).get("repository", {}) + if not repo: + logger.error(f"Failed to get GraphQL repository") + logger.error( + "This could be due to a lack of permissions or access token" + ) + raise GHASToolkitError(f"Failed to get GraphQL repository alerts") + + alerts = repo.get("vulnerabilityAlerts", {}) for alert in alerts.get("edges", []): data = alert.get("node", {}) package = data.get("securityVulnerability", {}).get("package", {}) purl = f"pkg:{package.get('ecosystem')}/{package.get('name')}".lower() + created_at = data.get("createdAt") + + advisory_data = data.get("securityAdvisory", {}) + # Fix issues between GraphQL and Advisory class + advisory_data["ghsa_id"] = advisory_data.pop("ghsaId") + advisory = Advisory(**advisory_data) - advisory = Advisory( - ghsa_id=data.get("securityAdvisory", {}).get("ghsaId"), - severity=data.get("securityAdvisory", {}).get("severity"), - # TODO: CWE info - ) dep_alert = DependencyAlert( - severity=advisory.severity, purl=purl, advisory=advisory + number=data.get("number"), + state=data.get("state"), + severity=advisory.severity.lower(), + purl=purl, + advisory=advisory, + created_at=created_at, ) dep_alert.__data__ = data results.append(dep_alert) diff --git a/vendor/ghastoolkit/octokit/dependencygraph.py b/vendor/ghastoolkit/octokit/dependencygraph.py index 31a7ad6..42c2e98 100644 --- a/vendor/ghastoolkit/octokit/dependencygraph.py +++ b/vendor/ghastoolkit/octokit/dependencygraph.py @@ -1,10 +1,12 @@ +"""Dependency Graph Octokit.""" + import logging -from dataclasses import dataclass, field -from datetime import datetime -import re -from typing import Any +from typing import Any, Dict import urllib.parse +from semantic_version import Version + +from ghastoolkit.errors import GHASToolkitError, GHASToolkitTypeError from ghastoolkit.octokit.github import GitHub, Repository from ghastoolkit.supplychain.advisories import Advisory from ghastoolkit.supplychain.dependencyalert import DependencyAlert @@ -15,13 +17,78 @@ class DependencyGraph: - def __init__(self, repository: Optional[Repository] = None) -> None: + """Dependency Graph API.""" + + def __init__( + self, + repository: Optional[Repository] = None, + enable_graphql: bool = True, + enable_clearlydefined: bool = False, + ) -> None: + """Initialise Dependency Graph.""" self.repository = repository or GitHub.repository self.rest = RestRequest(repository) self.graphql = GraphQLRequest(repository) + self.enable_graphql = enable_graphql + self.enable_clearlydefined = enable_clearlydefined + + def getOrganizationDependencies(self) -> Dict[Repository, Dependencies]: + """Get Organization Dependencies.""" + deps: Dict[Repository, Dependencies] = {} + + repositories = self.rest.get("/orgs/{org}/repos") + if not isinstance(repositories, list): + raise Exception("Invalid organization") + + for repo in repositories: + repo = Repository.parseRepository(repo.get("full_name")) + logger.debug(f"Processing repository :: {repo}") + try: + self.rest = RestRequest(repo) + + deps[repo] = self.getDependenciesSbom() + except Exception as err: + logger.warning(f"Failed to get dependencies :: {err}") + deps[repo] = Dependencies() + + self.rest = RestRequest(self.repository) + return deps + def getDependencies(self) -> Dependencies: - """Get Dependencies from SBOM""" + """Get Dependencies.""" + if GitHub.isEnterpriseServer(): + if not self.enable_clearlydefined: + logger.warning( + "Enterprise Server does not support licensing information" + ) + # enterprise: 3.8+ use SBOM API + if GitHub.server_version >= Version("3.9.0"): + logger.info("Using SBOM API to resolve dependencies (GHES 3.9+)") + deps = self.getDependenciesSbom() + # enterprise: 3.7+ use GraphQL API + elif GitHub.server_version >= Version("3.6.0"): + logger.warning("Using GraphQL API to resolve dependencies (GHES 3.6+)") + deps = self.getDependenciesGraphQL() + else: + raise GHASToolkitError("Enterprise Server version must be >= 3.6.0") + else: + # cloud: download SBOM + deps = self.getDependenciesSbom() + + if self.enable_graphql: + logger.debug("Enabled GraphQL Dependencies") + graph_deps = self.getDependenciesGraphQL() + + deps.updateDependencies(graph_deps) + + if self.enable_clearlydefined: + logger.info("Using ClearlyDefined API to resolve dependency licenses") + deps.applyClearlyDefined() + return deps + + def getDependenciesSbom(self) -> Dependencies: + """Get Dependencies from SBOM.""" result = Dependencies() spdx_bom = self.exportBOM() @@ -29,43 +96,178 @@ def getDependencies(self) -> Dependencies: extref = False dep = Dependency("") for ref in package.get("externalRefs", []): - if ref.get("referenceType"): + if ref.get("referenceType", "") == "purl": dep = Dependency.fromPurl(ref.get("referenceLocator")) extref = True + else: + logger.warning(f"Unknown external reference :: {ref}") # if get find a PURL or not if extref: - dep.licence = package.get("licenseConcluded") + dep.license = package.get("licenseConcluded") else: - name = package.get("name", "") + name = package.get("name", "").lower() # manager ':' if ":" in name: dep.manager, name = name.split(":", 1) + + # HACK: Maven / NuGet + if dep.manager in ["maven", "nuget"]: + if "." in name: + dep.namespace, name = name.rsplit(".", 1) # Namespace '/' - if "/" in package: + elif "/" in package: dep.namespace, name = name.split("/", 1) dep.name = name dep.version = package.get("versionInfo") - dep.licence = package.get("licenseConcluded") + dep.license = package.get("licenseConcluded") result.append(dep) return result + def getDependenciesGraphQL(self, dependencies_count: int = 100) -> Dependencies: + """Get Dependencies from GraphQL. + + This functions requests each manifest file in the repository and the + dependencies associated with it. It then paginates through both the manifests + and dependencies. + + This is done to avoid the timeout errors in the GraphQL API when requesting + large projects with many manifests and dependencies. + """ + deps = Dependencies() + + manifests = True + manifests_cursor = "" + dependencies_cursor = "" + + while manifests: + # Query a single manifest at a time + data = self.graphql.query( + "GetDependencyInfo", + { + "owner": self.repository.owner, + "repo": self.repository.repo, + "manifests_cursor": manifests_cursor, + "dependencies_first": dependencies_count, + "dependencies_cursor": dependencies_cursor, + }, + ) + + graph_manifests = ( + data.get("data", {}) + .get("repository", {}) + .get("dependencyGraphManifests", {}) + ) + logger.debug(f"Processing :: '{graph_manifests.get('totalCount')}'") + + # Runs at least once + has_next_page = True + + while has_next_page: + for manifest in graph_manifests.get("edges", []): + node = manifest.get("node", {}) + dependencies = node.get("dependencies", {}) + logger.debug(f"Processing :: '{node.get('filename')}'") + + # Pagination + has_next_page = dependencies.get("pageInfo", {}).get( + "hasNextPage", False + ) + if has_next_page: + dependencies_cursor = f'after: "{dependencies.get("pageInfo", {}).get("endCursor")}"' + else: + dependencies_cursor = "" + + for dep in dependencies.get("edges", []): + dep = dep.get("node", {}) + license = None + repository = None + + if dep.get("repository"): + if dep.get("repository", {}).get("licenseInfo"): + license = ( + dep.get("repository", {}) + .get("licenseInfo", {}) + .get("name") + ) + if dep.get("repository", {}).get("nameWithOwner"): + repository = dep.get("repository", {}).get( + "nameWithOwner" + ) + + version = dep.get("requirements") + if version: + version = version.replace("= ", "") + + deps.append( + Dependency( + name=dep.get("packageName"), + manager=dep.get("packageManager"), + version=version, + license=license, + repository=repository, + ) + ) + + if has_next_page: + logger.debug( + f"Re-run and fetch next data page :: {manifests_cursor} ({dependencies_cursor})" + ) + + data = self.graphql.query( + "GetDependencyInfo", + { + "owner": self.repository.owner, + "repo": self.repository.repo, + "manifests_cursor": manifests_cursor, + "dependencies_first": dependencies_count, + "dependencies_cursor": dependencies_cursor, + }, + ) + graph_manifests = ( + data.get("data", {}) + .get("repository", {}) + .get("dependencyGraphManifests", {}) + ) + + # If there are no other manifest files, then we are done + if graph_manifests.get("pageInfo", {}).get("hasNextPage"): + cursor = graph_manifests.get("pageInfo", {}).get("endCursor") + manifests_cursor = f'after: "{cursor}"' if cursor != "" else "" + logger.debug(f"Cursor :: {manifests_cursor}") + else: + manifests = False + manifests_cursor = "" + logger.debug("No more manifests to be processed") + + return deps + def getDependenciesInPR(self, base: str, head: str) -> Dependencies: - """Get all the dependencies from a Pull Request""" + """Get all the dependencies from a Pull Request.""" + + if GitHub.isEnterpriseServer() and GitHub.server_version < Version("3.6.0"): + raise GHASToolkitError("Enterprise Server version must be >= 3.6") + dependencies = Dependencies() base = urllib.parse.quote(base, safe="") head = urllib.parse.quote(head, safe="") basehead = f"{base}...{head}" logger.debug(f"PR basehead :: {basehead}") + results = self.rest.get( "/repos/{owner}/{repo}/dependency-graph/compare/{basehead}", {"basehead": basehead}, expected=200, ) + if not results: + logger.warning("Failed to get dependencies from Pull Request") + logger.warning( + "Make sure Advanced Security is enabled and token permissions are correct" + ) return dependencies for depdata in results: @@ -83,6 +285,8 @@ def getDependenciesInPR(self, base: str, head: str) -> Dependencies: for alert in depdata.get("vulnerabilities", []): dep_alert = DependencyAlert( + depdata.get("vulnerabilities").index(alert), + "open", alert.get("severity"), purl=dep.getPurl(False), advisory=Advisory( @@ -91,6 +295,7 @@ def getDependenciesInPR(self, base: str, head: str) -> Dependencies: summary=alert.get("advisory_summary"), url=alert.get("advisory_ghsa_url"), ), + manifest=alert.get("manifest"), ) dep.alerts.append(dep_alert) @@ -99,8 +304,18 @@ def getDependenciesInPR(self, base: str, head: str) -> Dependencies: return dependencies def exportBOM(self) -> Dependencies: - """Download / Export DependencyGraph SBOM""" - return self.rest.get("/repos/{owner}/{repo}/dependency-graph/sbom") + """Download / Export DependencyGraph SBOM. + + https://docs.github.com/en/rest/dependency-graph/sboms#export-a-software-bill-of-materials-sbom-for-a-repository + """ + result = self.rest.get("/repos/{owner}/{repo}/dependency-graph/sbom") + if result: + return result + + raise GHASToolkitTypeError( + "Failed to download SBOM", + docs="https://docs.github.com/en/rest/dependency-graph/sboms#export-a-software-bill-of-materials-sbom-for-a-repository", + ) def submitDependencies( self, @@ -112,7 +327,8 @@ def submitDependencies( version: str = "0.0.0", url: str = "", ): - """ + """Submit dependencies to GitHub Dependency Graph snapshots API. + https://docs.github.com/en/rest/dependency-graph/dependency-submission?apiVersion=2022-11-28#create-a-snapshot-of-dependencies-for-a-repository """ self.rest.postJson( @@ -122,7 +338,7 @@ def submitDependencies( ) def submitSbom(self, sbom: dict[Any, Any]): - """Submit SBOM""" + """Submit SBOM.""" self.rest.postJson( "/repos/{owner}/{repo}/dependency-graph/snapshots", sbom, diff --git a/vendor/ghastoolkit/octokit/enterprise.py b/vendor/ghastoolkit/octokit/enterprise.py new file mode 100644 index 0000000..d5dfb03 --- /dev/null +++ b/vendor/ghastoolkit/octokit/enterprise.py @@ -0,0 +1,197 @@ +import logging +from typing import List, Optional + +from semantic_version import Version + +from ghastoolkit.errors import GHASToolkitError +from ghastoolkit.octokit.github import GitHub +from ghastoolkit.octokit.octokit import Octokit, RestRequest +from ghastoolkit.octokit.repository import Repository + +logger = logging.getLogger("ghastoolkit.octokit.enterprise") + + +class Organization: + """Organization.""" + + def __init__( + self, organization: Optional[str] = None, identifier: Optional[int] = None + ) -> None: + """Initialise Organization.""" + self.name = organization + self.identifier = identifier + + self.rest = RestRequest(GitHub.repository) + + def getRepositories(self) -> List[Repository]: + """Get Repositories. + + https://docs.github.com/en/rest/repos/repos#list-organization-repositories + """ + repositories = [] + result = self.rest.get(f"/orgs/{self.name}/repos") + if not isinstance(result, list): + logger.error("Error getting repositories") + raise GHASToolkitError( + "Error getting repositories", + permissions=["Metadata repository permissions (read)"], + docs="https://docs.github.com/en/rest/repos/repos#list-organization-repositories", + ) + + for repository in result: + repositories.append(Repository.parseRepository(repository.get("full_name"))) + + return repositories + + def enableAllSecurityProduct(self) -> bool: + """Enable all security products.""" + products = [ + "advanced_security", + "dependency_graph", + "dependabot_alerts", + "dependabot_security_updates", + "code_scanning_default_setup", + "secret_scanning", + "secret_scanning_push_protection", + ] + for product in products: + rslt = self.enableSecurityProduct(product) + if not rslt: + return False + + return True + + def enableSecurityProduct(self, security_product: str) -> bool: + """Enable Advanced Security.""" + url = Octokit.route( + f"/orgs/{self.name}/{security_product}/enable_all", GitHub.repository + ) + result = self.rest.session.post(url) + if result.status_code != 204: + logger.error("Error enabling security product") + return False + + return True + + def enableDefaultSetup(self) -> bool: + """Enable Code Scanning Default Setup on all repositories in an organization. + Assumes that advanced-security is enabled on all repositories. + + - GHE cloud: supported + - GHE server: 3.8 or lower: not supported + - GHE server: 3.9 or 3.10: uses repo level setup (may take a while) + - GHE server: 3.11 or above: not supported + """ + + if GitHub.isEnterpriseServer(): + # version 3.8 or lower + if GitHub.server_version and GitHub.server_version < Version("3.9.0"): + logger.error( + "Enterprise Server 3.8 or lower does not support default setup" + ) + raise GHASToolkitError( + "Enterprise Server 3.8 or lower does not support default setup" + ) + + elif GitHub.server_version and GitHub.server_version < Version("3.11.0"): + from ghastoolkit.octokit.codescanning import CodeScanning + + logger.debug("Enterprise Server 3.9/3.10 supports repo level setup") + + for repo in self.getRepositories(): + logger.debug(f"Enabling default setup for {repo.repo}") + + code_scanning = CodeScanning(repo) + code_scanning.enableDefaultSetup() + return True + else: + logger.error( + "Enterprise Server 3.11 or above isn't supported by this version of the toolkit" + ) + else: + self.enableSecurityProduct("code_scanning_default_setup") + return True + return False + + def __str__(self) -> str: + """Return string representation.""" + return f"Organization('{self.name}')" + + +class Enterprise: + """Enterprise API.""" + + def __init__( + self, + enterprise: Optional[str] = None, + ) -> None: + """Initialise Enterprise.""" + self.enterprise = enterprise or GitHub.enterprise + self.rest = RestRequest(GitHub.repository) + + def getOrganizations(self, include_github: bool = False) -> List[Organization]: + """Get all the Organizations in an enterprise. + + You will need to be authenticated as an enterprise owner to use this API. + """ + github_orgs = ["github", "actions"] + organizations = [] + url = Octokit.route("/organizations", GitHub.repository) + # pagination uses a different API versus the rest of the API + # https://docs.github.com/en/enterprise-cloud@latest/rest/orgs/orgs#list-organizations + last_org_id = 1 + + while True: + response = self.rest.session.get( + url, params={"since": last_org_id, "per_page": 100} + ) + + if response.status_code != 200: + logger.error("Error getting organizations") + raise GHASToolkitError( + "Error getting organizations", + permissions=["Metadata repository permissions (read)"], + docs="https://docs.github.com/en/rest/orgs/orgs#list-organizations", + ) + + result = response.json() + + if not isinstance(result, list): + logger.error("Error getting organizations") + raise GHASToolkitError( + "Error getting organizations", + permissions=["Metadata repository permissions (read)"], + docs="https://docs.github.com/en/rest/orgs/orgs#list-organizations", + ) + + for org in result: + if not include_github and org.get("login") in github_orgs: + continue + organizations.append(Organization(org.get("login"), org.get("id"))) + + if len(result) < 100: + break + + if len(organizations) == 0: + logger.error("Error getting last org in organizations") + logger.error("Only GitHub orgs might be returned") + break + + # set last org ID + last_org_id = organizations[-1].identifier + + return organizations + + def enableDefaultSetup(self): + """Enable Code Scanning default setup on all repositories in an enterprise. + + Assumes that advanced-security is enabled on all repositories. + + - GHE cloud: supported + - GHE server: 3.8 or lower: not supported + - GHE server: 3.9 or 3.10: uses repo level setup + - GHE server: 3.11 or above: uses default setup + """ + + for organization in self.getOrganizations(): + organization.enableDefaultSetup() diff --git a/vendor/ghastoolkit/octokit/github.py b/vendor/ghastoolkit/octokit/github.py index c83a9a2..5f2ae78 100644 --- a/vendor/ghastoolkit/octokit/github.py +++ b/vendor/ghastoolkit/octokit/github.py @@ -1,182 +1,50 @@ +"""GitHub and Repository APIs.""" + import logging import os -import shutil -import tempfile -import subprocess -from dataclasses import dataclass -from typing import Optional, Tuple +from typing import Dict, Optional, Tuple from urllib.parse import urlparse +from semantic_version import Version -logger = logging.getLogger("ghastoolkit.octokit.github") +from ghastoolkit.octokit.repository import Repository -@dataclass -class Repository: - owner: str - repo: str - - reference: Optional[str] = None - branch: Optional[str] = None - __prinfo__: Optional[dict] = None - - sha: Optional[str] = None - - clone_path: Optional[str] = None - - def __post_init__(self) -> None: - if self.reference and not self.branch: - if not self.isInPullRequest(): - _, _, branch = self.reference.split("/", 2) - self.branch = branch - if self.branch and not self.reference: - self.reference = f"refs/heads/{self.branch}" - - if not self.clone_path: - self.clone_path = os.path.join(tempfile.gettempdir(), self.repo) - - def __str__(self) -> str: - name = f"{self.owner}/{self.repo}" - if self.reference: - return f"{name}:{self.reference}" - elif self.branch: - return f"{name}@{self.branch}" - return name - - def __repr__(self) -> str: - return self.__str__() - - def isInPullRequest(self) -> bool: - """Is in Pull Request?""" - if self.reference: - return self.reference.startswith("refs/pull") - return False - - def getPullRequestNumber(self) -> int: - """Get Pull Request Number""" - if self.isInPullRequest() and self.reference: - return int(self.reference.split("/")[2]) - return 0 - - def getPullRequestInfo(self) -> dict: - """Get information for the current pull request - - https://docs.github.com/en/enterprise-cloud@latest/rest/pulls/pulls#get-a-pull-request - """ - if not self.__prinfo__: - from ghastoolkit.octokit.octokit import RestRequest - - pull_number = self.getPullRequestNumber() - self.__prinfo__ = RestRequest().get( - "/repos/{owner}/{repo}/pulls/{pull_number}", - {"pull_number": pull_number}, - ) - return self.__prinfo__ - - def getPullRequestCommits(self) -> list[str]: - """Get Pull Request Commits""" - result = [] - if self.isInPullRequest(): - from ghastoolkit.octokit.octokit import RestRequest - - pull_number = self.getPullRequestNumber() - response = RestRequest().get( - "/repos/{owner}/{repo}/pulls/{pull_number}/commits", - {"pull_number": pull_number}, - ) - for commit in response: - result.append(commit.get("sha")) - return result - - @property - def clone_url(self) -> str: - if GitHub.github_app: - url = urlparse(GitHub.instance) - return f"{url.scheme}://x-access-token:{GitHub.token}@{url.netloc}/{self.owner}/{self.repo}.git" - elif GitHub.token: - url = urlparse(GitHub.instance) - return f"{url.scheme}://{GitHub.token}@{url.netloc}/{self.owner}/{self.repo}.git" - return f"{GitHub.instance}/{self.owner}/{self.repo}.git" - - def _cloneCmd(self, path: str, depth: Optional[int] = None) -> list[str]: - cmd = ["git", "clone"] - if self.branch: - cmd.extend(["-b", self.branch]) - if depth: - cmd.extend(["--depth", str(depth)]) - cmd.extend([self.clone_url, path]) - return cmd - - def clone( - self, - path: Optional[str] = None, - clobber: bool = False, - depth: Optional[int] = None, - ): - """Clone Repository - The clone path if left None will create a tmp folder for you - """ - if path: - self.clone_path = path - if not self.clone_path: - raise Exception(f"Clone path not set") - - if os.path.exists(self.clone_path) and clobber: - logger.debug(f"Path exists but deleting it ready for cloning") - shutil.rmtree(self.clone_path) - - elif not clobber and os.path.exists(self.clone_path): - logger.debug("Cloned repository already exists") - return - - cmd = self._cloneCmd(self.clone_path, depth=depth) - logger.debug(f"Cloning Command :: {cmd}") - - with open(os.devnull, "w") as null: - subprocess.check_call(cmd, stdout=null, stderr=null) - - def gitsha(self) -> str: - cmd = ["git", "rev-parse", "HEAD"] - result = ( - subprocess.check_output(cmd, cwd=self.clone_path).decode("ascii").strip() - ) - return result - - def getFile(self, path: str) -> str: - """Get a path relative from the base of the cloned repository""" - if not self.clone_path: - raise Exception(f"Unknown clone path") - return os.path.join(self.clone_path, path) - - def display(self): - if self.reference: - return f"{self.owner}/{self.repo}@{self.reference}" - return f"{self.owner}/{self.repo}" +logger = logging.getLogger("ghastoolkit.octokit.github") - @staticmethod - def parseRepository(name: str) -> "Repository": - ref = None - branch = None - if "@" in name: - name, branch = name.split("@", 1) - ref = f"refs/heads/{branch}" - owner, repo = name.split("/", 1) - return Repository(owner, repo, reference=ref, branch=branch) +class GitHub: + """The GitHub Class. + This API is used to configure the state for all Octokit apis. + Its a standard interface across all projects. + """ -class GitHub: repository: Repository = Repository("GeekMasher", "ghastoolkit") + """Repository""" + + owner: Optional[str] = None + """Owner / Organisation""" + + enterprise: Optional[str] = None + """Enterprise Name""" + token: Optional[str] = None + """GitHub Access Token""" # URLs instance: str = "https://github.com" + """Instance""" api_rest: str = "https://api.github.com" + """REST API URL""" api_graphql: str = "https://api.github.com/graphql" + """GraphQL API URL""" - enterprise: Optional[str] = None + server_version: Optional[Version] = None + """GitHub Enterprise Server Version""" github_app: bool = False + """GitHub App setting""" @staticmethod def init( @@ -185,14 +53,20 @@ def init( repo: Optional[str] = None, reference: Optional[str] = None, branch: Optional[str] = None, - token: Optional[str] = os.environ.get("GITHUB_TOKEN"), + token: Optional[str] = None, instance: Optional[str] = None, enterprise: Optional[str] = None, + retrieve_metadata: bool = True, ) -> None: - if repository: + """Initialise a GitHub class using a number of properties.""" + if repository and "/" in repository: GitHub.repository = Repository.parseRepository(repository) + GitHub.owner = GitHub.repository.owner + elif repository or owner: + GitHub.owner = owner or repository elif owner and repo: GitHub.repository = Repository(owner, repo) + GitHub.owner = owner if GitHub.repository: if reference: @@ -200,19 +74,29 @@ def init( if branch: GitHub.repository.branch = branch + if not token: + token = os.environ.get("GITHUB_TOKEN") GitHub.token = token + + if not instance: + instance = os.environ.get("GITHUB_SERVER_URL") + # instance - if instance: + if instance and instance != "": GitHub.instance = instance GitHub.api_rest, GitHub.api_graphql = GitHub.parseInstance(instance) + if GitHub.isEnterpriseServer() and retrieve_metadata: + # Get the server version + GitHub.getMetaInformation() + GitHub.enterprise = enterprise return @staticmethod def parseInstance(instance: str) -> Tuple[str, str]: - """Parse GitHub Instance""" + """Parse GitHub Instance.""" url = urlparse(instance) # GitHub Cloud (.com) @@ -220,10 +104,34 @@ def parseInstance(instance: str) -> Tuple[str, str]: api = url.scheme + "://api." + url.netloc return (api, f"{api}/graphql") # GitHub Ent Server - api = url.scheme + "://" + url.netloc + "/api/v3" + api = url.scheme + "://" + url.netloc + "/api" + + return (f"{api}/v3", f"{api}/graphql") - return (api, f"{api}/graphql") + @staticmethod + def isEnterpriseServer() -> bool: + """Is the GitHub instance an Enterprise Server.""" + return GitHub.instance != "https://github.com" @staticmethod def display() -> str: + """Display the GitHub Settings.""" return f"GitHub('{GitHub.repository.display()}', '{GitHub.instance}')" + + @staticmethod + def getOrganization() -> str: + """Get the Organization.""" + return GitHub.owner or GitHub.repository.owner + + @staticmethod + def getMetaInformation() -> Dict: + """Get the GitHub Meta Information.""" + from ghastoolkit.octokit.octokit import RestRequest + + response = RestRequest().session.get(f"{GitHub.api_rest}/meta") + + if response.headers.get("X-GitHub-Enterprise-Version"): + version = response.headers.get("X-GitHub-Enterprise-Version") + GitHub.server_version = Version(version) + + return response.json() diff --git a/vendor/ghastoolkit/octokit/graphql/__init__.py b/vendor/ghastoolkit/octokit/graphql/__init__.py new file mode 100644 index 0000000..5ecad9d --- /dev/null +++ b/vendor/ghastoolkit/octokit/graphql/__init__.py @@ -0,0 +1,102 @@ +DEPENDENCY_GRAPH_STATUS = """\ +{ + repository(owner: "$owner", name: "$repo") { + hasVulnerabilityAlertsEnabled + } +} +""" + +DEPENDENCY_GRAPH_ALERTS = """\ +{ + repository(owner: "$owner", name: "$repo") { + vulnerabilityAlerts(first: 100, states: [OPEN], $cursor) { + totalCount + pageInfo { + hasNextPage + endCursor + } + edges { + node { + number + state + createdAt + dismissReason + securityVulnerability { + package { + ecosystem + name + } + } + securityAdvisory { + ghsaId + severity + cwes(first: 100) { + edges { + node { + cweId + } + } + } + } + } + } + } + } +} +""" + +DEPENDENCY_GRAPH_INFO = """\ +{ + repository(owner: "$owner", name: "$repo") { + name + licenseInfo { + name + } + dependencyGraphManifests(first: 1, $manifests_cursor) { + totalCount + pageInfo { + hasNextPage + endCursor + } + edges { + node { + filename + dependencies(first: $dependencies_first, $dependencies_cursor) { + totalCount + pageInfo { + hasNextPage + endCursor + } + edges { + node { + packageName + packageManager + requirements + repository { + nameWithOwner + isArchived + isDisabled + isEmpty + isFork + isSecurityPolicyEnabled + isInOrganization + licenseInfo { + name + } + } + } + } + } + } + } + } + } +} +""" + + +QUERIES = { + "GetDependencyStatus": DEPENDENCY_GRAPH_STATUS, + "GetDependencyAlerts": DEPENDENCY_GRAPH_ALERTS, + "GetDependencyInfo": DEPENDENCY_GRAPH_INFO, +} diff --git a/vendor/ghastoolkit/octokit/octokit.py b/vendor/ghastoolkit/octokit/octokit.py index 3cc6506..53b19c1 100644 --- a/vendor/ghastoolkit/octokit/octokit.py +++ b/vendor/ghastoolkit/octokit/octokit.py @@ -1,43 +1,66 @@ +"""Octokit""" + import os import inspect import logging from string import Template -from typing import Any, Optional, Union +from typing import Any, Callable, Optional, Union from dataclasses import field, is_dataclass from requests import Session +from requests.adapters import HTTPAdapter, Retry from ratelimit import limits, sleep_and_retry +from ghastoolkit.errors import GHASToolkitAuthenticationError, GHASToolkitError from ghastoolkit.octokit.github import GitHub, Repository +from ghastoolkit.octokit.graphql import QUERIES # Assume REST requests are being done by a GitHub Token, not # a GitHub App which has a higher limit # https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#rate-limiting REST_MAX_CALLS = 80 # ~5000 per hour +GRAPHQL_MAX_CALLS = 100 # ~5000 per hour __OCTOKIT_PATH__ = os.path.dirname(os.path.realpath(__file__)) -__OCTOKIT_ERRORS__ = {401: "Authentication Issue"} +__OCTOKIT_ERRORS__ = { + 401: GHASToolkitAuthenticationError( + "Authentication / Permission Issue", status=401 + ), + 403: GHASToolkitAuthenticationError( + "Authentication / Permission Issue", status=403 + ), + 404: GHASToolkitError("Not Found", status=404), + 429: GHASToolkitError("Rate limit hit", status=429), + 500: GHASToolkitError("GitHub Server Error", status=500), +} # logger logger = logging.getLogger("ghastoolkit.octokit") +LOGLEVEL = os.environ.get("LOGLEVEL", "INFO").upper() +if isinstance(logging.getLevelName(LOGLEVEL), int): + logging.basicConfig(level=LOGLEVEL) class Octokit: + """Octokit base class.""" + @staticmethod def route(path: str, repository: Repository, rtype: str = "rest", **options) -> str: - """Generate Route string""" + """Generate Route string.""" formatted_path = Octokit.formatPath(path, repository, **options) if not formatted_path.startswith("/"): formatted_path = "/" + formatted_path + url = GitHub.api_rest if rtype == "rest" else GitHub.api_graphql return f"{url}{formatted_path}" @staticmethod def formatPath(path: str, repo: Repository, **options) -> str: + """Format Path.""" formatted_path = path.format( owner=repo.owner, org=repo.owner, repo=repo.repo, **options ) @@ -81,7 +104,9 @@ class RestRequest: PER_PAGE = 100 VERSION: str = "2022-11-28" - def __init__(self, repository: Optional[Repository] = None) -> None: + def __init__( + self, repository: Optional[Repository] = None, retries: Optional[Retry] = None + ) -> None: self.repository = repository or GitHub.repository self.session = Session() # https://docs.github.com/en/rest/overview/authenticating-to-the-rest-api @@ -91,9 +116,12 @@ def __init__(self, repository: Optional[Repository] = None) -> None: "Authorization": f"token {GitHub.token}", } + if retries: + self.session.mount("https://", HTTPAdapter(max_retries=retries)) + @staticmethod def restGet(url: str, authenticated: bool = False): - """Get Request Wrapper""" + """Get Request Wrapper.""" def decorator(func): def wrap(self, *args, **kwargs): @@ -129,10 +157,11 @@ def wrap(self, *args, **kwargs): params[argv] = argv_value args_index += 1 + # print(f"Request parameters :: '{params}'") result = rest.get(url, parameters=params, authenticated=authenticated) if response: - return func(self, responce=result, **kwargs) + return func(self, response=result, **kwargs) # TODO: runtime type checking @@ -169,10 +198,12 @@ def get( self, path: str, parameters: dict = {}, - expected: int = 200, + expected: Optional[int] = 200, authenticated: bool = False, + display_errors: bool = True, + error_handler: Optional[Callable[[int, dict], Any]] = None, ) -> Union[dict, list[dict]]: - """Get Request + """Get Request. Limits requests based on token """ @@ -184,7 +215,12 @@ def get( logger.debug(f"Fetching content from URL :: {url}") if authenticated and not self.session.headers.get("Authorization"): - raise Exception(f"GitHub Token required for this request") + raise GHASToolkitAuthenticationError( + "GitHub Token required for this request" + ) + + cursor = None + page = 1 # Page starts at 1 result = [] params = {} @@ -195,44 +231,75 @@ def get( params["per_page"] = RestRequest.PER_PAGE - page = 1 # index starts at 1 - while True: - params["page"] = page + if cursor: + params["after"] = cursor.replace("%3D", "=") + else: + params["page"] = page + + response = self.session.get(url, params=params) + # Every response should be a JSON (including errors) + response_json = response.json() - responce = self.session.get(url, params=params) - responce_json = responce.json() + if expected and response.status_code != expected: + if display_errors: + logger.error(f"Error code from server :: {response.status_code}") - if responce.status_code != expected: - logger.error(f"Error code from server :: {responce.status_code}") - logger.error(f"Content :: {responce_json}") - known_error = __OCTOKIT_ERRORS__.get(responce.status_code) + if error_handler: + return error_handler(response.status_code, response_json) + + known_error = __OCTOKIT_ERRORS__.get(response.status_code) if known_error: - raise Exception(known_error) - raise Exception("REST Request failed :: non-expected server error") + raise known_error + + # Handle errors in the response + if isinstance(response_json, dict) and response_json.get("message"): + # Custom error handler callback + if error_handler: + return error_handler(response.status_code, response_json) + + # Default error handling + message = response_json.get("message", "No message provided") + docs = response_json.get( + "documentation_url", "No documentation link provided" + ) + + logger.error(f"Error message from server :: {message}") + logger.error(f"Documentation Link :: {docs}") - if isinstance(responce_json, dict) and responce_json.get("errors"): - logger.error(responce_json.get("message")) - raise Exception("REST Request failed :: error from server") + raise GHASToolkitError(f"REST Request failed :: {message}", docs=docs) - if isinstance(responce_json, dict): - return responce_json + if isinstance(response_json, dict): + return response_json - result.extend(responce_json) + result.extend(response_json) # if the page is not full, we must have hit the end - if len(responce_json) < RestRequest.PER_PAGE: + if len(response_json) < RestRequest.PER_PAGE: break + # Use a cursor for pagination + if link := response.headers.get("Link"): + if next := [x for x in link.split(", ") if x.endswith('rel="next"')]: + next = next[0].split(">;")[0].replace("<", "") + # If `after` parameter is not in the URL + if after := next.split("&after="): + # We don't want to paginate if the cursor is a URL + if not after[0].startswith("http"): + cursor = after[0] + logger.debug(f"Cursor :: {cursor}") + page += 1 return result - def postJson(self, path: str, data: dict, expected: int = 200) -> dict: + def postJson( + self, path: str, data: dict, expected: int = 200, parameters={} + ) -> dict: repo = self.repository or GitHub.repository if not repo: raise Exception("Repository needs to be set") - url = Octokit.route(path, repo, rtype="rest") + url = Octokit.route(path, repo, rtype="rest", **parameters) logger.debug(f"Posting content from URL :: {url}") response = self.session.post(url, json=data) @@ -247,6 +314,35 @@ def postJson(self, path: str, data: dict, expected: int = 200) -> dict: return response.json() + def patchJson( + self, + path: str, + data: dict, + expected: Optional[Union[int, list[int]]] = 200, + parameters={}, + ) -> dict: + repo = self.repository or GitHub.repository + if not repo: + raise GHASToolkitError("Repository needs to be set") + + url = Octokit.route(path, repo, rtype="rest", **parameters) + logger.debug(f"Patching content from URL :: {url}") + + response = self.session.patch(url, json=data) + + if expected: + if (isinstance(expected, int) and response.status_code != expected) or ( + isinstance(expected, list) and response.status_code not in expected + ): + logger.error(f"Error code from server :: {response.status_code}") + logger.error(f"{response.content}") + known_error = __OCTOKIT_ERRORS__.get(response.status_code) + if known_error: + raise known_error + raise GHASToolkitError("Failed to patch data") + + return response.json() + DEFAULT_GRAPHQL_PATHS = [os.path.join(__OCTOKIT_PATH__, "graphql")] @@ -261,16 +357,25 @@ def __init__(self, repository: Optional[Repository] = None) -> None: "Accept": "application/vnd.github.hawkgirl-preview+json", "Authorization": f"token {GitHub.token}", } - self.queries = {} - - self.loadQueries(DEFAULT_GRAPHQL_PATHS) + # load in default hardcoded queries + self.queries = QUERIES + @sleep_and_retry + @limits(calls=GRAPHQL_MAX_CALLS, period=60) def query(self, name: str, options: dict[str, Any] = {}) -> dict: + """Run a GraphQL query. + + https://docs.github.com/en/enterprise-cloud@latest/graphql/overview/about-the-graphql-api + https://docs.github.com/en/enterprise-cloud@latest/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api#primary-rate-limit + """ logger.debug(f"Loading Query by Name :: {name}") query_content = self.queries.get(name) if not query_content: - raise Exception(f"Failed to load GraphQL query :: {name}") + raise GHASToolkitError( + f"Failed to load GraphQL query :: {name}", + docs="https://docs.github.com/en/enterprise-cloud@latest/graphql/overview/about-the-graphql-api", + ) cursor = f'after: "{self.cursor}"' if self.cursor != "" else "" @@ -282,9 +387,13 @@ def query(self, name: str, options: dict[str, Any] = {}) -> dict: if response.status_code != 200: logger.error(f"GraphQL API Status :: {response.status_code}") logger.error(f"GraphQL Content :: {response.content}") - raise Exception(f"Failed to get data from GraphQL API") + raise GHASToolkitError( + f"Failed to get data from GraphQL API", + docs="https://docs.github.com/en/enterprise-cloud@latest/graphql/overview/about-the-graphql-api", + ) rjson = response.json() + if rjson.get("errors"): for err in rjson.get("errors"): logger.warning(f"GraphQL Query failed :: {err.get('message')}") diff --git a/vendor/ghastoolkit/octokit/repository.py b/vendor/ghastoolkit/octokit/repository.py new file mode 100644 index 0000000..721a943 --- /dev/null +++ b/vendor/ghastoolkit/octokit/repository.py @@ -0,0 +1,273 @@ +import os +import re +import shutil +import logging +import tempfile +import subprocess +from dataclasses import dataclass +from typing import Optional, Union +from urllib.parse import urlparse + +from ghastoolkit.errors import GHASToolkitError + + +logger = logging.getLogger("ghastoolkit.octokit.repository") + + +@dataclass +class Repository: + """GitHub Repository.""" + + owner: str + """Owner""" + repo: str + """Repository name""" + + reference: Optional[str] = None + """Reference (`refs/heads/main`)""" + branch: Optional[str] = None + """Branch / Tab name""" + + path: Optional[str] = None + """Path inside the repository""" + + pr_number: Optional[int] = None + """Pull Request Number (if in a PR)""" + + __prinfo__: Optional[dict] = None + + sha: Optional[str] = None + """Git SHA""" + + clone_path: Optional[str] = None + """Clone Path""" + + repo_token: Optional[str] = None + """Repository Access Token""" + + is_github_app_token: bool = False + """Whether the token is a GitHub App Token""" + + def __post_init__(self) -> None: + if self.reference and not self.branch: + if not self.isInPullRequest(): + _, _, branch = self.reference.split("/", 2) + self.branch = branch + if self.branch and not self.reference: + self.reference = f"refs/heads/{self.branch}" + + if not self.clone_path: + self.clone_path = os.path.join(tempfile.gettempdir(), self.repo) + + def __str__(self) -> str: + """To String.""" + name = f"{self.owner}/{self.repo}" + if self.reference: + return f"{name}:{self.reference}" + elif self.branch: + return f"{name}@{self.branch}" + return name + + def __repr__(self) -> str: + return self.__str__() + + def __hash__(self) -> int: + return hash(self.__str__()) + + def isInPullRequest(self) -> bool: + """Check if the current reference is in a Pull Request.""" + if self.reference: + return self.reference.startswith("refs/pull") + return False + + def getPullRequestNumber(self) -> int: + """Get Pull Request Number / ID.""" + if self.isInPullRequest() and self.reference: + return int(self.reference.split("/")[2]) + return 0 + + def getPullRequestInfo(self) -> dict: + """Get information for the current Pull Request. + + https://docs.github.com/en/enterprise-cloud@latest/rest/pulls/pulls#get-a-pull-request + """ + if not self.__prinfo__: + from ghastoolkit.octokit.octokit import RestRequest + + self.pr_number = self.getPullRequestNumber() + self.__prinfo__ = RestRequest().get( + "/repos/{owner}/{repo}/pulls/{pull_number}", + {"pull_number": self.pr_number}, + ) + return self.__prinfo__ + + def getPullRequestCommits(self) -> list[str]: + """Get list of Pull Request commits.""" + result = [] + + if self.isInPullRequest(): + from ghastoolkit.octokit.octokit import RestRequest + + pull_number = self.getPullRequestNumber() + response = RestRequest().get( + "/repos/{owner}/{repo}/pulls/{pull_number}/commits", + {"pull_number": pull_number}, + ) + for commit in response: + result.append(commit.get("sha")) + return result + + def getPullRequestComments(self) -> list[dict[str, Union[int, str]]]: + """Get list of Pull Request comments.""" + result = [] + if self.isInPullRequest(): + from ghastoolkit.octokit.octokit import RestRequest + + issue_number = self.getPullRequestNumber() + response = RestRequest().get( + "/repos/{owner}/{repo}/issues/{issue_number}/comments", + {"issue_number": issue_number}, + ) + for comment in response: + result.append( + { + "id": comment.get("id"), + "body": comment.get("body", ""), + } + ) + return result + + def createPullRequestComment(self, comment_body: str) -> None: + """Create a new Pull Request comment.""" + if self.isInPullRequest(): + from ghastoolkit.octokit.octokit import RestRequest + + issue_number = self.getPullRequestNumber() + RestRequest().postJson( + "/repos/{owner}/{repo}/issues/{issue_number}/comments", + {"body": comment_body}, + expected=201, + parameters={"issue_number": issue_number}, + ) + return + + def updatePullRequestComment(self, comment_id: int, comment_body: str) -> None: + """Update an existing Pull Request comment.""" + if self.isInPullRequest(): + from ghastoolkit.octokit.octokit import RestRequest + + RestRequest().patchJson( + "/repos/{owner}/{repo}/issues/comments/{comment_id}", + {"body": comment_body}, + expected=200, + parameters={"comment_id": comment_id}, + ) + return + + @property + def clone_url(self) -> str: + """Repository clone URL.""" + from ghastoolkit.octokit.github import GitHub + + url = urlparse(GitHub.instance) + if self.repo_token: + if self.is_github_app_token: + return f"{url.scheme}://x-access-token:{self.repo_token}@{url.netloc}/{self.owner}/{self.repo}" + else: + return f"{url.scheme}://{self.repo_token}@{url.netloc}/{self.owner}/{self.repo}" + elif GitHub.github_app: + return f"{url.scheme}://x-access-token:{GitHub.token}@{url.netloc}/{self.owner}/{self.repo}.git" + elif GitHub.token: + return f"{url.scheme}://{GitHub.token}@{url.netloc}/{self.owner}/{self.repo}.git" + return f"{GitHub.instance}/{self.owner}/{self.repo}.git" + + def _cloneCmd(self, path: str, depth: Optional[int] = None) -> list[str]: + cmd = ["git", "clone"] + if self.branch: + cmd.extend(["-b", self.branch]) + if depth: + cmd.extend(["--depth", str(depth)]) + cmd.extend([self.clone_url, path]) + return cmd + + def clone( + self, + path: Optional[str] = None, + clobber: bool = False, + depth: Optional[int] = None, + ): + """Clone Repository based on url. + + path: str - if left `None`, it will create a tmp folder for you. + """ + if path: + self.clone_path = path + if not self.clone_path: + raise Exception(f"Clone path not set") + + if os.path.exists(self.clone_path) and clobber: + logger.debug(f"Path exists but deleting it ready for cloning") + shutil.rmtree(self.clone_path) + + elif not clobber and os.path.exists(self.clone_path): + logger.debug("Cloned repository already exists") + return + + cmd = self._cloneCmd(self.clone_path, depth=depth) + logger.debug(f"Cloning Command :: {cmd}") + + with open(os.devnull, "w") as null: + subprocess.check_call(cmd, stdout=null, stderr=null) + + def gitsha(self) -> str: + """Get the current Git SHA.""" + cmd = ["git", "rev-parse", "HEAD"] + result = ( + subprocess.check_output(cmd, cwd=self.clone_path).decode("ascii").strip() + ) + return result + + def getFile(self, path: str) -> str: + """Get a path relative from the base of the cloned repository.""" + if not self.clone_path: + raise GHASToolkitError(f"Unknown clone path") + return os.path.join(self.clone_path, path) + + def display(self) -> str: + """Display the repository as a string.""" + if self.reference: + return f"{self.owner}/{self.repo}@{self.reference}" + return f"{self.owner}/{self.repo}" + + @staticmethod + def parseRepository(name: str) -> "Repository": + """Parse the repository name into a Repository object. + + Samples: + - owner/repo + - owner/repo@branch + - owner/repo:relative/path/in/repo + - owner/repo/relative/path/in/repo + - owner/repo:relative/path/in/repo@branch + """ + ref = None + branch = None + path = None + + # validate the repository name + regex = re.compile( + r"^[a-zA-Z0-9-_\.]+/[a-zA-Z0-9-_\.]+((:|/)[a-zA-Z0-9-_/\.]+)?(@[a-zA-Z0-9-_/]+)?$" + ) + if not regex.match(name): + raise SyntaxError(f"Invalid repository name: '{name}'") + + if "@" in name: + name, branch = name.split("@", 1) + ref = f"refs/heads/{branch}" + if ":" in name: + name, path = name.split(":", 1) + if name.count("/") > 1: + owner, repo, path = name.split("/", 2) + else: + owner, repo = name.split("/", 1) + return Repository(owner, repo, reference=ref, branch=branch, path=path) diff --git a/vendor/ghastoolkit/octokit/secretscanning.py b/vendor/ghastoolkit/octokit/secretscanning.py index 3c5deeb..18dbee5 100644 --- a/vendor/ghastoolkit/octokit/secretscanning.py +++ b/vendor/ghastoolkit/octokit/secretscanning.py @@ -1,7 +1,13 @@ import logging from dataclasses import dataclass, field -from typing import Optional - +from datetime import datetime, timedelta +from typing import Any, Optional + +from ghastoolkit.errors import ( + GHASToolkitAuthenticationError, + GHASToolkitError, + GHASToolkitTypeError, +) from ghastoolkit.octokit.github import GitHub, Repository from ghastoolkit.octokit.octokit import OctoItem, RestRequest, loadOctoItem @@ -11,28 +17,53 @@ @dataclass class SecretAlert(OctoItem): + """Secret Scanning Alert.""" + number: int + """Number / Identifier""" state: str - - created_at: str + """Alert State""" secret_type: str + """Secret Scanning type""" secret_type_display_name: str + """Secret Scanning type display name""" secret: str + """Secret value (sensitive)""" + + created_at: str + """Created Timestamp""" + resolved_at: Optional[str] = None + """Resolved Timestamp""" + resolved_by: Optional[dict[str, Any]] = None + """Resolved By""" + + push_protection_bypassed: bool = False + """Push Protection Bypassed""" + push_protection_bypassed_by: Optional[dict[str, Any]] = None + """Push Protection Bypassed By""" + push_protection_bypassed_at: Optional[str] = None + """Push Protection Bypassed At""" + + resolution_comment: Optional[str] = None + """Resolution Comment""" + + validity: str = "unknown" + """Validity of secret""" _locations: list[dict] = field(default_factory=list) _sha: Optional[str] = None @property def locations(self) -> list[dict]: - """Get Alert locations (use cache or request from API)""" + """Get Alert locations. Uses a cached version or request from API.""" if not self._locations: self._locations = SecretScanning().getAlertLocations(self.number) return self._locations @property def commit_sha(self) -> Optional[str]: - """Get commit sha if present""" + """Get commit sha if present.""" if self._sha is None: for loc in self.locations: if loc.get("type") == "commit": @@ -40,40 +71,136 @@ def commit_sha(self) -> Optional[str]: break return self._sha + @property + def mttr(self) -> Optional[timedelta]: + """Calculate Mean Time To Resolution / Remidiate (MTTR) for a closed/fixed alert.""" + if self.created_at and self.resolved_at: + # GitHub returns ISO 8601 timestamps with a Z at the end + # datetime.fromisoformat() doesn't like the Z + created = self.created_at.replace("Z", "+00:00") + resolved = self.resolved_at.replace("Z", "+00:00") + return datetime.fromisoformat(resolved) - datetime.fromisoformat(created) + return None + def __str__(self) -> str: return f"SecretAlert({self.number}, '{self.secret_type}')" class SecretScanning: + """Secret Scanning API.""" + def __init__(self, repository: Optional[Repository] = None) -> None: + """Initialise Secret Scanning API.""" self.repository = repository or GitHub.repository if not self.repository: - raise Exception("SecretScanning requires Repository to be set") + raise GHASToolkitError("SecretScanning requires Repository to be set") self.rest = RestRequest(self.repository) + self.state = None + + def isEnabled(self) -> bool: + """Check to see if Secret Scanning is enabled or not via the repository status. + + Permissions: + - "Administration" repository permissions (read) + + https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#get-a-repository + """ + if not self.state: + self.state = self.getStatus() + + if self.state.get("visibility") == "public": + logger.debug("All public repositories have secret scanning enabled") + return True + if saa := self.state.get("security_and_analysis"): + return saa.get("secret_scanning", {}).get("status", "disabled") == "enabled" + + raise GHASToolkitAuthenticationError( + "Failed to fetch Secret Scanning repository settings", + docs="https://docs.github.com/en/enterprise-cloud@latest/rest/repos/repos#get-a-repository", + permissions=["Repository Administration (read)"], + ) + + def isPushProtectionEnabled(self) -> bool: + """Check if Push Protection is enabled. + + Permissions: + - "Administration" repository permissions (read) + + https://docs.github.com/en/rest/repos/repos?apiVersion=2022-11-28#get-a-repository + """ + if not self.state: + self.state = self.getStatus() + + if ssa := self.state.get("security_and_analysis"): + return ( + ssa.get("secret_scanning_push_protection", {}).get("status", "disabled") + == "enabled" + ) + + raise GHASToolkitAuthenticationError( + "Failed to get Push Protection status", + permissions=["Repository Administration (read)"], + docs="https://docs.github.com/en/rest/repos/repos#get-a-repository", + ) + + def getStatus(self) -> dict: + """Get Status of GitHub Advanced Security.""" + result = self.rest.get("/repos/{owner}/{repo}") + if isinstance(result, dict): + return result + raise GHASToolkitTypeError( + "Failed to get the current state of secret scanning", + permissions=["Repository Administration (read)"], + docs="https://docs.github.com/en/rest/repos/repos#get-a-repository", + ) + def getOrganizationAlerts(self, state: Optional[str] = None) -> list[dict]: - """Get Organization Alerts + """Get Organization Alerts. + + Permissions: + - "Secret scanning alerts" repository permissions (read) https://docs.github.com/en/rest/secret-scanning#list-secret-scanning-alerts-for-an-organization """ results = self.rest.get("/orgs/{org}/secret-scanning/alerts", {"state": state}) if isinstance(results, list): return results - raise Exception(f"Error getting organization secret scanning results") - @RestRequest.restGet("/repos/{owner}/{repo}/secret-scanning/alerts") + raise GHASToolkitTypeError( + f"Error getting organization secret scanning results", + permissions=["Secret scanning alerts (read)"], + docs="https://docs.github.com/en/rest/secret-scanning#list-secret-scanning-alerts-for-an-organization", + ) + def getAlerts(self, state: str = "open") -> list[SecretAlert]: - """Get Repository alerts + """Get Repository alerts. + + Permissions: + - "Secret scanning alerts" repository permissions (read) https://docs.github.com/en/rest/secret-scanning#list-secret-scanning-alerts-for-a-repository """ - return [] + + results = self.rest.get( + "/repos/{owner}/{repo}/secret-scanning/alerts", {"state": state} + ) + if isinstance(results, list): + return [loadOctoItem(SecretAlert, item) for item in results] + + raise GHASToolkitTypeError( + "Error getting secret scanning alerts", + docs="https://docs.github.com/en/rest/secret-scanning#list-secret-scanning-alerts-for-a-repository", + ) def getAlert( self, alert_number: int, state: Optional[str] = None ) -> Optional[SecretAlert]: - """Get Alert by `alert_number` + """Get Alert by `alert_number`. + + Permissions: + - "Secret scanning alerts" repository permissions (read) https://docs.github.com/en/rest/secret-scanning#get-a-secret-scanning-alert """ @@ -83,9 +210,18 @@ def getAlert( ) if isinstance(results, dict): return loadOctoItem(SecretAlert, results) + raise GHASToolkitTypeError( + "Error getting secret scanning alert", + docs="https://docs.github.com/en/rest/secret-scanning#get-a-secret-scanning-alert", + ) def getAlertsInPR(self) -> list[SecretAlert]: - """Get Alerts in a Pull Request""" + """Get Alerts in a Pull Request. + + Permissions: + - "Secret scanning alerts" repository permissions (read) + - "Pull requests" repository permissions (read) + """ results = [] pr_commits = self.repository.getPullRequestCommits() logger.debug(f"Number of Commits in PR :: {len(pr_commits)}") @@ -97,7 +233,10 @@ def getAlertsInPR(self) -> list[SecretAlert]: return results def getAlertLocations(self, alert_number: int) -> list[dict]: - """Get Alert Locations by `alert_number` + """Get Alert Locations by `alert_number`. + + Permissions: + - "Secret scanning alerts" repository permissions (read) https://docs.github.com/en/rest/secret-scanning#list-locations-for-a-secret-scanning-alert """ @@ -107,4 +246,7 @@ def getAlertLocations(self, alert_number: int) -> list[dict]: ) if isinstance(results, list): return results - raise Exception(f"Error getting alert locations") + raise GHASToolkitTypeError( + f"Error getting alert locations", + docs="https://docs.github.com/en/rest/secret-scanning#list-locations-for-a-secret-scanning-alert", + ) diff --git a/vendor/ghastoolkit/secretscanning/secretalerts.py b/vendor/ghastoolkit/secretscanning/secretalerts.py index 1d1aacc..9f103b4 100644 --- a/vendor/ghastoolkit/secretscanning/secretalerts.py +++ b/vendor/ghastoolkit/secretscanning/secretalerts.py @@ -33,7 +33,7 @@ def commit_sha(self) -> Optional[str]: if self._sha is None: for loc in self.locations: if loc.get("type") == "commit": - self._sha = loc.get("details", {}).get("blob_sha") + self._sha = loc.get("details", {}).get("commit_sha") break return self._sha diff --git a/vendor/ghastoolkit/supplychain/__main__.py b/vendor/ghastoolkit/supplychain/__main__.py new file mode 100644 index 0000000..aa3a03a --- /dev/null +++ b/vendor/ghastoolkit/supplychain/__main__.py @@ -0,0 +1,84 @@ +"""Supply Chain Toolkit CLI.""" + +from argparse import Namespace +import logging + +from ghastoolkit.octokit.dependencygraph import DependencyGraph +from ghastoolkit.octokit.github import GitHub +from ghastoolkit.utils.cli import CommandLine + + +def runDefault(arguments): + depgraph = DependencyGraph(GitHub.repository) + bom = depgraph.exportBOM() + packages = bom.get("sbom", {}).get("packages", []) + + logging.info(f"Total Dependencies :: {len(packages)}") + + info = bom.get("sbom", {}).get("creationInfo", {}) + logging.info(f"SBOM Created :: {info.get('created')}") + + logging.info("\nTools:") + for tool in info.get("creators", []): + logging.info(f" - {tool}") + + +def runOrgAudit(arguments): + """Run an audit on an organization.""" + licenses = arguments.licenses.split(",") + logging.info(f"Licenses :: {','.join(licenses)}") + + if arguments.debug: + logging.getLogger("ghastoolkit.octokit.dependencygraph").setLevel(logging.DEBUG) + + depgraph = DependencyGraph() + + dependencies = depgraph.getOrganizationDependencies() + + for repo, deps in dependencies.items(): + # get a list of deps that match the licenses + violations = deps.findLicenses(licenses) + # get a list of deps with no license data + unknowns = deps.findUnknownLicenses() + + if len(violations) == 0 and len(unknowns) == 0: + continue + + logging.info(f" > {repo} :: {len(deps)}") + logging.info(f" |-> Unknowns :: {len(unknowns)}") + for unknown in unknowns: + logging.warning(f" |---> {unknown.getPurl()}") + + logging.info(f" |-> Violations :: {len(violations)}") + for violation in violations: + logging.warning(f" |---> {violation.getPurl()}") + + +class SupplyChainCLI(CommandLine): + def arguments(self): + """CLI for Supply Chain Toolkit.""" + if self.subparser: + self.addModes(["org-audit"]) + + parser = self.parser.add_argument_group("supplychain") + parser.add_argument( + "--licenses", + default="GPL-*,AGPL-*,LGPL-*", + help="License(s) to check for (default: 'GPL-*,AGPL-*,LGPL-*')", + ) + + def run(self, arguments: Namespace): + """Run Supply Chain Toolkit.""" + if arguments.mode == "default": + runDefault(arguments) + elif arguments.mode == "org-audit": + runOrgAudit(arguments) + else: + self.parser.print_help() + exit(1) + + +if __name__ == "__main__": + parser = SupplyChainCLI() + parser.run(parser.parse_args()) + logging.info("Done.") diff --git a/vendor/ghastoolkit/supplychain/advisories.py b/vendor/ghastoolkit/supplychain/advisories.py index 1c54bbb..b5a7015 100644 --- a/vendor/ghastoolkit/supplychain/advisories.py +++ b/vendor/ghastoolkit/supplychain/advisories.py @@ -1,13 +1,288 @@ +import logging +import os +import json +from typing import List, Dict, Optional from dataclasses import dataclass, field -from typing import Optional + +from semantic_version import SimpleSpec, Version + from ghastoolkit.octokit.octokit import OctoItem +logger = logging.getLogger("ghastoolkit.supplychain.advisories") + + +def parseVersion(data: str) -> str: + """Parse Version to help semantic_version process the version.""" + stack = data.split(".") + if len(stack) == 1: + return f"{data}.0.0" + elif len(stack) == 2: + return f"{data}.0" + return data + + +@dataclass +class AdvisoryAffect: + """Advisory Affected.""" + + ecosystem: str + """Ecosystem / Dependency Manager / PURL type""" + package: str + """Package Full Name ([namespace +] name""" + + introduced: Optional[str] = None + """Introduced Version""" + fixed: Optional[str] = None + """Fixed Version""" + + package_dependency: Optional["Dependency"] = None + + def __post_init__(self): + self.ecosystem = self.ecosystem.lower() + # load package as dependency + from ghastoolkit import Dependency + + # HACK can we do this a better way? + if self.ecosystem in ["maven", "nuget"]: + namespace, name = self.package.rsplit(".", 1) + else: + namespace = None + name = self.package + + self.package_dependency = Dependency(name, namespace, manager=self.ecosystem) + + if self.introduced: + self.introduced = parseVersion(self.introduced) + if self.fixed: + self.fixed = parseVersion(self.fixed) + + @staticmethod + def loadAffect(data: dict) -> "AdvisoryAffect": + """Load affects from data. + + https://github.com/github/advisory-database + """ + # get introduced and fixed versions + events = data.get("ranges", [{}])[0].get("events", []) + introduced = None + fixed = None + for event in events: + if event.get("introduced"): + introduced = event.get("introduced") + if event.get("fixed"): + fixed = event.get("fixed") + + adaff = AdvisoryAffect( + data.get("package", {}).get("ecosystem", "NA").lower(), + data.get("package", {}).get("name", "NA"), + introduced=introduced, + fixed=fixed, + ) + return adaff + + def check(self, dependency: "Dependency") -> bool: + """Check to see in the dependency is affected by the advisory.""" + + from ghastoolkit import Dependency + + if not isinstance(dependency, Dependency): + raise Exception(f"Unknown type provided :: {type(dependency)}") + # Advisory package dependency + if not self.package_dependency: + return False + # manager / ecosystem + if dependency.manager != self.ecosystem: + return False + # name + if dependency.name != self.package_dependency.name: + return False + # if not advisory version provided, then it's affected + if not self.introduced or not self.fixed: + return True + + # no versions provided + if not dependency.version: + return False + return self.checkVersion(dependency.version) + + def checkVersion(self, version: str) -> bool: + """Check version data.""" + if not self.introduced or not self.fixed: + return False + logging.debug( + f"Check Versions :: {self.introduced} > {parseVersion(version)} < {self.fixed}" + ) + spec = SimpleSpec(f">={self.introduced},<{self.fixed}") + return Version(parseVersion(version)) in spec + @dataclass class Advisory(OctoItem): + """GitHub Advisory.""" + ghsa_id: str + """GitHub Security Advisory Identifier""" severity: str + """Severity level""" + + aliases: List[str] = field(default_factory=list) + """List of aliases (CVEs)""" summary: Optional[str] = None + """Summary / Description of the advisory""" + description: Optional[str] = None + """Description of the advisory""" url: Optional[str] = None - cwes: list[str] = field(default_factory=list) + """Reference URL""" + + cve_id: Optional[str] = None + """CVE ID (if applicable)""" + cwes: List[str] = field(default_factory=list) + """List of CWEs""" + + cvss: Optional[dict] = None + """CVSS Score""" + cvss_severities: Dict[str, dict] = field(default_factory=dict) + """CVSS Severities""" + + identifiers: List[dict] = field(default_factory=list) + """List of identifiers""" + references: List[dict] = field(default_factory=list) + """List of references""" + + published_at: Optional[str] = None + """Published Timestamp""" + updated_at: Optional[str] = None + """Updated Timestamp""" + withdrawn_at: Optional[str] = None + + affected: List[AdvisoryAffect] = field(default_factory=list) + """Affected versions""" + + def __post_init__(self): + """Post Init.""" + self.ghsa_id = self.ghsa_id.lower() + self.severity = self.severity.lower() + + # cwes checking and processing + cwes = [] + for cwe in self.cwes: + if isinstance(cwe, dict): + cwes.append(cwe.get("cwe_id")) + else: + cwes.append(cwe) + self.cwes = cwes + + @staticmethod + def load(path: str) -> "Advisory": + """Load Advisory from path using GitHub Advisory Spec.""" + if not os.path.exists(path): + raise Exception(f"Advisory path does not exist") + + _, ext = os.path.splitext(path) + if ext == ".json": + return Advisory.loadJson(path) + + raise Exception("Unsupported Advisory file type") + + @staticmethod + def loadJson(path: str) -> "Advisory": + """Load Advisory from JSON file.""" + logger.debug(f"Loading Advisory :: {path}") + with open(path, "r") as handle: + data = json.load(handle) + + affected = [] + for affect in data.get("affected", []): + affected.append(AdvisoryAffect.loadAffect(affect)) + + advisory = Advisory( + ghsa_id=data.get("id", data.get("ghas_id", "NA")), + severity=data.get("database_specific", {}).get("severity", "NA").lower(), + aliases=data.get("aliases", []), + summary=data.get("summary"), + affected=affected, + ) + return advisory + + def check(self, dependency: "Dependency") -> Optional["Advisory"]: + """Check if dependency is affected by advisory.""" + for affect in self.affected: + if affect.check(dependency): + return self + return + + def cvss_score(self, version: int = 3) -> Optional[float]: + """Get CVSS Score.""" + if version not in [3, 4]: + raise Exception(f"Unknown CVSS version :: {version}") + + if version == 3: + if cvss := self.cvss_severities.get("cvss_v3"): + return cvss.get("score") + elif cvss := self.cvss: + return cvss.get("score") + elif version == 4: + if cvss := self.cvss_severities.get("cvss_v4"): + return cvss.get("score") + return None + + +class Advisories: + """GitHub Advisory List.""" + + def __init__(self) -> None: + """Initialise Advisories.""" + self.advisories: List[Advisory] = [] + + def loadAdvisories(self, path: str): + """Load a single file or folder of advisories.""" + if not os.path.exists(path): + raise Exception("Advisories path does not exist") + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for file in files: + _, ext = os.path.splitext(file) + if ext in [".json"]: + fpath = os.path.join(root, file) + self.loadAdvisory(fpath) + else: + self.loadAdvisory(path) + + def loadAdvisory(self, path: str): + """Load file with an advisory.""" + if not os.path.exists(path): + raise Exception(f"Path does not exist") + self.advisories.append(Advisory.load(path)) + + def find(self, search: str) -> Optional[Advisory]: + """Find by id or aliases.""" + search = search.lower() + logging.debug(f"Searching for advisory :: {search}") + + for advisory in self.advisories: + if advisory.ghsa_id == search: + return advisory + if search in advisory.aliases: + return advisory + return + + def check(self, dependency: "Dependency") -> List[Advisory]: + """Check if dependency is affected by any advisory in the list of advisories.""" + results = [] + for a in self.advisories: + result = a.check(dependency) + if result: + results.append(result) + + return results + + def append(self, advisory: Advisory): + """Append advisory.""" + if not isinstance(advisory, Advisory): + raise Exception(f"Non-Advisory type tring to be appended") + self.advisories.append(advisory) + + def __len__(self) -> int: + """To String.""" + return len(self.advisories) diff --git a/vendor/ghastoolkit/supplychain/dependencies.py b/vendor/ghastoolkit/supplychain/dependencies.py index 51f4ce5..a834b51 100644 --- a/vendor/ghastoolkit/supplychain/dependencies.py +++ b/vendor/ghastoolkit/supplychain/dependencies.py @@ -2,8 +2,9 @@ from dataclasses import dataclass, field from datetime import datetime import re -from typing import Optional +from typing import Optional, Union +from ghastoolkit.octokit.github import Repository from ghastoolkit.supplychain.dependencyalert import DependencyAlert from ghastoolkit.supplychain.licensing import NO_LICENSES, Licenses @@ -12,20 +13,38 @@ @dataclass class Dependency: + """Dependency.""" + name: str + """Name of the Dependency""" namespace: Optional[str] = None + """Namespace of the Dependency""" version: Optional[str] = None + """Version of the Dependency""" manager: Optional[str] = None + """Package Manager""" path: Optional[str] = None + """Path to the Dependency""" qualifiers: dict[str, str] = field(default_factory=dict) - - # Licensing information - licence: Optional[str] = None - # Security Alerts + """Qualifiers""" + license: Optional[str] = None + """License information""" alerts: list[DependencyAlert] = field(default_factory=list) + """Security Alerts""" + + repository: Optional[Union[str, Repository]] = None + """GitHub Repository for the dependency""" + + def __post_init__(self): + # normalize manager + if self.manager: + self.manager = self.manager.lower() + if self.repository and isinstance(self.repository, str): + self.repository = Repository.parseRepository(self.repository) def getPurl(self, version: bool = True) -> str: - """Get PURL + """Create a PURL from the Dependency. + https://github.com/package-url/purl-spec """ result = f"pkg:" @@ -41,6 +60,7 @@ def getPurl(self, version: bool = True) -> str: @staticmethod def fromPurl(purl: str) -> "Dependency": + """Create a Dependency from a PURL.""" dep = Dependency("") # version (at end) if "@" in purl: @@ -70,7 +90,7 @@ def fromPurl(purl: str) -> "Dependency": @property def fullname(self) -> str: - """Full Name of the Dependency""" + """Full Name of the Dependency.""" if self.namespace: sep = "/" if self.manager == "maven": @@ -79,13 +99,19 @@ def fullname(self) -> str: return self.name def __str__(self) -> str: + """To String (PURL).""" return self.getPurl() def __repr__(self) -> str: return self.getPurl() + def __hash__(self) -> int: + return hash(self.getPurl()) + class Dependencies(list[Dependency]): + """List of Dependencies.""" + def exportBOM( self, tool: str, @@ -95,7 +121,7 @@ def exportBOM( version: str = "0.0.0", url: str = "", ) -> dict: - """Create a dependency graph submission JSON payload for GitHub""" + """Create a dependency graph submission JSON payload for GitHub.""" resolved = {} for dep in self: name = dep.name @@ -122,35 +148,50 @@ def exportBOM( return data def findLicenses(self, licenses: list[str]) -> "Dependencies": - """Find Denied License""" + """Find dependencies with a given license.""" regex_list = [re.compile(name_filter) for name_filter in licenses] return Dependencies( [ dep for dep in self - if any(regex.search(dep.licence or "NA") for regex in regex_list) + if any(regex.search(dep.license or "NA") for regex in regex_list) ] ) def findUnknownLicenses( self, licenses: Optional[list[str]] = None ) -> "Dependencies": - """Find all the dependencies with no license""" + """Find all the dependencies with no licensing information.""" licenses = licenses or NO_LICENSES return self.findLicenses(licenses) def applyLicenses(self, licenses: Licenses): - """Given a list of licenses (Licenses) apply a license""" + """Given a list of licenses (Licenses) apply a license.""" for i, dep in enumerate(self): - if dep.licence and dep.licence not in NO_LICENSES: + if dep.license and dep.license not in NO_LICENSES: continue purl = dep.getPurl(version=False) dblicense = licenses.find(purl) if dblicense: - dep.licence = " OR ".join(dblicense) + dep.license = " OR ".join(dblicense) + self[i] = dep + + def applyClearlyDefined(self): + """Reachout to ClearlyDefinded API, get the licenses for a component, and update all the Dependencies.""" + from ghastoolkit.octokit.clearlydefined import ClearlyDefined + + clearly = ClearlyDefined() + + for i, dep in enumerate(self): + if dep.license and dep.license not in NO_LICENSES: + continue + licenses = clearly.getLicenses(dep) + if licenses: + dep.license = " OR ".join(licenses) self[i] = dep def contains(self, dependency: Dependency) -> bool: + """Contains the dependency.""" purl = dependency.getPurl(version=False) for dep in self: if dep.name == dependency.name or dep.getPurl(version=False) == purl: @@ -158,14 +199,14 @@ def contains(self, dependency: Dependency) -> bool: return False def find(self, name: str) -> Optional[Dependency]: - """Find by name""" + """Find by name.""" for dep in self: if dep.name == name or dep.fullname == name: return dep logger.debug(f"Unable to find by name :: {name}") def findPurl(self, purl: str) -> Optional[Dependency]: - """Find by PURL""" + """Find by PURL.""" purldep = Dependency.fromPurl(purl) for dep in self: if purldep.name == purldep.fullname or dep.fullname == dep.fullname: @@ -173,8 +214,21 @@ def findPurl(self, purl: str) -> Optional[Dependency]: logger.debug(f"Unable to find by PURL :: {purl}") def findNames(self, names: list[str]) -> "Dependencies": - """Find by Name using wildcards""" + """Find by Name using wildcards.""" regex_list = [re.compile(name_filter) for name_filter in names] return Dependencies( [dep for dep in self if any(regex.search(dep.name) for regex in regex_list)] ) + + def updateDependency(self, dependency: Dependency): + """Update a dependency in our list with the incoming information.""" + for dep in self: + if dependency.name == dep.name or dependency.fullname == dep.fullname: + dep.__dict__.update(dependency.__dict__) + # self[i] = new_dep + break + + def updateDependencies(self, dependencies: "Dependencies"): + """Update a list of dependencies.""" + for dep in dependencies: + self.updateDependency(dep) diff --git a/vendor/ghastoolkit/supplychain/dependencyalert.py b/vendor/ghastoolkit/supplychain/dependencyalert.py index e3cca71..cc8bfd6 100644 --- a/vendor/ghastoolkit/supplychain/dependencyalert.py +++ b/vendor/ghastoolkit/supplychain/dependencyalert.py @@ -8,12 +8,23 @@ @dataclass class DependencyAlert(OctoItem): + number: int + """Number / Identifier""" + state: str + """Alert State""" severity: str + """Alert Severity""" advisory: Advisory + """GitHub Security Advisory""" purl: str + """Package URL""" created_at: Optional[str] = None + """Created Timestamp""" + + manifest: Optional[str] = None + """Manifest""" def __init_post__(self): if not self.created_at: diff --git a/vendor/ghastoolkit/utils/__init__.py b/vendor/ghastoolkit/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/vendor/ghastoolkit/utils/cli.py b/vendor/ghastoolkit/utils/cli.py new file mode 100644 index 0000000..ba1e5e9 --- /dev/null +++ b/vendor/ghastoolkit/utils/cli.py @@ -0,0 +1,129 @@ +import logging +import os +from argparse import ArgumentParser, Namespace +from typing import Optional + +from ghastoolkit.octokit.github import GitHub + + +class CommandLine: + def __init__( + self, + name: Optional[str] = None, + parser: Optional[ArgumentParser] = None, + default_logger: bool = True, + ) -> None: + """Initialize CommandLine.""" + self.parser = parser or ArgumentParser(name or "ghastoolkit") + self.subparser: bool = parser is None + + if not parser: + self.default() + + self.modes = set() + self.modes.add("default") + + self.arguments() + + if not parser: + self.parser.add_argument( + "mode", + const="default", + nargs="?", + default="default", + choices=list(self.modes), + ) + + if default_logger: + self.default_logger() + + def default(self): + """Setup default arguments.""" + self.parser.add_argument( + "--debug", dest="debug", action="store_true", help="Enable Debugging" + ) + self.parser.add_argument( + "--version", dest="version", action="store_true", help="Output version" + ) + self.parser.add_argument( + "--cwd", + "--working-directory", + dest="cwd", + default=os.getcwd(), + help="Working directory", + ) + + github = self.parser.add_argument_group("github") + + github.add_argument( + "-r", + "--github-repository", + dest="repository", + default=os.environ.get("GITHUB_REPOSITORY"), + help="GitHub Repository (default: GITHUB_REPOSITORY)", + ) + github.add_argument( + "--github-instance", + dest="instance", + default=os.environ.get("GITHUB_SERVER_URL", "https://github.com"), + help="GitHub Instance URL (default: GITHUB_SERVER_URL)", + ) + github.add_argument( + "--github-owner", dest="owner", help="GitHub Owner (Org/User)" + ) + github.add_argument( + "--github-enterprise", dest="enterprise", help="GitHub Enterprise" + ) + github.add_argument( + "-t", + "--github-token", + dest="token", + default=os.environ.get("GITHUB_TOKEN"), + help="GitHub API Token (default: GITHUB_TOKEN)", + ) + + github.add_argument( + "--sha", default=os.environ.get("GITHUB_SHA"), help="Commit SHA" + ) + github.add_argument( + "--ref", default=os.environ.get("GITHUB_REF"), help="Commit ref" + ) + + def addModes(self, modes: list[str]): + """Set modes.""" + self.modes.update(modes) + + def arguments(self): + """Set custom arguments.""" + return + + def run(self, arguments: Optional[Namespace] = None): + """Run CLI.""" + raise Exception("Not implemented") + + def default_logger(self): + """Setup default logger.""" + arguments = self.parse_args() + logging.basicConfig( + level=( + logging.DEBUG + if arguments.debug or os.environ.get("DEBUG") + else logging.INFO + ), + format="%(message)s", + ) + + def parse_args(self) -> Namespace: + """Parse arguments.""" + arguments = self.parser.parse_args() + # GitHub Init + GitHub.init( + repository=arguments.repository, + reference=arguments.ref, + owner=arguments.owner, + instance=arguments.instance, + token=arguments.token, + enterprise=arguments.enterprise, + ) + + return arguments diff --git a/vendor/idna/__init__.py b/vendor/idna/__init__.py index a40eeaf..cfdc030 100644 --- a/vendor/idna/__init__.py +++ b/vendor/idna/__init__.py @@ -1,4 +1,3 @@ -from .package_data import __version__ from .core import ( IDNABidiError, IDNAError, @@ -20,8 +19,10 @@ valid_string_length, ) from .intranges import intranges_contain +from .package_data import __version__ __all__ = [ + "__version__", "IDNABidiError", "IDNAError", "InvalidCodepoint", diff --git a/vendor/idna/codec.py b/vendor/idna/codec.py index 1ca9ba6..913abfd 100644 --- a/vendor/idna/codec.py +++ b/vendor/idna/codec.py @@ -1,49 +1,51 @@ -from .core import encode, decode, alabel, ulabel, IDNAError import codecs import re -from typing import Tuple, Optional +from typing import Any, Optional, Tuple -_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') +from .core import IDNAError, alabel, decode, encode, ulabel + +_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") -class Codec(codecs.Codec): - def encode(self, data: str, errors: str = 'strict') -> Tuple[bytes, int]: - if errors != 'strict': - raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) +class Codec(codecs.Codec): + def encode(self, data: str, errors: str = "strict") -> Tuple[bytes, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) if not data: return b"", 0 return encode(data), len(data) - def decode(self, data: bytes, errors: str = 'strict') -> Tuple[str, int]: - if errors != 'strict': - raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + def decode(self, data: bytes, errors: str = "strict") -> Tuple[str, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) if not data: - return '', 0 + return "", 0 return decode(data), len(data) + class IncrementalEncoder(codecs.BufferedIncrementalEncoder): - def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore - if errors != 'strict': - raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[bytes, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) if not data: - return "", 0 + return b"", 0 labels = _unicode_dots_re.split(data) - trailing_dot = '' + trailing_dot = b"" if labels: if not labels[-1]: - trailing_dot = '.' + trailing_dot = b"." del labels[-1] elif not final: # Keep potentially unfinished label until the next call del labels[-1] if labels: - trailing_dot = '.' + trailing_dot = b"." result = [] size = 0 @@ -54,29 +56,33 @@ def _buffer_encode(self, data: str, errors: str, final: bool) -> Tuple[str, int] size += len(label) # Join with U+002E - result_str = '.'.join(result) + trailing_dot # type: ignore + result_bytes = b".".join(result) + trailing_dot size += len(trailing_dot) - return result_str, size + return result_bytes, size + class IncrementalDecoder(codecs.BufferedIncrementalDecoder): - def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int]: # type: ignore - if errors != 'strict': - raise IDNAError('Unsupported error handling \"{}\"'.format(errors)) + def _buffer_decode(self, data: Any, errors: str, final: bool) -> Tuple[str, int]: + if errors != "strict": + raise IDNAError('Unsupported error handling "{}"'.format(errors)) if not data: - return ('', 0) + return ("", 0) + + if not isinstance(data, str): + data = str(data, "ascii") labels = _unicode_dots_re.split(data) - trailing_dot = '' + trailing_dot = "" if labels: if not labels[-1]: - trailing_dot = '.' + trailing_dot = "." del labels[-1] elif not final: # Keep potentially unfinished label until the next call del labels[-1] if labels: - trailing_dot = '.' + trailing_dot = "." result = [] size = 0 @@ -86,7 +92,7 @@ def _buffer_decode(self, data: str, errors: str, final: bool) -> Tuple[str, int] size += 1 size += len(label) - result_str = '.'.join(result) + trailing_dot + result_str = ".".join(result) + trailing_dot size += len(trailing_dot) return (result_str, size) @@ -99,14 +105,18 @@ class StreamReader(Codec, codecs.StreamReader): pass -def getregentry() -> codecs.CodecInfo: - # Compatibility as a search_function for codecs.register() +def search_function(name: str) -> Optional[codecs.CodecInfo]: + if name != "idna2008": + return None return codecs.CodecInfo( - name='idna', - encode=Codec().encode, # type: ignore - decode=Codec().decode, # type: ignore + name=name, + encode=Codec().encode, + decode=Codec().decode, incrementalencoder=IncrementalEncoder, incrementaldecoder=IncrementalDecoder, streamwriter=StreamWriter, streamreader=StreamReader, ) + + +codecs.register(search_function) diff --git a/vendor/idna/compat.py b/vendor/idna/compat.py index 786e6bd..1df9f2a 100644 --- a/vendor/idna/compat.py +++ b/vendor/idna/compat.py @@ -1,13 +1,15 @@ -from .core import * -from .codec import * from typing import Any, Union +from .core import decode, encode + + def ToASCII(label: str) -> bytes: return encode(label) + def ToUnicode(label: Union[bytes, bytearray]) -> str: return decode(label) -def nameprep(s: Any) -> None: - raise NotImplementedError('IDNA 2008 does not utilise nameprep protocol') +def nameprep(s: Any) -> None: + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") diff --git a/vendor/idna/core.py b/vendor/idna/core.py index 4f30037..9115f12 100644 --- a/vendor/idna/core.py +++ b/vendor/idna/core.py @@ -1,31 +1,37 @@ -from . import idnadata import bisect -import unicodedata import re -from typing import Union, Optional +import unicodedata +from typing import Optional, Union + +from . import idnadata from .intranges import intranges_contain _virama_combining_class = 9 -_alabel_prefix = b'xn--' -_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') +_alabel_prefix = b"xn--" +_unicode_dots_re = re.compile("[\u002e\u3002\uff0e\uff61]") + class IDNAError(UnicodeError): - """ Base exception for all IDNA-encoding related problems """ + """Base exception for all IDNA-encoding related problems""" + pass class IDNABidiError(IDNAError): - """ Exception when bidirectional requirements are not satisfied """ + """Exception when bidirectional requirements are not satisfied""" + pass class InvalidCodepoint(IDNAError): - """ Exception when a disallowed or unallocated codepoint is used """ + """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 """ + """Exception when the codepoint is not valid in the context it is used""" + pass @@ -33,17 +39,20 @@ def _combining_class(cp: int) -> int: v = unicodedata.combining(chr(cp)) if v == 0: if not unicodedata.name(chr(cp)): - raise ValueError('Unknown character in unicodedata') + raise ValueError("Unknown character in unicodedata") return v + def _is_script(cp: str, script: str) -> bool: return intranges_contain(ord(cp), idnadata.scripts[script]) + def _punycode(s: str) -> bytes: - return s.encode('punycode') + return s.encode("punycode") + def _unot(s: int) -> str: - return 'U+{:04X}'.format(s) + return "U+{:04X}".format(s) def valid_label_length(label: Union[bytes, str]) -> bool: @@ -61,158 +70,170 @@ def valid_string_length(label: Union[bytes, str], trailing_dot: bool) -> bool: def check_bidi(label: str, check_ltr: bool = False) -> bool: # Bidi rules should only be applied if string contains RTL characters bidi_label = False - for (idx, cp) in enumerate(label, 1): + for idx, cp in enumerate(label, 1): direction = unicodedata.bidirectional(cp) - if direction == '': + if direction == "": # String likely comes from a newer version of Unicode - raise IDNABidiError('Unknown directionality in label {} at position {}'.format(repr(label), idx)) - if direction in ['R', 'AL', 'AN']: + raise IDNABidiError("Unknown directionality in label {} at position {}".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']: + if direction in ["R", "AL"]: rtl = True - elif direction == 'L': + elif direction == "L": rtl = False else: - raise IDNABidiError('First codepoint in label {} must be directionality L, R or AL'.format(repr(label))) + raise IDNABidiError("First codepoint in label {} must be directionality L, R or AL".format(repr(label))) valid_ending = False - number_type = None # type: Optional[str] - for (idx, cp) in enumerate(label, 1): + number_type: Optional[str] = None + 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 {} in a right-to-left label'.format(idx)) + if direction not in [ + "R", + "AL", + "AN", + "EN", + "ES", + "CS", + "ET", + "ON", + "BN", + "NSM", + ]: + raise IDNABidiError("Invalid direction for codepoint at position {} in a right-to-left label".format(idx)) # Bidi rule 3 - if direction in ['R', 'AL', 'EN', 'AN']: + if direction in ["R", "AL", "EN", "AN"]: valid_ending = True - elif direction != 'NSM': + elif direction != "NSM": valid_ending = False # Bidi rule 4 - if direction in ['AN', 'EN']: + 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') + 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 {} in a left-to-right label'.format(idx)) + if direction not in ["L", "EN", "ES", "CS", "ET", "ON", "BN", "NSM"]: + raise IDNABidiError("Invalid direction for codepoint at position {} in a left-to-right label".format(idx)) # Bidi rule 6 - if direction in ['L', 'EN']: + if direction in ["L", "EN"]: valid_ending = True - elif direction != 'NSM': + elif direction != "NSM": valid_ending = False if not valid_ending: - raise IDNABidiError('Label ends with illegal codepoint directionality') + raise IDNABidiError("Label ends with illegal codepoint directionality") return True def check_initial_combiner(label: str) -> bool: - if unicodedata.category(label[0])[0] == 'M': - raise IDNAError('Label begins with an illegal combining character') + if unicodedata.category(label[0])[0] == "M": + raise IDNAError("Label begins with an illegal combining character") return True def check_hyphen_ok(label: str) -> bool: - 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') + 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: str) -> None: - if unicodedata.normalize('NFC', label) != label: - raise IDNAError('Label must be in Normalization Form C') + if unicodedata.normalize("NFC", label) != label: + raise IDNAError("Label must be in Normalization Form C") def valid_contextj(label: str, pos: int) -> bool: cp_value = ord(label[pos]) - if cp_value == 0x200c: - + 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): + for i in range(pos - 1, -1, -1): joining_type = idnadata.joining_types.get(ord(label[i])) - if joining_type == ord('T'): + if joining_type == ord("T"): continue - if joining_type in [ord('L'), ord('D')]: + elif joining_type in [ord("L"), ord("D")]: ok = True break + else: + break if not ok: return False ok = False - for i in range(pos+1, len(label)): + for i in range(pos + 1, len(label)): joining_type = idnadata.joining_types.get(ord(label[i])) - if joining_type == ord('T'): + if joining_type == ord("T"): continue - if joining_type in [ord('R'), ord('D')]: + elif joining_type in [ord("R"), ord("D")]: ok = True break + else: + break return ok - if cp_value == 0x200d: - + 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: str, pos: int, exception: bool = False) -> bool: 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: + 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') + 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: + elif cp_value == 0x05F3 or cp_value == 0x05F4: if pos > 0: - return _is_script(label[pos - 1], 'Hebrew') + return _is_script(label[pos - 1], "Hebrew") return False - elif cp_value == 0x30fb: + elif cp_value == 0x30FB: for cp in label: - if cp == '\u30fb': + if cp == "\u30fb": continue - if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + 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: + if 0x6F0 <= ord(cp) <= 0x06F9: return False return True - elif 0x6f0 <= cp_value <= 0x6f9: + elif 0x6F0 <= cp_value <= 0x6F9: for cp in label: if 0x660 <= ord(cp) <= 0x0669: return False @@ -223,55 +244,58 @@ def valid_contexto(label: str, pos: int, exception: bool = False) -> bool: def check_label(label: Union[str, bytes, bytearray]) -> None: if isinstance(label, (bytes, bytearray)): - label = label.decode('utf-8') + label = label.decode("utf-8") if len(label) == 0: - raise IDNAError('Empty Label') + raise IDNAError("Empty Label") check_nfc(label) check_hyphen_ok(label) check_initial_combiner(label) - for (pos, cp) in enumerate(label): + for pos, cp in enumerate(label): cp_value = ord(cp) - if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + if intranges_contain(cp_value, idnadata.codepoint_classes["PVALID"]): continue - elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + elif intranges_contain(cp_value, idnadata.codepoint_classes["CONTEXTJ"]): try: if not valid_contextj(label, pos): - raise InvalidCodepointContext('Joiner {} not allowed at position {} in {}'.format( - _unot(cp_value), pos+1, repr(label))) + raise InvalidCodepointContext( + "Joiner {} not allowed at position {} in {}".format(_unot(cp_value), pos + 1, repr(label)) + ) except ValueError: - raise IDNAError('Unknown codepoint adjacent to joiner {} at position {} in {}'.format( - _unot(cp_value), pos+1, repr(label))) - elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + raise IDNAError( + "Unknown codepoint adjacent to joiner {} at position {} in {}".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 {} not allowed at position {} in {}'.format(_unot(cp_value), pos+1, repr(label))) + raise InvalidCodepointContext( + "Codepoint {} not allowed at position {} in {}".format(_unot(cp_value), pos + 1, repr(label)) + ) else: - raise InvalidCodepoint('Codepoint {} at position {} of {} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + raise InvalidCodepoint( + "Codepoint {} at position {} of {} not allowed".format(_unot(cp_value), pos + 1, repr(label)) + ) check_bidi(label) def alabel(label: str) -> bytes: try: - label_bytes = label.encode('ascii') + label_bytes = label.encode("ascii") ulabel(label_bytes) if not valid_label_length(label_bytes): - raise IDNAError('Label too long') + raise IDNAError("Label too long") return label_bytes except UnicodeEncodeError: pass - if not label: - raise IDNAError('No Input') - - label = str(label) check_label(label) - label_bytes = _punycode(label) - label_bytes = _alabel_prefix + label_bytes + label_bytes = _alabel_prefix + _punycode(label) if not valid_label_length(label_bytes): - raise IDNAError('Label too long') + raise IDNAError("Label too long") return label_bytes @@ -279,7 +303,7 @@ def alabel(label: str) -> bytes: def ulabel(label: Union[str, bytes, bytearray]) -> str: if not isinstance(label, (bytes, bytearray)): try: - label_bytes = label.encode('ascii') + label_bytes = label.encode("ascii") except UnicodeEncodeError: check_label(label) return label @@ -288,19 +312,19 @@ def ulabel(label: Union[str, bytes, bytearray]) -> str: label_bytes = label_bytes.lower() if label_bytes.startswith(_alabel_prefix): - label_bytes = label_bytes[len(_alabel_prefix):] + label_bytes = label_bytes[len(_alabel_prefix) :] if not label_bytes: - raise IDNAError('Malformed A-label, no Punycode eligible content found') - if label_bytes.decode('ascii')[-1] == '-': - raise IDNAError('A-label must not end with a hyphen') + raise IDNAError("Malformed A-label, no Punycode eligible content found") + if label_bytes.decode("ascii")[-1] == "-": + raise IDNAError("A-label must not end with a hyphen") else: check_label(label_bytes) - return label_bytes.decode('ascii') + return label_bytes.decode("ascii") try: - label = label_bytes.decode('punycode') + label = label_bytes.decode("punycode") except UnicodeError: - raise IDNAError('Invalid A-label') + raise IDNAError("Invalid A-label") check_label(label) return label @@ -308,52 +332,60 @@ def ulabel(label: Union[str, bytes, bytearray]) -> str: def uts46_remap(domain: str, std3_rules: bool = True, transitional: bool = False) -> str: """Re-map the characters in the string according to UTS46 processing.""" from .uts46data import uts46data - output = '' + + output = "" for pos, char in enumerate(domain): code_point = ord(char) try: - uts46row = uts46data[code_point if code_point < 256 else - bisect.bisect_left(uts46data, (code_point, 'Z')) - 1] + uts46row = uts46data[code_point if code_point < 256 else bisect.bisect_left(uts46data, (code_point, "Z")) - 1] status = uts46row[1] - replacement = None # type: Optional[str] + replacement: Optional[str] = None if len(uts46row) == 3: - replacement = uts46row[2] # type: ignore - if (status == 'V' or - (status == 'D' and not transitional) or - (status == '3' and not std3_rules and replacement is None)): + replacement = uts46row[2] + 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)): + 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': + elif status != "I": raise IndexError() except IndexError: raise InvalidCodepoint( - 'Codepoint {} not allowed at position {} in {}'.format( - _unot(code_point), pos + 1, repr(domain))) + "Codepoint {} not allowed at position {} in {}".format(_unot(code_point), pos + 1, repr(domain)) + ) - return unicodedata.normalize('NFC', output) + return unicodedata.normalize("NFC", output) -def encode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False, transitional: bool = False) -> bytes: - if isinstance(s, (bytes, bytearray)): +def encode( + s: Union[str, bytes, bytearray], + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, + transitional: bool = False, +) -> bytes: + if not isinstance(s, str): try: - s = s.decode('ascii') + s = str(s, "ascii") except UnicodeDecodeError: - raise IDNAError('should pass a unicode string to the function rather than a byte string.') + raise IDNAError("should pass a unicode string to the function rather than a byte string.") if uts46: s = uts46_remap(s, std3_rules, transitional) trailing_dot = False result = [] if strict: - labels = s.split('.') + labels = s.split(".") else: labels = _unicode_dots_re.split(s) - if not labels or labels == ['']: - raise IDNAError('Empty domain') - if labels[-1] == '': + if not labels or labels == [""]: + raise IDNAError("Empty domain") + if labels[-1] == "": del labels[-1] trailing_dot = True for label in labels: @@ -361,21 +393,26 @@ def encode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = if s: result.append(s) else: - raise IDNAError('Empty label') + raise IDNAError("Empty label") if trailing_dot: - result.append(b'') - s = b'.'.join(result) + result.append(b"") + s = b".".join(result) if not valid_string_length(s, trailing_dot): - raise IDNAError('Domain too long') + raise IDNAError("Domain too long") return s -def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = False, std3_rules: bool = False) -> str: +def decode( + s: Union[str, bytes, bytearray], + strict: bool = False, + uts46: bool = False, + std3_rules: bool = False, +) -> str: try: - if isinstance(s, (bytes, bytearray)): - s = s.decode('ascii') + if not isinstance(s, str): + s = str(s, "ascii") except UnicodeDecodeError: - raise IDNAError('Invalid ASCII in A-label') + raise IDNAError("Invalid ASCII in A-label") if uts46: s = uts46_remap(s, std3_rules, False) trailing_dot = False @@ -383,9 +420,9 @@ def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = if not strict: labels = _unicode_dots_re.split(s) else: - labels = s.split('.') - if not labels or labels == ['']: - raise IDNAError('Empty domain') + labels = s.split(".") + if not labels or labels == [""]: + raise IDNAError("Empty domain") if not labels[-1]: del labels[-1] trailing_dot = True @@ -394,7 +431,7 @@ def decode(s: Union[str, bytes, bytearray], strict: bool = False, uts46: bool = if s: result.append(s) else: - raise IDNAError('Empty label') + raise IDNAError("Empty label") if trailing_dot: - result.append('') - return '.'.join(result) + result.append("") + return ".".join(result) diff --git a/vendor/idna/idnadata.py b/vendor/idna/idnadata.py index 67db462..4be6004 100644 --- a/vendor/idna/idnadata.py +++ b/vendor/idna/idnadata.py @@ -1,115 +1,290 @@ # This file is automatically generated by tools/idna-data -__version__ = '15.0.0' +__version__ = "15.1.0" scripts = { - 'Greek': ( + "Greek": ( 0x37000000374, 0x37500000378, - 0x37a0000037e, - 0x37f00000380, + 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, + 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, + 0xAB650000AB66, + 0x101400001018F, + 0x101A0000101A1, + 0x1D2000001D246, ), - 'Han': ( - 0x2e8000002e9a, - 0x2e9b00002ef4, - 0x2f0000002fd6, + "Han": ( + 0x2E8000002E9A, + 0x2E9B00002EF4, + 0x2F0000002FD6, 0x300500003006, 0x300700003008, - 0x30210000302a, - 0x30380000303c, - 0x340000004dc0, - 0x4e000000a000, - 0xf9000000fa6e, - 0xfa700000fada, - 0x16fe200016fe4, - 0x16ff000016ff2, - 0x200000002a6e0, - 0x2a7000002b73a, - 0x2b7400002b81e, - 0x2b8200002cea2, - 0x2ceb00002ebe1, - 0x2f8000002fa1e, - 0x300000003134b, - 0x31350000323b0, + 0x30210000302A, + 0x30380000303C, + 0x340000004DC0, + 0x4E000000A000, + 0xF9000000FA6E, + 0xFA700000FADA, + 0x16FE200016FE4, + 0x16FF000016FF2, + 0x200000002A6E0, + 0x2A7000002B73A, + 0x2B7400002B81E, + 0x2B8200002CEA2, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x2F8000002FA1E, + 0x300000003134B, + 0x31350000323B0, ), - 'Hebrew': ( - 0x591000005c8, - 0x5d0000005eb, - 0x5ef000005f5, - 0xfb1d0000fb37, - 0xfb380000fb3d, - 0xfb3e0000fb3f, - 0xfb400000fb42, - 0xfb430000fb45, - 0xfb460000fb50, + "Hebrew": ( + 0x591000005C8, + 0x5D0000005EB, + 0x5EF000005F5, + 0xFB1D0000FB37, + 0xFB380000FB3D, + 0xFB3E0000FB3F, + 0xFB400000FB42, + 0xFB430000FB45, + 0xFB460000FB50, ), - 'Hiragana': ( + "Hiragana": ( 0x304100003097, - 0x309d000030a0, - 0x1b0010001b120, - 0x1b1320001b133, - 0x1b1500001b153, - 0x1f2000001f201, + 0x309D000030A0, + 0x1B0010001B120, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1F2000001F201, ), - 'Katakana': ( - 0x30a1000030fb, - 0x30fd00003100, - 0x31f000003200, - 0x32d0000032ff, + "Katakana": ( + 0x30A1000030FB, + 0x30FD00003100, + 0x31F000003200, + 0x32D0000032FF, 0x330000003358, - 0xff660000ff70, - 0xff710000ff9e, - 0x1aff00001aff4, - 0x1aff50001affc, - 0x1affd0001afff, - 0x1b0000001b001, - 0x1b1200001b123, - 0x1b1550001b156, - 0x1b1640001b168, + 0xFF660000FF70, + 0xFF710000FF9E, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B001, + 0x1B1200001B123, + 0x1B1550001B156, + 0x1B1640001B168, ), } joining_types = { - 0x600: 85, - 0x601: 85, - 0x602: 85, - 0x603: 85, - 0x604: 85, - 0x605: 85, - 0x608: 85, - 0x60b: 85, + 0xAD: 84, + 0x300: 84, + 0x301: 84, + 0x302: 84, + 0x303: 84, + 0x304: 84, + 0x305: 84, + 0x306: 84, + 0x307: 84, + 0x308: 84, + 0x309: 84, + 0x30A: 84, + 0x30B: 84, + 0x30C: 84, + 0x30D: 84, + 0x30E: 84, + 0x30F: 84, + 0x310: 84, + 0x311: 84, + 0x312: 84, + 0x313: 84, + 0x314: 84, + 0x315: 84, + 0x316: 84, + 0x317: 84, + 0x318: 84, + 0x319: 84, + 0x31A: 84, + 0x31B: 84, + 0x31C: 84, + 0x31D: 84, + 0x31E: 84, + 0x31F: 84, + 0x320: 84, + 0x321: 84, + 0x322: 84, + 0x323: 84, + 0x324: 84, + 0x325: 84, + 0x326: 84, + 0x327: 84, + 0x328: 84, + 0x329: 84, + 0x32A: 84, + 0x32B: 84, + 0x32C: 84, + 0x32D: 84, + 0x32E: 84, + 0x32F: 84, + 0x330: 84, + 0x331: 84, + 0x332: 84, + 0x333: 84, + 0x334: 84, + 0x335: 84, + 0x336: 84, + 0x337: 84, + 0x338: 84, + 0x339: 84, + 0x33A: 84, + 0x33B: 84, + 0x33C: 84, + 0x33D: 84, + 0x33E: 84, + 0x33F: 84, + 0x340: 84, + 0x341: 84, + 0x342: 84, + 0x343: 84, + 0x344: 84, + 0x345: 84, + 0x346: 84, + 0x347: 84, + 0x348: 84, + 0x349: 84, + 0x34A: 84, + 0x34B: 84, + 0x34C: 84, + 0x34D: 84, + 0x34E: 84, + 0x34F: 84, + 0x350: 84, + 0x351: 84, + 0x352: 84, + 0x353: 84, + 0x354: 84, + 0x355: 84, + 0x356: 84, + 0x357: 84, + 0x358: 84, + 0x359: 84, + 0x35A: 84, + 0x35B: 84, + 0x35C: 84, + 0x35D: 84, + 0x35E: 84, + 0x35F: 84, + 0x360: 84, + 0x361: 84, + 0x362: 84, + 0x363: 84, + 0x364: 84, + 0x365: 84, + 0x366: 84, + 0x367: 84, + 0x368: 84, + 0x369: 84, + 0x36A: 84, + 0x36B: 84, + 0x36C: 84, + 0x36D: 84, + 0x36E: 84, + 0x36F: 84, + 0x483: 84, + 0x484: 84, + 0x485: 84, + 0x486: 84, + 0x487: 84, + 0x488: 84, + 0x489: 84, + 0x591: 84, + 0x592: 84, + 0x593: 84, + 0x594: 84, + 0x595: 84, + 0x596: 84, + 0x597: 84, + 0x598: 84, + 0x599: 84, + 0x59A: 84, + 0x59B: 84, + 0x59C: 84, + 0x59D: 84, + 0x59E: 84, + 0x59F: 84, + 0x5A0: 84, + 0x5A1: 84, + 0x5A2: 84, + 0x5A3: 84, + 0x5A4: 84, + 0x5A5: 84, + 0x5A6: 84, + 0x5A7: 84, + 0x5A8: 84, + 0x5A9: 84, + 0x5AA: 84, + 0x5AB: 84, + 0x5AC: 84, + 0x5AD: 84, + 0x5AE: 84, + 0x5AF: 84, + 0x5B0: 84, + 0x5B1: 84, + 0x5B2: 84, + 0x5B3: 84, + 0x5B4: 84, + 0x5B5: 84, + 0x5B6: 84, + 0x5B7: 84, + 0x5B8: 84, + 0x5B9: 84, + 0x5BA: 84, + 0x5BB: 84, + 0x5BC: 84, + 0x5BD: 84, + 0x5BF: 84, + 0x5C1: 84, + 0x5C2: 84, + 0x5C4: 84, + 0x5C5: 84, + 0x5C7: 84, + 0x610: 84, + 0x611: 84, + 0x612: 84, + 0x613: 84, + 0x614: 84, + 0x615: 84, + 0x616: 84, + 0x617: 84, + 0x618: 84, + 0x619: 84, + 0x61A: 84, + 0x61C: 84, 0x620: 68, - 0x621: 85, 0x622: 82, 0x623: 82, 0x624: 82, @@ -118,12 +293,12 @@ 0x627: 82, 0x628: 68, 0x629: 82, - 0x62a: 68, - 0x62b: 68, - 0x62c: 68, - 0x62d: 68, - 0x62e: 68, - 0x62f: 82, + 0x62A: 68, + 0x62B: 68, + 0x62C: 68, + 0x62D: 68, + 0x62E: 68, + 0x62F: 82, 0x630: 82, 0x631: 82, 0x632: 82, @@ -134,12 +309,12 @@ 0x637: 68, 0x638: 68, 0x639: 68, - 0x63a: 68, - 0x63b: 68, - 0x63c: 68, - 0x63d: 68, - 0x63e: 68, - 0x63f: 68, + 0x63A: 68, + 0x63B: 68, + 0x63C: 68, + 0x63D: 68, + 0x63E: 68, + 0x63F: 68, 0x640: 67, 0x641: 68, 0x642: 68, @@ -150,24 +325,45 @@ 0x647: 68, 0x648: 82, 0x649: 68, - 0x64a: 68, - 0x66e: 68, - 0x66f: 68, + 0x64A: 68, + 0x64B: 84, + 0x64C: 84, + 0x64D: 84, + 0x64E: 84, + 0x64F: 84, + 0x650: 84, + 0x651: 84, + 0x652: 84, + 0x653: 84, + 0x654: 84, + 0x655: 84, + 0x656: 84, + 0x657: 84, + 0x658: 84, + 0x659: 84, + 0x65A: 84, + 0x65B: 84, + 0x65C: 84, + 0x65D: 84, + 0x65E: 84, + 0x65F: 84, + 0x66E: 68, + 0x66F: 68, + 0x670: 84, 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, + 0x67A: 68, + 0x67B: 68, + 0x67C: 68, + 0x67D: 68, + 0x67E: 68, + 0x67F: 68, 0x680: 68, 0x681: 68, 0x682: 68, @@ -178,12 +374,12 @@ 0x687: 68, 0x688: 82, 0x689: 82, - 0x68a: 82, - 0x68b: 82, - 0x68c: 82, - 0x68d: 82, - 0x68e: 82, - 0x68f: 82, + 0x68A: 82, + 0x68B: 82, + 0x68C: 82, + 0x68D: 82, + 0x68E: 82, + 0x68F: 82, 0x690: 82, 0x691: 82, 0x692: 82, @@ -194,74 +390,93 @@ 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, + 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, + 0x6D6: 84, + 0x6D7: 84, + 0x6D8: 84, + 0x6D9: 84, + 0x6DA: 84, + 0x6DB: 84, + 0x6DC: 84, + 0x6DF: 84, + 0x6E0: 84, + 0x6E1: 84, + 0x6E2: 84, + 0x6E3: 84, + 0x6E4: 84, + 0x6E7: 84, + 0x6E8: 84, + 0x6EA: 84, + 0x6EB: 84, + 0x6EC: 84, + 0x6ED: 84, + 0x6EE: 82, + 0x6EF: 82, + 0x6FA: 68, + 0x6FB: 68, + 0x6FC: 68, + 0x6FF: 68, + 0x70F: 84, 0x710: 82, + 0x711: 84, 0x712: 68, 0x713: 68, 0x714: 68, @@ -270,12 +485,12 @@ 0x717: 82, 0x718: 82, 0x719: 82, - 0x71a: 68, - 0x71b: 68, - 0x71c: 68, - 0x71d: 68, - 0x71e: 82, - 0x71f: 68, + 0x71A: 68, + 0x71B: 68, + 0x71C: 68, + 0x71D: 68, + 0x71E: 82, + 0x71F: 68, 0x720: 68, 0x721: 68, 0x722: 68, @@ -286,15 +501,42 @@ 0x727: 68, 0x728: 82, 0x729: 68, - 0x72a: 82, - 0x72b: 68, - 0x72c: 82, - 0x72d: 68, - 0x72e: 68, - 0x72f: 82, - 0x74d: 82, - 0x74e: 68, - 0x74f: 68, + 0x72A: 82, + 0x72B: 68, + 0x72C: 82, + 0x72D: 68, + 0x72E: 68, + 0x72F: 82, + 0x730: 84, + 0x731: 84, + 0x732: 84, + 0x733: 84, + 0x734: 84, + 0x735: 84, + 0x736: 84, + 0x737: 84, + 0x738: 84, + 0x739: 84, + 0x73A: 84, + 0x73B: 84, + 0x73C: 84, + 0x73D: 84, + 0x73E: 84, + 0x73F: 84, + 0x740: 84, + 0x741: 84, + 0x742: 84, + 0x743: 84, + 0x744: 84, + 0x745: 84, + 0x746: 84, + 0x747: 84, + 0x748: 84, + 0x749: 84, + 0x74A: 84, + 0x74D: 82, + 0x74E: 68, + 0x74F: 68, 0x750: 68, 0x751: 68, 0x752: 68, @@ -305,12 +547,12 @@ 0x757: 68, 0x758: 68, 0x759: 82, - 0x75a: 82, - 0x75b: 82, - 0x75c: 68, - 0x75d: 68, - 0x75e: 68, - 0x75f: 68, + 0x75A: 82, + 0x75B: 82, + 0x75C: 68, + 0x75D: 68, + 0x75E: 68, + 0x75F: 68, 0x760: 68, 0x761: 68, 0x762: 68, @@ -321,12 +563,12 @@ 0x767: 68, 0x768: 68, 0x769: 68, - 0x76a: 68, - 0x76b: 82, - 0x76c: 82, - 0x76d: 68, - 0x76e: 68, - 0x76f: 68, + 0x76A: 68, + 0x76B: 82, + 0x76C: 82, + 0x76D: 68, + 0x76E: 68, + 0x76F: 68, 0x770: 68, 0x771: 82, 0x772: 68, @@ -337,46 +579,88 @@ 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, + 0x77A: 68, + 0x77B: 68, + 0x77C: 68, + 0x77D: 68, + 0x77E: 68, + 0x77F: 68, + 0x7A6: 84, + 0x7A7: 84, + 0x7A8: 84, + 0x7A9: 84, + 0x7AA: 84, + 0x7AB: 84, + 0x7AC: 84, + 0x7AD: 84, + 0x7AE: 84, + 0x7AF: 84, + 0x7B0: 84, + 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, + 0x7EB: 84, + 0x7EC: 84, + 0x7ED: 84, + 0x7EE: 84, + 0x7EF: 84, + 0x7F0: 84, + 0x7F1: 84, + 0x7F2: 84, + 0x7F3: 84, + 0x7FA: 67, + 0x7FD: 84, + 0x816: 84, + 0x817: 84, + 0x818: 84, + 0x819: 84, + 0x81B: 84, + 0x81C: 84, + 0x81D: 84, + 0x81E: 84, + 0x81F: 84, + 0x820: 84, + 0x821: 84, + 0x822: 84, + 0x823: 84, + 0x825: 84, + 0x826: 84, + 0x827: 84, + 0x829: 84, + 0x82A: 84, + 0x82B: 84, + 0x82C: 84, + 0x82D: 84, 0x840: 82, 0x841: 68, 0x842: 68, @@ -387,12 +671,12 @@ 0x847: 82, 0x848: 68, 0x849: 82, - 0x84a: 68, - 0x84b: 68, - 0x84c: 68, - 0x84d: 68, - 0x84e: 68, - 0x84f: 68, + 0x84A: 68, + 0x84B: 68, + 0x84C: 68, + 0x84D: 68, + 0x84E: 68, + 0x84F: 68, 0x850: 68, 0x851: 68, 0x852: 68, @@ -402,17 +686,18 @@ 0x856: 82, 0x857: 82, 0x858: 82, + 0x859: 84, + 0x85A: 84, + 0x85B: 84, 0x860: 68, - 0x861: 85, 0x862: 68, 0x863: 68, 0x864: 68, 0x865: 68, - 0x866: 85, 0x867: 82, 0x868: 68, 0x869: 82, - 0x86a: 82, + 0x86A: 82, 0x870: 82, 0x871: 82, 0x872: 82, @@ -423,12 +708,12 @@ 0x877: 82, 0x878: 82, 0x879: 82, - 0x87a: 82, - 0x87b: 82, - 0x87c: 82, - 0x87d: 82, - 0x87e: 82, - 0x87f: 82, + 0x87A: 82, + 0x87B: 82, + 0x87C: 82, + 0x87D: 82, + 0x87E: 82, + 0x87F: 82, 0x880: 82, 0x881: 82, 0x882: 82, @@ -436,62 +721,411 @@ 0x884: 67, 0x885: 67, 0x886: 68, - 0x887: 85, - 0x888: 85, 0x889: 68, - 0x88a: 68, - 0x88b: 68, - 0x88c: 68, - 0x88d: 68, - 0x88e: 82, - 0x890: 85, - 0x891: 85, - 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, - 0x8b5: 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, - 0x8c8: 68, - 0x8e2: 85, - 0x1806: 85, + 0x88A: 68, + 0x88B: 68, + 0x88C: 68, + 0x88D: 68, + 0x88E: 82, + 0x898: 84, + 0x899: 84, + 0x89A: 84, + 0x89B: 84, + 0x89C: 84, + 0x89D: 84, + 0x89E: 84, + 0x89F: 84, + 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, + 0x8AE: 82, + 0x8AF: 68, + 0x8B0: 68, + 0x8B1: 82, + 0x8B2: 82, + 0x8B3: 68, + 0x8B4: 68, + 0x8B5: 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, + 0x8C8: 68, + 0x8CA: 84, + 0x8CB: 84, + 0x8CC: 84, + 0x8CD: 84, + 0x8CE: 84, + 0x8CF: 84, + 0x8D0: 84, + 0x8D1: 84, + 0x8D2: 84, + 0x8D3: 84, + 0x8D4: 84, + 0x8D5: 84, + 0x8D6: 84, + 0x8D7: 84, + 0x8D8: 84, + 0x8D9: 84, + 0x8DA: 84, + 0x8DB: 84, + 0x8DC: 84, + 0x8DD: 84, + 0x8DE: 84, + 0x8DF: 84, + 0x8E0: 84, + 0x8E1: 84, + 0x8E3: 84, + 0x8E4: 84, + 0x8E5: 84, + 0x8E6: 84, + 0x8E7: 84, + 0x8E8: 84, + 0x8E9: 84, + 0x8EA: 84, + 0x8EB: 84, + 0x8EC: 84, + 0x8ED: 84, + 0x8EE: 84, + 0x8EF: 84, + 0x8F0: 84, + 0x8F1: 84, + 0x8F2: 84, + 0x8F3: 84, + 0x8F4: 84, + 0x8F5: 84, + 0x8F6: 84, + 0x8F7: 84, + 0x8F8: 84, + 0x8F9: 84, + 0x8FA: 84, + 0x8FB: 84, + 0x8FC: 84, + 0x8FD: 84, + 0x8FE: 84, + 0x8FF: 84, + 0x900: 84, + 0x901: 84, + 0x902: 84, + 0x93A: 84, + 0x93C: 84, + 0x941: 84, + 0x942: 84, + 0x943: 84, + 0x944: 84, + 0x945: 84, + 0x946: 84, + 0x947: 84, + 0x948: 84, + 0x94D: 84, + 0x951: 84, + 0x952: 84, + 0x953: 84, + 0x954: 84, + 0x955: 84, + 0x956: 84, + 0x957: 84, + 0x962: 84, + 0x963: 84, + 0x981: 84, + 0x9BC: 84, + 0x9C1: 84, + 0x9C2: 84, + 0x9C3: 84, + 0x9C4: 84, + 0x9CD: 84, + 0x9E2: 84, + 0x9E3: 84, + 0x9FE: 84, + 0xA01: 84, + 0xA02: 84, + 0xA3C: 84, + 0xA41: 84, + 0xA42: 84, + 0xA47: 84, + 0xA48: 84, + 0xA4B: 84, + 0xA4C: 84, + 0xA4D: 84, + 0xA51: 84, + 0xA70: 84, + 0xA71: 84, + 0xA75: 84, + 0xA81: 84, + 0xA82: 84, + 0xABC: 84, + 0xAC1: 84, + 0xAC2: 84, + 0xAC3: 84, + 0xAC4: 84, + 0xAC5: 84, + 0xAC7: 84, + 0xAC8: 84, + 0xACD: 84, + 0xAE2: 84, + 0xAE3: 84, + 0xAFA: 84, + 0xAFB: 84, + 0xAFC: 84, + 0xAFD: 84, + 0xAFE: 84, + 0xAFF: 84, + 0xB01: 84, + 0xB3C: 84, + 0xB3F: 84, + 0xB41: 84, + 0xB42: 84, + 0xB43: 84, + 0xB44: 84, + 0xB4D: 84, + 0xB55: 84, + 0xB56: 84, + 0xB62: 84, + 0xB63: 84, + 0xB82: 84, + 0xBC0: 84, + 0xBCD: 84, + 0xC00: 84, + 0xC04: 84, + 0xC3C: 84, + 0xC3E: 84, + 0xC3F: 84, + 0xC40: 84, + 0xC46: 84, + 0xC47: 84, + 0xC48: 84, + 0xC4A: 84, + 0xC4B: 84, + 0xC4C: 84, + 0xC4D: 84, + 0xC55: 84, + 0xC56: 84, + 0xC62: 84, + 0xC63: 84, + 0xC81: 84, + 0xCBC: 84, + 0xCBF: 84, + 0xCC6: 84, + 0xCCC: 84, + 0xCCD: 84, + 0xCE2: 84, + 0xCE3: 84, + 0xD00: 84, + 0xD01: 84, + 0xD3B: 84, + 0xD3C: 84, + 0xD41: 84, + 0xD42: 84, + 0xD43: 84, + 0xD44: 84, + 0xD4D: 84, + 0xD62: 84, + 0xD63: 84, + 0xD81: 84, + 0xDCA: 84, + 0xDD2: 84, + 0xDD3: 84, + 0xDD4: 84, + 0xDD6: 84, + 0xE31: 84, + 0xE34: 84, + 0xE35: 84, + 0xE36: 84, + 0xE37: 84, + 0xE38: 84, + 0xE39: 84, + 0xE3A: 84, + 0xE47: 84, + 0xE48: 84, + 0xE49: 84, + 0xE4A: 84, + 0xE4B: 84, + 0xE4C: 84, + 0xE4D: 84, + 0xE4E: 84, + 0xEB1: 84, + 0xEB4: 84, + 0xEB5: 84, + 0xEB6: 84, + 0xEB7: 84, + 0xEB8: 84, + 0xEB9: 84, + 0xEBA: 84, + 0xEBB: 84, + 0xEBC: 84, + 0xEC8: 84, + 0xEC9: 84, + 0xECA: 84, + 0xECB: 84, + 0xECC: 84, + 0xECD: 84, + 0xECE: 84, + 0xF18: 84, + 0xF19: 84, + 0xF35: 84, + 0xF37: 84, + 0xF39: 84, + 0xF71: 84, + 0xF72: 84, + 0xF73: 84, + 0xF74: 84, + 0xF75: 84, + 0xF76: 84, + 0xF77: 84, + 0xF78: 84, + 0xF79: 84, + 0xF7A: 84, + 0xF7B: 84, + 0xF7C: 84, + 0xF7D: 84, + 0xF7E: 84, + 0xF80: 84, + 0xF81: 84, + 0xF82: 84, + 0xF83: 84, + 0xF84: 84, + 0xF86: 84, + 0xF87: 84, + 0xF8D: 84, + 0xF8E: 84, + 0xF8F: 84, + 0xF90: 84, + 0xF91: 84, + 0xF92: 84, + 0xF93: 84, + 0xF94: 84, + 0xF95: 84, + 0xF96: 84, + 0xF97: 84, + 0xF99: 84, + 0xF9A: 84, + 0xF9B: 84, + 0xF9C: 84, + 0xF9D: 84, + 0xF9E: 84, + 0xF9F: 84, + 0xFA0: 84, + 0xFA1: 84, + 0xFA2: 84, + 0xFA3: 84, + 0xFA4: 84, + 0xFA5: 84, + 0xFA6: 84, + 0xFA7: 84, + 0xFA8: 84, + 0xFA9: 84, + 0xFAA: 84, + 0xFAB: 84, + 0xFAC: 84, + 0xFAD: 84, + 0xFAE: 84, + 0xFAF: 84, + 0xFB0: 84, + 0xFB1: 84, + 0xFB2: 84, + 0xFB3: 84, + 0xFB4: 84, + 0xFB5: 84, + 0xFB6: 84, + 0xFB7: 84, + 0xFB8: 84, + 0xFB9: 84, + 0xFBA: 84, + 0xFBB: 84, + 0xFBC: 84, + 0xFC6: 84, + 0x102D: 84, + 0x102E: 84, + 0x102F: 84, + 0x1030: 84, + 0x1032: 84, + 0x1033: 84, + 0x1034: 84, + 0x1035: 84, + 0x1036: 84, + 0x1037: 84, + 0x1039: 84, + 0x103A: 84, + 0x103D: 84, + 0x103E: 84, + 0x1058: 84, + 0x1059: 84, + 0x105E: 84, + 0x105F: 84, + 0x1060: 84, + 0x1071: 84, + 0x1072: 84, + 0x1073: 84, + 0x1074: 84, + 0x1082: 84, + 0x1085: 84, + 0x1086: 84, + 0x108D: 84, + 0x109D: 84, + 0x135D: 84, + 0x135E: 84, + 0x135F: 84, + 0x1712: 84, + 0x1713: 84, + 0x1714: 84, + 0x1732: 84, + 0x1733: 84, + 0x1752: 84, + 0x1753: 84, + 0x1772: 84, + 0x1773: 84, + 0x17B4: 84, + 0x17B5: 84, + 0x17B7: 84, + 0x17B8: 84, + 0x17B9: 84, + 0x17BA: 84, + 0x17BB: 84, + 0x17BC: 84, + 0x17BD: 84, + 0x17C6: 84, + 0x17C9: 84, + 0x17CA: 84, + 0x17CB: 84, + 0x17CC: 84, + 0x17CD: 84, + 0x17CE: 84, + 0x17CF: 84, + 0x17D0: 84, + 0x17D1: 84, + 0x17D2: 84, + 0x17D3: 84, + 0x17DD: 84, 0x1807: 68, - 0x180a: 67, - 0x180e: 85, + 0x180A: 67, + 0x180B: 84, + 0x180C: 84, + 0x180D: 84, + 0x180F: 84, 0x1820: 68, 0x1821: 68, 0x1822: 68, @@ -502,12 +1136,12 @@ 0x1827: 68, 0x1828: 68, 0x1829: 68, - 0x182a: 68, - 0x182b: 68, - 0x182c: 68, - 0x182d: 68, - 0x182e: 68, - 0x182f: 68, + 0x182A: 68, + 0x182B: 68, + 0x182C: 68, + 0x182D: 68, + 0x182E: 68, + 0x182F: 68, 0x1830: 68, 0x1831: 68, 0x1832: 68, @@ -518,12 +1152,12 @@ 0x1837: 68, 0x1838: 68, 0x1839: 68, - 0x183a: 68, - 0x183b: 68, - 0x183c: 68, - 0x183d: 68, - 0x183e: 68, - 0x183f: 68, + 0x183A: 68, + 0x183B: 68, + 0x183C: 68, + 0x183D: 68, + 0x183E: 68, + 0x183F: 68, 0x1840: 68, 0x1841: 68, 0x1842: 68, @@ -534,12 +1168,12 @@ 0x1847: 68, 0x1848: 68, 0x1849: 68, - 0x184a: 68, - 0x184b: 68, - 0x184c: 68, - 0x184d: 68, - 0x184e: 68, - 0x184f: 68, + 0x184A: 68, + 0x184B: 68, + 0x184C: 68, + 0x184D: 68, + 0x184E: 68, + 0x184F: 68, 0x1850: 68, 0x1851: 68, 0x1852: 68, @@ -550,12 +1184,12 @@ 0x1857: 68, 0x1858: 68, 0x1859: 68, - 0x185a: 68, - 0x185b: 68, - 0x185c: 68, - 0x185d: 68, - 0x185e: 68, - 0x185f: 68, + 0x185A: 68, + 0x185B: 68, + 0x185C: 68, + 0x185D: 68, + 0x185E: 68, + 0x185F: 68, 0x1860: 68, 0x1861: 68, 0x1862: 68, @@ -566,12 +1200,12 @@ 0x1867: 68, 0x1868: 68, 0x1869: 68, - 0x186a: 68, - 0x186b: 68, - 0x186c: 68, - 0x186d: 68, - 0x186e: 68, - 0x186f: 68, + 0x186A: 68, + 0x186B: 68, + 0x186C: 68, + 0x186D: 68, + 0x186E: 68, + 0x186F: 68, 0x1870: 68, 0x1871: 68, 0x1872: 68, @@ -581,22 +1215,17 @@ 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, + 0x188A: 68, + 0x188B: 68, + 0x188C: 68, + 0x188D: 68, + 0x188E: 68, + 0x188F: 68, 0x1890: 68, 0x1891: 68, 0x1892: 68, @@ -607,1545 +1236,3008 @@ 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, - 0x10f70: 68, - 0x10f71: 68, - 0x10f72: 68, - 0x10f73: 68, - 0x10f74: 82, - 0x10f75: 82, - 0x10f76: 68, - 0x10f77: 68, - 0x10f78: 68, - 0x10f79: 68, - 0x10f7a: 68, - 0x10f7b: 68, - 0x10f7c: 68, - 0x10f7d: 68, - 0x10f7e: 68, - 0x10f7f: 68, - 0x10f80: 68, - 0x10f81: 68, - 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, + 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, + 0x18A9: 84, + 0x18AA: 68, + 0x1920: 84, + 0x1921: 84, + 0x1922: 84, + 0x1927: 84, + 0x1928: 84, + 0x1932: 84, + 0x1939: 84, + 0x193A: 84, + 0x193B: 84, + 0x1A17: 84, + 0x1A18: 84, + 0x1A1B: 84, + 0x1A56: 84, + 0x1A58: 84, + 0x1A59: 84, + 0x1A5A: 84, + 0x1A5B: 84, + 0x1A5C: 84, + 0x1A5D: 84, + 0x1A5E: 84, + 0x1A60: 84, + 0x1A62: 84, + 0x1A65: 84, + 0x1A66: 84, + 0x1A67: 84, + 0x1A68: 84, + 0x1A69: 84, + 0x1A6A: 84, + 0x1A6B: 84, + 0x1A6C: 84, + 0x1A73: 84, + 0x1A74: 84, + 0x1A75: 84, + 0x1A76: 84, + 0x1A77: 84, + 0x1A78: 84, + 0x1A79: 84, + 0x1A7A: 84, + 0x1A7B: 84, + 0x1A7C: 84, + 0x1A7F: 84, + 0x1AB0: 84, + 0x1AB1: 84, + 0x1AB2: 84, + 0x1AB3: 84, + 0x1AB4: 84, + 0x1AB5: 84, + 0x1AB6: 84, + 0x1AB7: 84, + 0x1AB8: 84, + 0x1AB9: 84, + 0x1ABA: 84, + 0x1ABB: 84, + 0x1ABC: 84, + 0x1ABD: 84, + 0x1ABE: 84, + 0x1ABF: 84, + 0x1AC0: 84, + 0x1AC1: 84, + 0x1AC2: 84, + 0x1AC3: 84, + 0x1AC4: 84, + 0x1AC5: 84, + 0x1AC6: 84, + 0x1AC7: 84, + 0x1AC8: 84, + 0x1AC9: 84, + 0x1ACA: 84, + 0x1ACB: 84, + 0x1ACC: 84, + 0x1ACD: 84, + 0x1ACE: 84, + 0x1B00: 84, + 0x1B01: 84, + 0x1B02: 84, + 0x1B03: 84, + 0x1B34: 84, + 0x1B36: 84, + 0x1B37: 84, + 0x1B38: 84, + 0x1B39: 84, + 0x1B3A: 84, + 0x1B3C: 84, + 0x1B42: 84, + 0x1B6B: 84, + 0x1B6C: 84, + 0x1B6D: 84, + 0x1B6E: 84, + 0x1B6F: 84, + 0x1B70: 84, + 0x1B71: 84, + 0x1B72: 84, + 0x1B73: 84, + 0x1B80: 84, + 0x1B81: 84, + 0x1BA2: 84, + 0x1BA3: 84, + 0x1BA4: 84, + 0x1BA5: 84, + 0x1BA8: 84, + 0x1BA9: 84, + 0x1BAB: 84, + 0x1BAC: 84, + 0x1BAD: 84, + 0x1BE6: 84, + 0x1BE8: 84, + 0x1BE9: 84, + 0x1BED: 84, + 0x1BEF: 84, + 0x1BF0: 84, + 0x1BF1: 84, + 0x1C2C: 84, + 0x1C2D: 84, + 0x1C2E: 84, + 0x1C2F: 84, + 0x1C30: 84, + 0x1C31: 84, + 0x1C32: 84, + 0x1C33: 84, + 0x1C36: 84, + 0x1C37: 84, + 0x1CD0: 84, + 0x1CD1: 84, + 0x1CD2: 84, + 0x1CD4: 84, + 0x1CD5: 84, + 0x1CD6: 84, + 0x1CD7: 84, + 0x1CD8: 84, + 0x1CD9: 84, + 0x1CDA: 84, + 0x1CDB: 84, + 0x1CDC: 84, + 0x1CDD: 84, + 0x1CDE: 84, + 0x1CDF: 84, + 0x1CE0: 84, + 0x1CE2: 84, + 0x1CE3: 84, + 0x1CE4: 84, + 0x1CE5: 84, + 0x1CE6: 84, + 0x1CE7: 84, + 0x1CE8: 84, + 0x1CED: 84, + 0x1CF4: 84, + 0x1CF8: 84, + 0x1CF9: 84, + 0x1DC0: 84, + 0x1DC1: 84, + 0x1DC2: 84, + 0x1DC3: 84, + 0x1DC4: 84, + 0x1DC5: 84, + 0x1DC6: 84, + 0x1DC7: 84, + 0x1DC8: 84, + 0x1DC9: 84, + 0x1DCA: 84, + 0x1DCB: 84, + 0x1DCC: 84, + 0x1DCD: 84, + 0x1DCE: 84, + 0x1DCF: 84, + 0x1DD0: 84, + 0x1DD1: 84, + 0x1DD2: 84, + 0x1DD3: 84, + 0x1DD4: 84, + 0x1DD5: 84, + 0x1DD6: 84, + 0x1DD7: 84, + 0x1DD8: 84, + 0x1DD9: 84, + 0x1DDA: 84, + 0x1DDB: 84, + 0x1DDC: 84, + 0x1DDD: 84, + 0x1DDE: 84, + 0x1DDF: 84, + 0x1DE0: 84, + 0x1DE1: 84, + 0x1DE2: 84, + 0x1DE3: 84, + 0x1DE4: 84, + 0x1DE5: 84, + 0x1DE6: 84, + 0x1DE7: 84, + 0x1DE8: 84, + 0x1DE9: 84, + 0x1DEA: 84, + 0x1DEB: 84, + 0x1DEC: 84, + 0x1DED: 84, + 0x1DEE: 84, + 0x1DEF: 84, + 0x1DF0: 84, + 0x1DF1: 84, + 0x1DF2: 84, + 0x1DF3: 84, + 0x1DF4: 84, + 0x1DF5: 84, + 0x1DF6: 84, + 0x1DF7: 84, + 0x1DF8: 84, + 0x1DF9: 84, + 0x1DFA: 84, + 0x1DFB: 84, + 0x1DFC: 84, + 0x1DFD: 84, + 0x1DFE: 84, + 0x1DFF: 84, + 0x200B: 84, + 0x200D: 67, + 0x200E: 84, + 0x200F: 84, + 0x202A: 84, + 0x202B: 84, + 0x202C: 84, + 0x202D: 84, + 0x202E: 84, + 0x2060: 84, + 0x2061: 84, + 0x2062: 84, + 0x2063: 84, + 0x2064: 84, + 0x206A: 84, + 0x206B: 84, + 0x206C: 84, + 0x206D: 84, + 0x206E: 84, + 0x206F: 84, + 0x20D0: 84, + 0x20D1: 84, + 0x20D2: 84, + 0x20D3: 84, + 0x20D4: 84, + 0x20D5: 84, + 0x20D6: 84, + 0x20D7: 84, + 0x20D8: 84, + 0x20D9: 84, + 0x20DA: 84, + 0x20DB: 84, + 0x20DC: 84, + 0x20DD: 84, + 0x20DE: 84, + 0x20DF: 84, + 0x20E0: 84, + 0x20E1: 84, + 0x20E2: 84, + 0x20E3: 84, + 0x20E4: 84, + 0x20E5: 84, + 0x20E6: 84, + 0x20E7: 84, + 0x20E8: 84, + 0x20E9: 84, + 0x20EA: 84, + 0x20EB: 84, + 0x20EC: 84, + 0x20ED: 84, + 0x20EE: 84, + 0x20EF: 84, + 0x20F0: 84, + 0x2CEF: 84, + 0x2CF0: 84, + 0x2CF1: 84, + 0x2D7F: 84, + 0x2DE0: 84, + 0x2DE1: 84, + 0x2DE2: 84, + 0x2DE3: 84, + 0x2DE4: 84, + 0x2DE5: 84, + 0x2DE6: 84, + 0x2DE7: 84, + 0x2DE8: 84, + 0x2DE9: 84, + 0x2DEA: 84, + 0x2DEB: 84, + 0x2DEC: 84, + 0x2DED: 84, + 0x2DEE: 84, + 0x2DEF: 84, + 0x2DF0: 84, + 0x2DF1: 84, + 0x2DF2: 84, + 0x2DF3: 84, + 0x2DF4: 84, + 0x2DF5: 84, + 0x2DF6: 84, + 0x2DF7: 84, + 0x2DF8: 84, + 0x2DF9: 84, + 0x2DFA: 84, + 0x2DFB: 84, + 0x2DFC: 84, + 0x2DFD: 84, + 0x2DFE: 84, + 0x2DFF: 84, + 0x302A: 84, + 0x302B: 84, + 0x302C: 84, + 0x302D: 84, + 0x3099: 84, + 0x309A: 84, + 0xA66F: 84, + 0xA670: 84, + 0xA671: 84, + 0xA672: 84, + 0xA674: 84, + 0xA675: 84, + 0xA676: 84, + 0xA677: 84, + 0xA678: 84, + 0xA679: 84, + 0xA67A: 84, + 0xA67B: 84, + 0xA67C: 84, + 0xA67D: 84, + 0xA69E: 84, + 0xA69F: 84, + 0xA6F0: 84, + 0xA6F1: 84, + 0xA802: 84, + 0xA806: 84, + 0xA80B: 84, + 0xA825: 84, + 0xA826: 84, + 0xA82C: 84, + 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, + 0xA8C4: 84, + 0xA8C5: 84, + 0xA8E0: 84, + 0xA8E1: 84, + 0xA8E2: 84, + 0xA8E3: 84, + 0xA8E4: 84, + 0xA8E5: 84, + 0xA8E6: 84, + 0xA8E7: 84, + 0xA8E8: 84, + 0xA8E9: 84, + 0xA8EA: 84, + 0xA8EB: 84, + 0xA8EC: 84, + 0xA8ED: 84, + 0xA8EE: 84, + 0xA8EF: 84, + 0xA8F0: 84, + 0xA8F1: 84, + 0xA8FF: 84, + 0xA926: 84, + 0xA927: 84, + 0xA928: 84, + 0xA929: 84, + 0xA92A: 84, + 0xA92B: 84, + 0xA92C: 84, + 0xA92D: 84, + 0xA947: 84, + 0xA948: 84, + 0xA949: 84, + 0xA94A: 84, + 0xA94B: 84, + 0xA94C: 84, + 0xA94D: 84, + 0xA94E: 84, + 0xA94F: 84, + 0xA950: 84, + 0xA951: 84, + 0xA980: 84, + 0xA981: 84, + 0xA982: 84, + 0xA9B3: 84, + 0xA9B6: 84, + 0xA9B7: 84, + 0xA9B8: 84, + 0xA9B9: 84, + 0xA9BC: 84, + 0xA9BD: 84, + 0xA9E5: 84, + 0xAA29: 84, + 0xAA2A: 84, + 0xAA2B: 84, + 0xAA2C: 84, + 0xAA2D: 84, + 0xAA2E: 84, + 0xAA31: 84, + 0xAA32: 84, + 0xAA35: 84, + 0xAA36: 84, + 0xAA43: 84, + 0xAA4C: 84, + 0xAA7C: 84, + 0xAAB0: 84, + 0xAAB2: 84, + 0xAAB3: 84, + 0xAAB4: 84, + 0xAAB7: 84, + 0xAAB8: 84, + 0xAABE: 84, + 0xAABF: 84, + 0xAAC1: 84, + 0xAAEC: 84, + 0xAAED: 84, + 0xAAF6: 84, + 0xABE5: 84, + 0xABE8: 84, + 0xABED: 84, + 0xFB1E: 84, + 0xFE00: 84, + 0xFE01: 84, + 0xFE02: 84, + 0xFE03: 84, + 0xFE04: 84, + 0xFE05: 84, + 0xFE06: 84, + 0xFE07: 84, + 0xFE08: 84, + 0xFE09: 84, + 0xFE0A: 84, + 0xFE0B: 84, + 0xFE0C: 84, + 0xFE0D: 84, + 0xFE0E: 84, + 0xFE0F: 84, + 0xFE20: 84, + 0xFE21: 84, + 0xFE22: 84, + 0xFE23: 84, + 0xFE24: 84, + 0xFE25: 84, + 0xFE26: 84, + 0xFE27: 84, + 0xFE28: 84, + 0xFE29: 84, + 0xFE2A: 84, + 0xFE2B: 84, + 0xFE2C: 84, + 0xFE2D: 84, + 0xFE2E: 84, + 0xFE2F: 84, + 0xFEFF: 84, + 0xFFF9: 84, + 0xFFFA: 84, + 0xFFFB: 84, + 0x101FD: 84, + 0x102E0: 84, + 0x10376: 84, + 0x10377: 84, + 0x10378: 84, + 0x10379: 84, + 0x1037A: 84, + 0x10A01: 84, + 0x10A02: 84, + 0x10A03: 84, + 0x10A05: 84, + 0x10A06: 84, + 0x10A0C: 84, + 0x10A0D: 84, + 0x10A0E: 84, + 0x10A0F: 84, + 0x10A38: 84, + 0x10A39: 84, + 0x10A3A: 84, + 0x10A3F: 84, + 0x10AC0: 68, + 0x10AC1: 68, + 0x10AC2: 68, + 0x10AC3: 68, + 0x10AC4: 68, + 0x10AC5: 82, + 0x10AC7: 82, + 0x10AC9: 82, + 0x10ACA: 82, + 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, + 0x10AE4: 82, + 0x10AE5: 84, + 0x10AE6: 84, + 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, + 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, + 0x10D24: 84, + 0x10D25: 84, + 0x10D26: 84, + 0x10D27: 84, + 0x10EAB: 84, + 0x10EAC: 84, + 0x10EFD: 84, + 0x10EFE: 84, + 0x10EFF: 84, + 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, + 0x10F46: 84, + 0x10F47: 84, + 0x10F48: 84, + 0x10F49: 84, + 0x10F4A: 84, + 0x10F4B: 84, + 0x10F4C: 84, + 0x10F4D: 84, + 0x10F4E: 84, + 0x10F4F: 84, + 0x10F50: 84, + 0x10F51: 68, + 0x10F52: 68, + 0x10F53: 68, + 0x10F54: 82, + 0x10F70: 68, + 0x10F71: 68, + 0x10F72: 68, + 0x10F73: 68, + 0x10F74: 82, + 0x10F75: 82, + 0x10F76: 68, + 0x10F77: 68, + 0x10F78: 68, + 0x10F79: 68, + 0x10F7A: 68, + 0x10F7B: 68, + 0x10F7C: 68, + 0x10F7D: 68, + 0x10F7E: 68, + 0x10F7F: 68, + 0x10F80: 68, + 0x10F81: 68, + 0x10F82: 84, + 0x10F83: 84, + 0x10F84: 84, + 0x10F85: 84, + 0x10FB0: 68, + 0x10FB2: 68, + 0x10FB3: 68, + 0x10FB4: 82, + 0x10FB5: 82, + 0x10FB6: 82, + 0x10FB8: 68, + 0x10FB9: 82, + 0x10FBA: 82, + 0x10FBB: 68, + 0x10FBC: 68, + 0x10FBD: 82, + 0x10FBE: 68, + 0x10FBF: 68, + 0x10FC1: 68, + 0x10FC2: 82, + 0x10FC3: 82, + 0x10FC4: 68, + 0x10FC9: 82, + 0x10FCA: 68, + 0x10FCB: 76, + 0x11001: 84, + 0x11038: 84, + 0x11039: 84, + 0x1103A: 84, + 0x1103B: 84, + 0x1103C: 84, + 0x1103D: 84, + 0x1103E: 84, + 0x1103F: 84, + 0x11040: 84, + 0x11041: 84, + 0x11042: 84, + 0x11043: 84, + 0x11044: 84, + 0x11045: 84, + 0x11046: 84, + 0x11070: 84, + 0x11073: 84, + 0x11074: 84, + 0x1107F: 84, + 0x11080: 84, + 0x11081: 84, + 0x110B3: 84, + 0x110B4: 84, + 0x110B5: 84, + 0x110B6: 84, + 0x110B9: 84, + 0x110BA: 84, + 0x110C2: 84, + 0x11100: 84, + 0x11101: 84, + 0x11102: 84, + 0x11127: 84, + 0x11128: 84, + 0x11129: 84, + 0x1112A: 84, + 0x1112B: 84, + 0x1112D: 84, + 0x1112E: 84, + 0x1112F: 84, + 0x11130: 84, + 0x11131: 84, + 0x11132: 84, + 0x11133: 84, + 0x11134: 84, + 0x11173: 84, + 0x11180: 84, + 0x11181: 84, + 0x111B6: 84, + 0x111B7: 84, + 0x111B8: 84, + 0x111B9: 84, + 0x111BA: 84, + 0x111BB: 84, + 0x111BC: 84, + 0x111BD: 84, + 0x111BE: 84, + 0x111C9: 84, + 0x111CA: 84, + 0x111CB: 84, + 0x111CC: 84, + 0x111CF: 84, + 0x1122F: 84, + 0x11230: 84, + 0x11231: 84, + 0x11234: 84, + 0x11236: 84, + 0x11237: 84, + 0x1123E: 84, + 0x11241: 84, + 0x112DF: 84, + 0x112E3: 84, + 0x112E4: 84, + 0x112E5: 84, + 0x112E6: 84, + 0x112E7: 84, + 0x112E8: 84, + 0x112E9: 84, + 0x112EA: 84, + 0x11300: 84, + 0x11301: 84, + 0x1133B: 84, + 0x1133C: 84, + 0x11340: 84, + 0x11366: 84, + 0x11367: 84, + 0x11368: 84, + 0x11369: 84, + 0x1136A: 84, + 0x1136B: 84, + 0x1136C: 84, + 0x11370: 84, + 0x11371: 84, + 0x11372: 84, + 0x11373: 84, + 0x11374: 84, + 0x11438: 84, + 0x11439: 84, + 0x1143A: 84, + 0x1143B: 84, + 0x1143C: 84, + 0x1143D: 84, + 0x1143E: 84, + 0x1143F: 84, + 0x11442: 84, + 0x11443: 84, + 0x11444: 84, + 0x11446: 84, + 0x1145E: 84, + 0x114B3: 84, + 0x114B4: 84, + 0x114B5: 84, + 0x114B6: 84, + 0x114B7: 84, + 0x114B8: 84, + 0x114BA: 84, + 0x114BF: 84, + 0x114C0: 84, + 0x114C2: 84, + 0x114C3: 84, + 0x115B2: 84, + 0x115B3: 84, + 0x115B4: 84, + 0x115B5: 84, + 0x115BC: 84, + 0x115BD: 84, + 0x115BF: 84, + 0x115C0: 84, + 0x115DC: 84, + 0x115DD: 84, + 0x11633: 84, + 0x11634: 84, + 0x11635: 84, + 0x11636: 84, + 0x11637: 84, + 0x11638: 84, + 0x11639: 84, + 0x1163A: 84, + 0x1163D: 84, + 0x1163F: 84, + 0x11640: 84, + 0x116AB: 84, + 0x116AD: 84, + 0x116B0: 84, + 0x116B1: 84, + 0x116B2: 84, + 0x116B3: 84, + 0x116B4: 84, + 0x116B5: 84, + 0x116B7: 84, + 0x1171D: 84, + 0x1171E: 84, + 0x1171F: 84, + 0x11722: 84, + 0x11723: 84, + 0x11724: 84, + 0x11725: 84, + 0x11727: 84, + 0x11728: 84, + 0x11729: 84, + 0x1172A: 84, + 0x1172B: 84, + 0x1182F: 84, + 0x11830: 84, + 0x11831: 84, + 0x11832: 84, + 0x11833: 84, + 0x11834: 84, + 0x11835: 84, + 0x11836: 84, + 0x11837: 84, + 0x11839: 84, + 0x1183A: 84, + 0x1193B: 84, + 0x1193C: 84, + 0x1193E: 84, + 0x11943: 84, + 0x119D4: 84, + 0x119D5: 84, + 0x119D6: 84, + 0x119D7: 84, + 0x119DA: 84, + 0x119DB: 84, + 0x119E0: 84, + 0x11A01: 84, + 0x11A02: 84, + 0x11A03: 84, + 0x11A04: 84, + 0x11A05: 84, + 0x11A06: 84, + 0x11A07: 84, + 0x11A08: 84, + 0x11A09: 84, + 0x11A0A: 84, + 0x11A33: 84, + 0x11A34: 84, + 0x11A35: 84, + 0x11A36: 84, + 0x11A37: 84, + 0x11A38: 84, + 0x11A3B: 84, + 0x11A3C: 84, + 0x11A3D: 84, + 0x11A3E: 84, + 0x11A47: 84, + 0x11A51: 84, + 0x11A52: 84, + 0x11A53: 84, + 0x11A54: 84, + 0x11A55: 84, + 0x11A56: 84, + 0x11A59: 84, + 0x11A5A: 84, + 0x11A5B: 84, + 0x11A8A: 84, + 0x11A8B: 84, + 0x11A8C: 84, + 0x11A8D: 84, + 0x11A8E: 84, + 0x11A8F: 84, + 0x11A90: 84, + 0x11A91: 84, + 0x11A92: 84, + 0x11A93: 84, + 0x11A94: 84, + 0x11A95: 84, + 0x11A96: 84, + 0x11A98: 84, + 0x11A99: 84, + 0x11C30: 84, + 0x11C31: 84, + 0x11C32: 84, + 0x11C33: 84, + 0x11C34: 84, + 0x11C35: 84, + 0x11C36: 84, + 0x11C38: 84, + 0x11C39: 84, + 0x11C3A: 84, + 0x11C3B: 84, + 0x11C3C: 84, + 0x11C3D: 84, + 0x11C3F: 84, + 0x11C92: 84, + 0x11C93: 84, + 0x11C94: 84, + 0x11C95: 84, + 0x11C96: 84, + 0x11C97: 84, + 0x11C98: 84, + 0x11C99: 84, + 0x11C9A: 84, + 0x11C9B: 84, + 0x11C9C: 84, + 0x11C9D: 84, + 0x11C9E: 84, + 0x11C9F: 84, + 0x11CA0: 84, + 0x11CA1: 84, + 0x11CA2: 84, + 0x11CA3: 84, + 0x11CA4: 84, + 0x11CA5: 84, + 0x11CA6: 84, + 0x11CA7: 84, + 0x11CAA: 84, + 0x11CAB: 84, + 0x11CAC: 84, + 0x11CAD: 84, + 0x11CAE: 84, + 0x11CAF: 84, + 0x11CB0: 84, + 0x11CB2: 84, + 0x11CB3: 84, + 0x11CB5: 84, + 0x11CB6: 84, + 0x11D31: 84, + 0x11D32: 84, + 0x11D33: 84, + 0x11D34: 84, + 0x11D35: 84, + 0x11D36: 84, + 0x11D3A: 84, + 0x11D3C: 84, + 0x11D3D: 84, + 0x11D3F: 84, + 0x11D40: 84, + 0x11D41: 84, + 0x11D42: 84, + 0x11D43: 84, + 0x11D44: 84, + 0x11D45: 84, + 0x11D47: 84, + 0x11D90: 84, + 0x11D91: 84, + 0x11D95: 84, + 0x11D97: 84, + 0x11EF3: 84, + 0x11EF4: 84, + 0x11F00: 84, + 0x11F01: 84, + 0x11F36: 84, + 0x11F37: 84, + 0x11F38: 84, + 0x11F39: 84, + 0x11F3A: 84, + 0x11F40: 84, + 0x11F42: 84, + 0x13430: 84, + 0x13431: 84, + 0x13432: 84, + 0x13433: 84, + 0x13434: 84, + 0x13435: 84, + 0x13436: 84, + 0x13437: 84, + 0x13438: 84, + 0x13439: 84, + 0x1343A: 84, + 0x1343B: 84, + 0x1343C: 84, + 0x1343D: 84, + 0x1343E: 84, + 0x1343F: 84, + 0x13440: 84, + 0x13447: 84, + 0x13448: 84, + 0x13449: 84, + 0x1344A: 84, + 0x1344B: 84, + 0x1344C: 84, + 0x1344D: 84, + 0x1344E: 84, + 0x1344F: 84, + 0x13450: 84, + 0x13451: 84, + 0x13452: 84, + 0x13453: 84, + 0x13454: 84, + 0x13455: 84, + 0x16AF0: 84, + 0x16AF1: 84, + 0x16AF2: 84, + 0x16AF3: 84, + 0x16AF4: 84, + 0x16B30: 84, + 0x16B31: 84, + 0x16B32: 84, + 0x16B33: 84, + 0x16B34: 84, + 0x16B35: 84, + 0x16B36: 84, + 0x16F4F: 84, + 0x16F8F: 84, + 0x16F90: 84, + 0x16F91: 84, + 0x16F92: 84, + 0x16FE4: 84, + 0x1BC9D: 84, + 0x1BC9E: 84, + 0x1BCA0: 84, + 0x1BCA1: 84, + 0x1BCA2: 84, + 0x1BCA3: 84, + 0x1CF00: 84, + 0x1CF01: 84, + 0x1CF02: 84, + 0x1CF03: 84, + 0x1CF04: 84, + 0x1CF05: 84, + 0x1CF06: 84, + 0x1CF07: 84, + 0x1CF08: 84, + 0x1CF09: 84, + 0x1CF0A: 84, + 0x1CF0B: 84, + 0x1CF0C: 84, + 0x1CF0D: 84, + 0x1CF0E: 84, + 0x1CF0F: 84, + 0x1CF10: 84, + 0x1CF11: 84, + 0x1CF12: 84, + 0x1CF13: 84, + 0x1CF14: 84, + 0x1CF15: 84, + 0x1CF16: 84, + 0x1CF17: 84, + 0x1CF18: 84, + 0x1CF19: 84, + 0x1CF1A: 84, + 0x1CF1B: 84, + 0x1CF1C: 84, + 0x1CF1D: 84, + 0x1CF1E: 84, + 0x1CF1F: 84, + 0x1CF20: 84, + 0x1CF21: 84, + 0x1CF22: 84, + 0x1CF23: 84, + 0x1CF24: 84, + 0x1CF25: 84, + 0x1CF26: 84, + 0x1CF27: 84, + 0x1CF28: 84, + 0x1CF29: 84, + 0x1CF2A: 84, + 0x1CF2B: 84, + 0x1CF2C: 84, + 0x1CF2D: 84, + 0x1CF30: 84, + 0x1CF31: 84, + 0x1CF32: 84, + 0x1CF33: 84, + 0x1CF34: 84, + 0x1CF35: 84, + 0x1CF36: 84, + 0x1CF37: 84, + 0x1CF38: 84, + 0x1CF39: 84, + 0x1CF3A: 84, + 0x1CF3B: 84, + 0x1CF3C: 84, + 0x1CF3D: 84, + 0x1CF3E: 84, + 0x1CF3F: 84, + 0x1CF40: 84, + 0x1CF41: 84, + 0x1CF42: 84, + 0x1CF43: 84, + 0x1CF44: 84, + 0x1CF45: 84, + 0x1CF46: 84, + 0x1D167: 84, + 0x1D168: 84, + 0x1D169: 84, + 0x1D173: 84, + 0x1D174: 84, + 0x1D175: 84, + 0x1D176: 84, + 0x1D177: 84, + 0x1D178: 84, + 0x1D179: 84, + 0x1D17A: 84, + 0x1D17B: 84, + 0x1D17C: 84, + 0x1D17D: 84, + 0x1D17E: 84, + 0x1D17F: 84, + 0x1D180: 84, + 0x1D181: 84, + 0x1D182: 84, + 0x1D185: 84, + 0x1D186: 84, + 0x1D187: 84, + 0x1D188: 84, + 0x1D189: 84, + 0x1D18A: 84, + 0x1D18B: 84, + 0x1D1AA: 84, + 0x1D1AB: 84, + 0x1D1AC: 84, + 0x1D1AD: 84, + 0x1D242: 84, + 0x1D243: 84, + 0x1D244: 84, + 0x1DA00: 84, + 0x1DA01: 84, + 0x1DA02: 84, + 0x1DA03: 84, + 0x1DA04: 84, + 0x1DA05: 84, + 0x1DA06: 84, + 0x1DA07: 84, + 0x1DA08: 84, + 0x1DA09: 84, + 0x1DA0A: 84, + 0x1DA0B: 84, + 0x1DA0C: 84, + 0x1DA0D: 84, + 0x1DA0E: 84, + 0x1DA0F: 84, + 0x1DA10: 84, + 0x1DA11: 84, + 0x1DA12: 84, + 0x1DA13: 84, + 0x1DA14: 84, + 0x1DA15: 84, + 0x1DA16: 84, + 0x1DA17: 84, + 0x1DA18: 84, + 0x1DA19: 84, + 0x1DA1A: 84, + 0x1DA1B: 84, + 0x1DA1C: 84, + 0x1DA1D: 84, + 0x1DA1E: 84, + 0x1DA1F: 84, + 0x1DA20: 84, + 0x1DA21: 84, + 0x1DA22: 84, + 0x1DA23: 84, + 0x1DA24: 84, + 0x1DA25: 84, + 0x1DA26: 84, + 0x1DA27: 84, + 0x1DA28: 84, + 0x1DA29: 84, + 0x1DA2A: 84, + 0x1DA2B: 84, + 0x1DA2C: 84, + 0x1DA2D: 84, + 0x1DA2E: 84, + 0x1DA2F: 84, + 0x1DA30: 84, + 0x1DA31: 84, + 0x1DA32: 84, + 0x1DA33: 84, + 0x1DA34: 84, + 0x1DA35: 84, + 0x1DA36: 84, + 0x1DA3B: 84, + 0x1DA3C: 84, + 0x1DA3D: 84, + 0x1DA3E: 84, + 0x1DA3F: 84, + 0x1DA40: 84, + 0x1DA41: 84, + 0x1DA42: 84, + 0x1DA43: 84, + 0x1DA44: 84, + 0x1DA45: 84, + 0x1DA46: 84, + 0x1DA47: 84, + 0x1DA48: 84, + 0x1DA49: 84, + 0x1DA4A: 84, + 0x1DA4B: 84, + 0x1DA4C: 84, + 0x1DA4D: 84, + 0x1DA4E: 84, + 0x1DA4F: 84, + 0x1DA50: 84, + 0x1DA51: 84, + 0x1DA52: 84, + 0x1DA53: 84, + 0x1DA54: 84, + 0x1DA55: 84, + 0x1DA56: 84, + 0x1DA57: 84, + 0x1DA58: 84, + 0x1DA59: 84, + 0x1DA5A: 84, + 0x1DA5B: 84, + 0x1DA5C: 84, + 0x1DA5D: 84, + 0x1DA5E: 84, + 0x1DA5F: 84, + 0x1DA60: 84, + 0x1DA61: 84, + 0x1DA62: 84, + 0x1DA63: 84, + 0x1DA64: 84, + 0x1DA65: 84, + 0x1DA66: 84, + 0x1DA67: 84, + 0x1DA68: 84, + 0x1DA69: 84, + 0x1DA6A: 84, + 0x1DA6B: 84, + 0x1DA6C: 84, + 0x1DA75: 84, + 0x1DA84: 84, + 0x1DA9B: 84, + 0x1DA9C: 84, + 0x1DA9D: 84, + 0x1DA9E: 84, + 0x1DA9F: 84, + 0x1DAA1: 84, + 0x1DAA2: 84, + 0x1DAA3: 84, + 0x1DAA4: 84, + 0x1DAA5: 84, + 0x1DAA6: 84, + 0x1DAA7: 84, + 0x1DAA8: 84, + 0x1DAA9: 84, + 0x1DAAA: 84, + 0x1DAAB: 84, + 0x1DAAC: 84, + 0x1DAAD: 84, + 0x1DAAE: 84, + 0x1DAAF: 84, + 0x1E000: 84, + 0x1E001: 84, + 0x1E002: 84, + 0x1E003: 84, + 0x1E004: 84, + 0x1E005: 84, + 0x1E006: 84, + 0x1E008: 84, + 0x1E009: 84, + 0x1E00A: 84, + 0x1E00B: 84, + 0x1E00C: 84, + 0x1E00D: 84, + 0x1E00E: 84, + 0x1E00F: 84, + 0x1E010: 84, + 0x1E011: 84, + 0x1E012: 84, + 0x1E013: 84, + 0x1E014: 84, + 0x1E015: 84, + 0x1E016: 84, + 0x1E017: 84, + 0x1E018: 84, + 0x1E01B: 84, + 0x1E01C: 84, + 0x1E01D: 84, + 0x1E01E: 84, + 0x1E01F: 84, + 0x1E020: 84, + 0x1E021: 84, + 0x1E023: 84, + 0x1E024: 84, + 0x1E026: 84, + 0x1E027: 84, + 0x1E028: 84, + 0x1E029: 84, + 0x1E02A: 84, + 0x1E08F: 84, + 0x1E130: 84, + 0x1E131: 84, + 0x1E132: 84, + 0x1E133: 84, + 0x1E134: 84, + 0x1E135: 84, + 0x1E136: 84, + 0x1E2AE: 84, + 0x1E2EC: 84, + 0x1E2ED: 84, + 0x1E2EE: 84, + 0x1E2EF: 84, + 0x1E4EC: 84, + 0x1E4ED: 84, + 0x1E4EE: 84, + 0x1E4EF: 84, + 0x1E8D0: 84, + 0x1E8D1: 84, + 0x1E8D2: 84, + 0x1E8D3: 84, + 0x1E8D4: 84, + 0x1E8D5: 84, + 0x1E8D6: 84, + 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, + 0x1E944: 84, + 0x1E945: 84, + 0x1E946: 84, + 0x1E947: 84, + 0x1E948: 84, + 0x1E949: 84, + 0x1E94A: 84, + 0x1E94B: 84, + 0xE0001: 84, + 0xE0020: 84, + 0xE0021: 84, + 0xE0022: 84, + 0xE0023: 84, + 0xE0024: 84, + 0xE0025: 84, + 0xE0026: 84, + 0xE0027: 84, + 0xE0028: 84, + 0xE0029: 84, + 0xE002A: 84, + 0xE002B: 84, + 0xE002C: 84, + 0xE002D: 84, + 0xE002E: 84, + 0xE002F: 84, + 0xE0030: 84, + 0xE0031: 84, + 0xE0032: 84, + 0xE0033: 84, + 0xE0034: 84, + 0xE0035: 84, + 0xE0036: 84, + 0xE0037: 84, + 0xE0038: 84, + 0xE0039: 84, + 0xE003A: 84, + 0xE003B: 84, + 0xE003C: 84, + 0xE003D: 84, + 0xE003E: 84, + 0xE003F: 84, + 0xE0040: 84, + 0xE0041: 84, + 0xE0042: 84, + 0xE0043: 84, + 0xE0044: 84, + 0xE0045: 84, + 0xE0046: 84, + 0xE0047: 84, + 0xE0048: 84, + 0xE0049: 84, + 0xE004A: 84, + 0xE004B: 84, + 0xE004C: 84, + 0xE004D: 84, + 0xE004E: 84, + 0xE004F: 84, + 0xE0050: 84, + 0xE0051: 84, + 0xE0052: 84, + 0xE0053: 84, + 0xE0054: 84, + 0xE0055: 84, + 0xE0056: 84, + 0xE0057: 84, + 0xE0058: 84, + 0xE0059: 84, + 0xE005A: 84, + 0xE005B: 84, + 0xE005C: 84, + 0xE005D: 84, + 0xE005E: 84, + 0xE005F: 84, + 0xE0060: 84, + 0xE0061: 84, + 0xE0062: 84, + 0xE0063: 84, + 0xE0064: 84, + 0xE0065: 84, + 0xE0066: 84, + 0xE0067: 84, + 0xE0068: 84, + 0xE0069: 84, + 0xE006A: 84, + 0xE006B: 84, + 0xE006C: 84, + 0xE006D: 84, + 0xE006E: 84, + 0xE006F: 84, + 0xE0070: 84, + 0xE0071: 84, + 0xE0072: 84, + 0xE0073: 84, + 0xE0074: 84, + 0xE0075: 84, + 0xE0076: 84, + 0xE0077: 84, + 0xE0078: 84, + 0xE0079: 84, + 0xE007A: 84, + 0xE007B: 84, + 0xE007C: 84, + 0xE007D: 84, + 0xE007E: 84, + 0xE007F: 84, + 0xE0100: 84, + 0xE0101: 84, + 0xE0102: 84, + 0xE0103: 84, + 0xE0104: 84, + 0xE0105: 84, + 0xE0106: 84, + 0xE0107: 84, + 0xE0108: 84, + 0xE0109: 84, + 0xE010A: 84, + 0xE010B: 84, + 0xE010C: 84, + 0xE010D: 84, + 0xE010E: 84, + 0xE010F: 84, + 0xE0110: 84, + 0xE0111: 84, + 0xE0112: 84, + 0xE0113: 84, + 0xE0114: 84, + 0xE0115: 84, + 0xE0116: 84, + 0xE0117: 84, + 0xE0118: 84, + 0xE0119: 84, + 0xE011A: 84, + 0xE011B: 84, + 0xE011C: 84, + 0xE011D: 84, + 0xE011E: 84, + 0xE011F: 84, + 0xE0120: 84, + 0xE0121: 84, + 0xE0122: 84, + 0xE0123: 84, + 0xE0124: 84, + 0xE0125: 84, + 0xE0126: 84, + 0xE0127: 84, + 0xE0128: 84, + 0xE0129: 84, + 0xE012A: 84, + 0xE012B: 84, + 0xE012C: 84, + 0xE012D: 84, + 0xE012E: 84, + 0xE012F: 84, + 0xE0130: 84, + 0xE0131: 84, + 0xE0132: 84, + 0xE0133: 84, + 0xE0134: 84, + 0xE0135: 84, + 0xE0136: 84, + 0xE0137: 84, + 0xE0138: 84, + 0xE0139: 84, + 0xE013A: 84, + 0xE013B: 84, + 0xE013C: 84, + 0xE013D: 84, + 0xE013E: 84, + 0xE013F: 84, + 0xE0140: 84, + 0xE0141: 84, + 0xE0142: 84, + 0xE0143: 84, + 0xE0144: 84, + 0xE0145: 84, + 0xE0146: 84, + 0xE0147: 84, + 0xE0148: 84, + 0xE0149: 84, + 0xE014A: 84, + 0xE014B: 84, + 0xE014C: 84, + 0xE014D: 84, + 0xE014E: 84, + 0xE014F: 84, + 0xE0150: 84, + 0xE0151: 84, + 0xE0152: 84, + 0xE0153: 84, + 0xE0154: 84, + 0xE0155: 84, + 0xE0156: 84, + 0xE0157: 84, + 0xE0158: 84, + 0xE0159: 84, + 0xE015A: 84, + 0xE015B: 84, + 0xE015C: 84, + 0xE015D: 84, + 0xE015E: 84, + 0xE015F: 84, + 0xE0160: 84, + 0xE0161: 84, + 0xE0162: 84, + 0xE0163: 84, + 0xE0164: 84, + 0xE0165: 84, + 0xE0166: 84, + 0xE0167: 84, + 0xE0168: 84, + 0xE0169: 84, + 0xE016A: 84, + 0xE016B: 84, + 0xE016C: 84, + 0xE016D: 84, + 0xE016E: 84, + 0xE016F: 84, + 0xE0170: 84, + 0xE0171: 84, + 0xE0172: 84, + 0xE0173: 84, + 0xE0174: 84, + 0xE0175: 84, + 0xE0176: 84, + 0xE0177: 84, + 0xE0178: 84, + 0xE0179: 84, + 0xE017A: 84, + 0xE017B: 84, + 0xE017C: 84, + 0xE017D: 84, + 0xE017E: 84, + 0xE017F: 84, + 0xE0180: 84, + 0xE0181: 84, + 0xE0182: 84, + 0xE0183: 84, + 0xE0184: 84, + 0xE0185: 84, + 0xE0186: 84, + 0xE0187: 84, + 0xE0188: 84, + 0xE0189: 84, + 0xE018A: 84, + 0xE018B: 84, + 0xE018C: 84, + 0xE018D: 84, + 0xE018E: 84, + 0xE018F: 84, + 0xE0190: 84, + 0xE0191: 84, + 0xE0192: 84, + 0xE0193: 84, + 0xE0194: 84, + 0xE0195: 84, + 0xE0196: 84, + 0xE0197: 84, + 0xE0198: 84, + 0xE0199: 84, + 0xE019A: 84, + 0xE019B: 84, + 0xE019C: 84, + 0xE019D: 84, + 0xE019E: 84, + 0xE019F: 84, + 0xE01A0: 84, + 0xE01A1: 84, + 0xE01A2: 84, + 0xE01A3: 84, + 0xE01A4: 84, + 0xE01A5: 84, + 0xE01A6: 84, + 0xE01A7: 84, + 0xE01A8: 84, + 0xE01A9: 84, + 0xE01AA: 84, + 0xE01AB: 84, + 0xE01AC: 84, + 0xE01AD: 84, + 0xE01AE: 84, + 0xE01AF: 84, + 0xE01B0: 84, + 0xE01B1: 84, + 0xE01B2: 84, + 0xE01B3: 84, + 0xE01B4: 84, + 0xE01B5: 84, + 0xE01B6: 84, + 0xE01B7: 84, + 0xE01B8: 84, + 0xE01B9: 84, + 0xE01BA: 84, + 0xE01BB: 84, + 0xE01BC: 84, + 0xE01BD: 84, + 0xE01BE: 84, + 0xE01BF: 84, + 0xE01C0: 84, + 0xE01C1: 84, + 0xE01C2: 84, + 0xE01C3: 84, + 0xE01C4: 84, + 0xE01C5: 84, + 0xE01C6: 84, + 0xE01C7: 84, + 0xE01C8: 84, + 0xE01C9: 84, + 0xE01CA: 84, + 0xE01CB: 84, + 0xE01CC: 84, + 0xE01CD: 84, + 0xE01CE: 84, + 0xE01CF: 84, + 0xE01D0: 84, + 0xE01D1: 84, + 0xE01D2: 84, + 0xE01D3: 84, + 0xE01D4: 84, + 0xE01D5: 84, + 0xE01D6: 84, + 0xE01D7: 84, + 0xE01D8: 84, + 0xE01D9: 84, + 0xE01DA: 84, + 0xE01DB: 84, + 0xE01DC: 84, + 0xE01DD: 84, + 0xE01DE: 84, + 0xE01DF: 84, + 0xE01E0: 84, + 0xE01E1: 84, + 0xE01E2: 84, + 0xE01E3: 84, + 0xE01E4: 84, + 0xE01E5: 84, + 0xE01E6: 84, + 0xE01E7: 84, + 0xE01E8: 84, + 0xE01E9: 84, + 0xE01EA: 84, + 0xE01EB: 84, + 0xE01EC: 84, + 0xE01ED: 84, + 0xE01EE: 84, + 0xE01EF: 84, } codepoint_classes = { - 'PVALID': ( - 0x2d0000002e, - 0x300000003a, - 0x610000007b, - 0xdf000000f7, - 0xf800000100, + "PVALID": ( + 0x2D0000002E, + 0x300000003A, + 0x610000007B, + 0xDF000000F7, + 0xF800000100, 0x10100000102, 0x10300000104, 0x10500000106, 0x10700000108, - 0x1090000010a, - 0x10b0000010c, - 0x10d0000010e, - 0x10f00000110, + 0x1090000010A, + 0x10B0000010C, + 0x10D0000010E, + 0x10F00000110, 0x11100000112, 0x11300000114, 0x11500000116, 0x11700000118, - 0x1190000011a, - 0x11b0000011c, - 0x11d0000011e, - 0x11f00000120, + 0x1190000011A, + 0x11B0000011C, + 0x11D0000011E, + 0x11F00000120, 0x12100000122, 0x12300000124, 0x12500000126, 0x12700000128, - 0x1290000012a, - 0x12b0000012c, - 0x12d0000012e, - 0x12f00000130, + 0x1290000012A, + 0x12B0000012C, + 0x12D0000012E, + 0x12F00000130, 0x13100000132, 0x13500000136, 0x13700000139, - 0x13a0000013b, - 0x13c0000013d, - 0x13e0000013f, + 0x13A0000013B, + 0x13C0000013D, + 0x13E0000013F, 0x14200000143, 0x14400000145, 0x14600000147, 0x14800000149, - 0x14b0000014c, - 0x14d0000014e, - 0x14f00000150, + 0x14B0000014C, + 0x14D0000014E, + 0x14F00000150, 0x15100000152, 0x15300000154, 0x15500000156, 0x15700000158, - 0x1590000015a, - 0x15b0000015c, - 0x15d0000015e, - 0x15f00000160, + 0x1590000015A, + 0x15B0000015C, + 0x15D0000015E, + 0x15F00000160, 0x16100000162, 0x16300000164, 0x16500000166, 0x16700000168, - 0x1690000016a, - 0x16b0000016c, - 0x16d0000016e, - 0x16f00000170, + 0x1690000016A, + 0x16B0000016C, + 0x16D0000016E, + 0x16F00000170, 0x17100000172, 0x17300000174, 0x17500000176, 0x17700000178, - 0x17a0000017b, - 0x17c0000017d, - 0x17e0000017f, + 0x17A0000017B, + 0x17C0000017D, + 0x17E0000017F, 0x18000000181, 0x18300000184, 0x18500000186, 0x18800000189, - 0x18c0000018e, + 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, + 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, + 0x2090000020A, + 0x20B0000020C, + 0x20D0000020E, + 0x20F00000210, 0x21100000212, 0x21300000214, 0x21500000216, 0x21700000218, - 0x2190000021a, - 0x21b0000021c, - 0x21d0000021e, - 0x21f00000220, + 0x2190000021A, + 0x21B0000021C, + 0x21D0000021E, + 0x21F00000220, 0x22100000222, 0x22300000224, 0x22500000226, 0x22700000228, - 0x2290000022a, - 0x22b0000022c, - 0x22d0000022e, - 0x22f00000230, + 0x2290000022A, + 0x22B0000022C, + 0x22D0000022E, + 0x22F00000230, 0x23100000232, - 0x2330000023a, - 0x23c0000023d, - 0x23f00000241, + 0x2330000023A, + 0x23C0000023D, + 0x23F00000241, 0x24200000243, 0x24700000248, - 0x2490000024a, - 0x24b0000024c, - 0x24d0000024e, - 0x24f000002b0, - 0x2b9000002c2, - 0x2c6000002d2, - 0x2ec000002ed, - 0x2ee000002ef, + 0x2490000024A, + 0x24B0000024C, + 0x24D0000024E, + 0x24F000002B0, + 0x2B9000002C2, + 0x2C6000002D2, + 0x2EC000002ED, + 0x2EE000002EF, 0x30000000340, 0x34200000343, - 0x3460000034f, + 0x3460000034F, 0x35000000370, 0x37100000372, 0x37300000374, 0x37700000378, - 0x37b0000037e, + 0x37B0000037E, 0x39000000391, - 0x3ac000003cf, - 0x3d7000003d8, - 0x3d9000003da, - 0x3db000003dc, - 0x3dd000003de, - 0x3df000003e0, - 0x3e1000003e2, - 0x3e3000003e4, - 0x3e5000003e6, - 0x3e7000003e8, - 0x3e9000003ea, - 0x3eb000003ec, - 0x3ed000003ee, - 0x3ef000003f0, - 0x3f3000003f4, - 0x3f8000003f9, - 0x3fb000003fd, + 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, + 0x4690000046A, + 0x46B0000046C, + 0x46D0000046E, + 0x46F00000470, 0x47100000472, 0x47300000474, 0x47500000476, 0x47700000478, - 0x4790000047a, - 0x47b0000047c, - 0x47d0000047e, - 0x47f00000480, + 0x4790000047A, + 0x47B0000047C, + 0x47D0000047E, + 0x47F00000480, 0x48100000482, 0x48300000488, - 0x48b0000048c, - 0x48d0000048e, - 0x48f00000490, + 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, + 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, + 0x5090000050A, + 0x50B0000050C, + 0x50D0000050E, + 0x50F00000510, 0x51100000512, 0x51300000514, 0x51500000516, 0x51700000518, - 0x5190000051a, - 0x51b0000051c, - 0x51d0000051e, - 0x51f00000520, + 0x5190000051A, + 0x51B0000051C, + 0x51D0000051E, + 0x51F00000520, 0x52100000522, 0x52300000524, 0x52500000526, 0x52700000528, - 0x5290000052a, - 0x52b0000052c, - 0x52d0000052e, - 0x52f00000530, - 0x5590000055a, + 0x5290000052A, + 0x52B0000052C, + 0x52D0000052E, + 0x52F00000530, + 0x5590000055A, 0x56000000587, 0x58800000589, - 0x591000005be, - 0x5bf000005c0, - 0x5c1000005c3, - 0x5c4000005c6, - 0x5c7000005c8, - 0x5d0000005eb, - 0x5ef000005f3, - 0x6100000061b, + 0x591000005BE, + 0x5BF000005C0, + 0x5C1000005C3, + 0x5C4000005C6, + 0x5C7000005C8, + 0x5D0000005EB, + 0x5EF000005F3, + 0x6100000061B, 0x62000000640, 0x64100000660, - 0x66e00000675, - 0x679000006d4, - 0x6d5000006dd, - 0x6df000006e9, - 0x6ea000006f0, - 0x6fa00000700, - 0x7100000074b, - 0x74d000007b2, - 0x7c0000007f6, - 0x7fd000007fe, - 0x8000000082e, - 0x8400000085c, - 0x8600000086b, + 0x66E00000675, + 0x679000006D4, + 0x6D5000006DD, + 0x6DF000006E9, + 0x6EA000006F0, + 0x6FA00000700, + 0x7100000074B, + 0x74D000007B2, + 0x7C0000007F6, + 0x7FD000007FE, + 0x8000000082E, + 0x8400000085C, + 0x8600000086B, 0x87000000888, - 0x8890000088f, - 0x898000008e2, - 0x8e300000958, + 0x8890000088F, + 0x898000008E2, + 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, - 0xc3c00000c45, - 0xc4600000c49, - 0xc4a00000c4e, - 0xc5500000c57, - 0xc5800000c5b, - 0xc5d00000c5e, - 0xc6000000c64, - 0xc6600000c70, - 0xc8000000c84, - 0xc8500000c8d, - 0xc8e00000c91, - 0xc9200000ca9, - 0xcaa00000cb4, - 0xcb500000cba, - 0xcbc00000cc5, - 0xcc600000cc9, - 0xcca00000cce, - 0xcd500000cd7, - 0xcdd00000cdf, - 0xce000000ce4, - 0xce600000cf0, - 0xcf100000cf4, - 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, - 0xec800000ecf, - 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, + 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, + 0xC3C00000C45, + 0xC4600000C49, + 0xC4A00000C4E, + 0xC5500000C57, + 0xC5800000C5B, + 0xC5D00000C5E, + 0xC6000000C64, + 0xC6600000C70, + 0xC8000000C84, + 0xC8500000C8D, + 0xC8E00000C91, + 0xC9200000CA9, + 0xCAA00000CB4, + 0xCB500000CBA, + 0xCBC00000CC5, + 0xCC600000CC9, + 0xCCA00000CCE, + 0xCD500000CD7, + 0xCDD00000CDF, + 0xCE000000CE4, + 0xCE600000CF0, + 0xCF100000CF4, + 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, + 0xEC800000ECF, + 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, + 0x124A0000124E, 0x125000001257, 0x125800001259, - 0x125a0000125e, + 0x125A0000125E, 0x126000001289, - 0x128a0000128e, - 0x1290000012b1, - 0x12b2000012b6, - 0x12b8000012bf, - 0x12c0000012c1, - 0x12c2000012c6, - 0x12c8000012d7, - 0x12d800001311, + 0x128A0000128E, + 0x1290000012B1, + 0x12B2000012B6, + 0x12B8000012BF, + 0x12C0000012C1, + 0x12C2000012C6, + 0x12C8000012D7, + 0x12D800001311, 0x131200001316, - 0x13180000135b, - 0x135d00001360, + 0x13180000135B, + 0x135D00001360, 0x138000001390, - 0x13a0000013f6, - 0x14010000166d, - 0x166f00001680, - 0x16810000169b, - 0x16a0000016eb, - 0x16f1000016f9, + 0x13A0000013F6, + 0x14010000166D, + 0x166F00001680, + 0x16810000169B, + 0x16A0000016EB, + 0x16F1000016F9, 0x170000001716, - 0x171f00001735, + 0x171F00001735, 0x174000001754, - 0x17600000176d, - 0x176e00001771, + 0x17600000176D, + 0x176E00001771, 0x177200001774, - 0x1780000017b4, - 0x17b6000017d4, - 0x17d7000017d8, - 0x17dc000017de, - 0x17e0000017ea, - 0x18100000181a, + 0x1780000017B4, + 0x17B6000017D4, + 0x17D7000017D8, + 0x17DC000017DE, + 0x17E0000017EA, + 0x18100000181A, 0x182000001879, - 0x1880000018ab, - 0x18b0000018f6, - 0x19000000191f, - 0x19200000192c, - 0x19300000193c, - 0x19460000196e, + 0x1880000018AB, + 0x18B0000018F6, + 0x19000000191F, + 0x19200000192C, + 0x19300000193C, + 0x19460000196E, 0x197000001975, - 0x1980000019ac, - 0x19b0000019ca, - 0x19d0000019da, - 0x1a0000001a1c, - 0x1a2000001a5f, - 0x1a6000001a7d, - 0x1a7f00001a8a, - 0x1a9000001a9a, - 0x1aa700001aa8, - 0x1ab000001abe, - 0x1abf00001acf, - 0x1b0000001b4d, - 0x1b5000001b5a, - 0x1b6b00001b74, - 0x1b8000001bf4, - 0x1c0000001c38, - 0x1c4000001c4a, - 0x1c4d00001c7e, - 0x1cd000001cd3, - 0x1cd400001cfb, - 0x1d0000001d2c, - 0x1d2f00001d30, - 0x1d3b00001d3c, - 0x1d4e00001d4f, - 0x1d6b00001d78, - 0x1d7900001d9b, - 0x1dc000001e00, - 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, + 0x1980000019AC, + 0x19B0000019CA, + 0x19D0000019DA, + 0x1A0000001A1C, + 0x1A2000001A5F, + 0x1A6000001A7D, + 0x1A7F00001A8A, + 0x1A9000001A9A, + 0x1AA700001AA8, + 0x1AB000001ABE, + 0x1ABF00001ACF, + 0x1B0000001B4D, + 0x1B5000001B5A, + 0x1B6B00001B74, + 0x1B8000001BF4, + 0x1C0000001C38, + 0x1C4000001C4A, + 0x1C4D00001C7E, + 0x1CD000001CD3, + 0x1CD400001CFB, + 0x1D0000001D2C, + 0x1D2F00001D30, + 0x1D3B00001D3C, + 0x1D4E00001D4F, + 0x1D6B00001D78, + 0x1D7900001D9B, + 0x1DC000001E00, + 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, - 0x2c3000002c60, - 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, + 0x2C3000002C60, + 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, + 0x302A0000302E, + 0x303C0000303D, 0x304100003097, - 0x30990000309b, - 0x309d0000309f, - 0x30a1000030fb, - 0x30fc000030ff, + 0x30990000309B, + 0x309D0000309F, + 0x30A1000030FB, + 0x30FC000030FF, 0x310500003130, - 0x31a0000031c0, - 0x31f000003200, - 0x340000004dc0, - 0x4e000000a48d, - 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, - 0xa7c10000a7c2, - 0xa7c30000a7c4, - 0xa7c80000a7c9, - 0xa7ca0000a7cb, - 0xa7d10000a7d2, - 0xa7d30000a7d4, - 0xa7d50000a7d6, - 0xa7d70000a7d8, - 0xa7d90000a7da, - 0xa7f20000a7f5, - 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, - 0xab600000ab69, - 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, + 0x31A0000031C0, + 0x31F000003200, + 0x340000004DC0, + 0x4E000000A48D, + 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, + 0xA7C10000A7C2, + 0xA7C30000A7C4, + 0xA7C80000A7C9, + 0xA7CA0000A7CB, + 0xA7D10000A7D2, + 0xA7D30000A7D4, + 0xA7D50000A7D6, + 0xA7D70000A7D8, + 0xA7D90000A7DA, + 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, + 0xAB600000AB69, + 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, + 0x1032D00010341, + 0x103420001034A, + 0x103500001037B, + 0x103800001039E, + 0x103A0000103C4, + 0x103C8000103D0, + 0x104280001049E, + 0x104A0000104AA, + 0x104D8000104FC, 0x1050000010528, 0x1053000010564, - 0x10597000105a2, - 0x105a3000105b2, - 0x105b3000105ba, - 0x105bb000105bd, + 0x10597000105A2, + 0x105A3000105B2, + 0x105B3000105BA, + 0x105BB000105BD, 0x1060000010737, 0x1074000010756, 0x1076000010768, - 0x1078000010786, - 0x10787000107b1, - 0x107b2000107bb, + 0x1078000010781, 0x1080000010806, 0x1080800010809, - 0x1080a00010836, + 0x1080A00010836, 0x1083700010839, - 0x1083c0001083d, - 0x1083f00010856, + 0x1083C0001083D, + 0x1083F00010856, 0x1086000010877, - 0x108800001089f, - 0x108e0000108f3, - 0x108f4000108f6, + 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, - 0x10efd00010f1d, - 0x10f2700010f28, - 0x10f3000010f51, - 0x10f7000010f86, - 0x10fb000010fc5, - 0x10fe000010ff7, + 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, + 0x10EFD00010F1D, + 0x10F2700010F28, + 0x10F3000010F51, + 0x10F7000010F86, + 0x10FB000010FC5, + 0x10FE000010FF7, 0x1100000011047, 0x1106600011076, - 0x1107f000110bb, - 0x110c2000110c3, - 0x110d0000110e9, - 0x110f0000110fa, + 0x1107F000110BB, + 0x110C2000110C3, + 0x110D0000110E9, + 0x110F0000110FA, 0x1110000011135, 0x1113600011140, 0x1114400011148, 0x1115000011174, 0x1117600011177, - 0x11180000111c5, - 0x111c9000111cd, - 0x111ce000111db, - 0x111dc000111dd, + 0x11180000111C5, + 0x111C9000111CD, + 0x111CE000111DB, + 0x111DC000111DD, 0x1120000011212, 0x1121300011238, - 0x1123e00011242, + 0x1123E00011242, 0x1128000011287, 0x1128800011289, - 0x1128a0001128e, - 0x1128f0001129e, - 0x1129f000112a9, - 0x112b0000112eb, - 0x112f0000112fa, + 0x1128A0001128E, + 0x1128F0001129E, + 0x1129F000112A9, + 0x112B0000112EB, + 0x112F0000112FA, 0x1130000011304, - 0x113050001130d, - 0x1130f00011311, + 0x113050001130D, + 0x1130F00011311, 0x1131300011329, - 0x1132a00011331, + 0x1132A00011331, 0x1133200011334, - 0x113350001133a, - 0x1133b00011345, + 0x113350001133A, + 0x1133B00011345, 0x1134700011349, - 0x1134b0001134e, + 0x1134B0001134E, 0x1135000011351, 0x1135700011358, - 0x1135d00011364, - 0x113660001136d, + 0x1135D00011364, + 0x113660001136D, 0x1137000011375, - 0x114000001144b, - 0x114500001145a, - 0x1145e00011462, - 0x11480000114c6, - 0x114c7000114c8, - 0x114d0000114da, - 0x11580000115b6, - 0x115b8000115c1, - 0x115d8000115de, + 0x114000001144B, + 0x114500001145A, + 0x1145E00011462, + 0x11480000114C6, + 0x114C7000114C8, + 0x114D0000114DA, + 0x11580000115B6, + 0x115B8000115C1, + 0x115D8000115DE, 0x1160000011641, 0x1164400011645, - 0x116500001165a, - 0x11680000116b9, - 0x116c0000116ca, - 0x117000001171b, - 0x1171d0001172c, - 0x117300001173a, + 0x116500001165A, + 0x11680000116B9, + 0x116C0000116CA, + 0x117000001171B, + 0x1171D0001172C, + 0x117300001173A, 0x1174000011747, - 0x118000001183b, - 0x118c0000118ea, - 0x118ff00011907, - 0x119090001190a, - 0x1190c00011914, + 0x118000001183B, + 0x118C0000118EA, + 0x118FF00011907, + 0x119090001190A, + 0x1190C00011914, 0x1191500011917, 0x1191800011936, 0x1193700011939, - 0x1193b00011944, - 0x119500001195a, - 0x119a0000119a8, - 0x119aa000119d8, - 0x119da000119e2, - 0x119e3000119e5, - 0x11a0000011a3f, - 0x11a4700011a48, - 0x11a5000011a9a, - 0x11a9d00011a9e, - 0x11ab000011af9, - 0x11c0000011c09, - 0x11c0a00011c37, - 0x11c3800011c41, - 0x11c5000011c5a, - 0x11c7200011c90, - 0x11c9200011ca8, - 0x11ca900011cb7, - 0x11d0000011d07, - 0x11d0800011d0a, - 0x11d0b00011d37, - 0x11d3a00011d3b, - 0x11d3c00011d3e, - 0x11d3f00011d48, - 0x11d5000011d5a, - 0x11d6000011d66, - 0x11d6700011d69, - 0x11d6a00011d8f, - 0x11d9000011d92, - 0x11d9300011d99, - 0x11da000011daa, - 0x11ee000011ef7, - 0x11f0000011f11, - 0x11f1200011f3b, - 0x11f3e00011f43, - 0x11f5000011f5a, - 0x11fb000011fb1, - 0x120000001239a, + 0x1193B00011944, + 0x119500001195A, + 0x119A0000119A8, + 0x119AA000119D8, + 0x119DA000119E2, + 0x119E3000119E5, + 0x11A0000011A3F, + 0x11A4700011A48, + 0x11A5000011A9A, + 0x11A9D00011A9E, + 0x11AB000011AF9, + 0x11C0000011C09, + 0x11C0A00011C37, + 0x11C3800011C41, + 0x11C5000011C5A, + 0x11C7200011C90, + 0x11C9200011CA8, + 0x11CA900011CB7, + 0x11D0000011D07, + 0x11D0800011D0A, + 0x11D0B00011D37, + 0x11D3A00011D3B, + 0x11D3C00011D3E, + 0x11D3F00011D48, + 0x11D5000011D5A, + 0x11D6000011D66, + 0x11D6700011D69, + 0x11D6A00011D8F, + 0x11D9000011D92, + 0x11D9300011D99, + 0x11DA000011DAA, + 0x11EE000011EF7, + 0x11F0000011F11, + 0x11F1200011F3B, + 0x11F3E00011F43, + 0x11F5000011F5A, + 0x11FB000011FB1, + 0x120000001239A, 0x1248000012544, - 0x12f9000012ff1, + 0x12F9000012FF1, 0x1300000013430, 0x1344000013456, 0x1440000014647, - 0x1680000016a39, - 0x16a4000016a5f, - 0x16a6000016a6a, - 0x16a7000016abf, - 0x16ac000016aca, - 0x16ad000016aee, - 0x16af000016af5, - 0x16b0000016b37, - 0x16b4000016b44, - 0x16b5000016b5a, - 0x16b6300016b78, - 0x16b7d00016b90, - 0x16e6000016e80, - 0x16f0000016f4b, - 0x16f4f00016f88, - 0x16f8f00016fa0, - 0x16fe000016fe2, - 0x16fe300016fe5, - 0x16ff000016ff2, - 0x17000000187f8, - 0x1880000018cd6, - 0x18d0000018d09, - 0x1aff00001aff4, - 0x1aff50001affc, - 0x1affd0001afff, - 0x1b0000001b123, - 0x1b1320001b133, - 0x1b1500001b153, - 0x1b1550001b156, - 0x1b1640001b168, - 0x1b1700001b2fc, - 0x1bc000001bc6b, - 0x1bc700001bc7d, - 0x1bc800001bc89, - 0x1bc900001bc9a, - 0x1bc9d0001bc9f, - 0x1cf000001cf2e, - 0x1cf300001cf47, - 0x1da000001da37, - 0x1da3b0001da6d, - 0x1da750001da76, - 0x1da840001da85, - 0x1da9b0001daa0, - 0x1daa10001dab0, - 0x1df000001df1f, - 0x1df250001df2b, - 0x1e0000001e007, - 0x1e0080001e019, - 0x1e01b0001e022, - 0x1e0230001e025, - 0x1e0260001e02b, - 0x1e0300001e06e, - 0x1e08f0001e090, - 0x1e1000001e12d, - 0x1e1300001e13e, - 0x1e1400001e14a, - 0x1e14e0001e14f, - 0x1e2900001e2af, - 0x1e2c00001e2fa, - 0x1e4d00001e4fa, - 0x1e7e00001e7e7, - 0x1e7e80001e7ec, - 0x1e7ed0001e7ef, - 0x1e7f00001e7ff, - 0x1e8000001e8c5, - 0x1e8d00001e8d7, - 0x1e9220001e94c, - 0x1e9500001e95a, - 0x200000002a6e0, - 0x2a7000002b73a, - 0x2b7400002b81e, - 0x2b8200002cea2, - 0x2ceb00002ebe1, - 0x300000003134b, - 0x31350000323b0, + 0x1680000016A39, + 0x16A4000016A5F, + 0x16A6000016A6A, + 0x16A7000016ABF, + 0x16AC000016ACA, + 0x16AD000016AEE, + 0x16AF000016AF5, + 0x16B0000016B37, + 0x16B4000016B44, + 0x16B5000016B5A, + 0x16B6300016B78, + 0x16B7D00016B90, + 0x16E6000016E80, + 0x16F0000016F4B, + 0x16F4F00016F88, + 0x16F8F00016FA0, + 0x16FE000016FE2, + 0x16FE300016FE5, + 0x16FF000016FF2, + 0x17000000187F8, + 0x1880000018CD6, + 0x18D0000018D09, + 0x1AFF00001AFF4, + 0x1AFF50001AFFC, + 0x1AFFD0001AFFF, + 0x1B0000001B123, + 0x1B1320001B133, + 0x1B1500001B153, + 0x1B1550001B156, + 0x1B1640001B168, + 0x1B1700001B2FC, + 0x1BC000001BC6B, + 0x1BC700001BC7D, + 0x1BC800001BC89, + 0x1BC900001BC9A, + 0x1BC9D0001BC9F, + 0x1CF000001CF2E, + 0x1CF300001CF47, + 0x1DA000001DA37, + 0x1DA3B0001DA6D, + 0x1DA750001DA76, + 0x1DA840001DA85, + 0x1DA9B0001DAA0, + 0x1DAA10001DAB0, + 0x1DF000001DF1F, + 0x1DF250001DF2B, + 0x1E0000001E007, + 0x1E0080001E019, + 0x1E01B0001E022, + 0x1E0230001E025, + 0x1E0260001E02B, + 0x1E08F0001E090, + 0x1E1000001E12D, + 0x1E1300001E13E, + 0x1E1400001E14A, + 0x1E14E0001E14F, + 0x1E2900001E2AF, + 0x1E2C00001E2FA, + 0x1E4D00001E4FA, + 0x1E7E00001E7E7, + 0x1E7E80001E7EC, + 0x1E7ED0001E7EF, + 0x1E7F00001E7FF, + 0x1E8000001E8C5, + 0x1E8D00001E8D7, + 0x1E9220001E94C, + 0x1E9500001E95A, + 0x200000002A6E0, + 0x2A7000002B73A, + 0x2B7400002B81E, + 0x2B8200002CEA2, + 0x2CEB00002EBE1, + 0x2EBF00002EE5E, + 0x300000003134B, + 0x31350000323B0, ), - 'CONTEXTJ': ( - 0x200c0000200e, - ), - 'CONTEXTO': ( - 0xb7000000b8, + "CONTEXTJ": (0x200C0000200E,), + "CONTEXTO": ( + 0xB7000000B8, 0x37500000376, - 0x5f3000005f5, - 0x6600000066a, - 0x6f0000006fa, - 0x30fb000030fc, + 0x5F3000005F5, + 0x6600000066A, + 0x6F0000006FA, + 0x30FB000030FC, ), } diff --git a/vendor/idna/intranges.py b/vendor/idna/intranges.py index 6a43b04..7bfaa8d 100644 --- a/vendor/idna/intranges.py +++ b/vendor/idna/intranges.py @@ -8,6 +8,7 @@ import bisect from typing import List, Tuple + def intranges_from_list(list_: List[int]) -> Tuple[int, ...]: """Represent a list of integers as a sequence of ranges: ((start_0, end_0), (start_1, end_1), ...), such that the original @@ -20,18 +21,20 @@ def intranges_from_list(list_: List[int]) -> Tuple[int, ...]: 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: + 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] + 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: int, end: int) -> int: return (start << 32) | end + def _decode_range(r: int) -> Tuple[int, int]: return (r >> 32), (r & ((1 << 32) - 1)) @@ -43,7 +46,7 @@ def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool: # we could be immediately ahead of a tuple (start, end) # with start < int_ <= end if pos > 0: - left, right = _decode_range(ranges[pos-1]) + left, right = _decode_range(ranges[pos - 1]) if left <= int_ < right: return True # or we could be immediately behind a tuple (int_, end) diff --git a/vendor/idna/package_data.py b/vendor/idna/package_data.py index 8501893..514ff7e 100644 --- a/vendor/idna/package_data.py +++ b/vendor/idna/package_data.py @@ -1,2 +1 @@ -__version__ = '3.4' - +__version__ = "3.10" diff --git a/vendor/idna/uts46data.py b/vendor/idna/uts46data.py index 186796c..eb89432 100644 --- a/vendor/idna/uts46data.py +++ b/vendor/idna/uts46data.py @@ -3,8517 +3,8598 @@ from typing import List, Tuple, Union - """IDNA Mapping Table from UTS46.""" -__version__ = '15.0.0' +__version__ = "15.1.0" + + def _seg_0() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: 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', 'a'), - (0x42, 'M', 'b'), - (0x43, 'M', 'c'), - (0x44, 'M', 'd'), - (0x45, 'M', 'e'), - (0x46, 'M', 'f'), - (0x47, 'M', 'g'), - (0x48, 'M', 'h'), - (0x49, 'M', 'i'), - (0x4A, 'M', 'j'), - (0x4B, 'M', 'k'), - (0x4C, 'M', 'l'), - (0x4D, 'M', 'm'), - (0x4E, 'M', 'n'), - (0x4F, 'M', 'o'), - (0x50, 'M', 'p'), - (0x51, 'M', 'q'), - (0x52, 'M', 'r'), - (0x53, 'M', 's'), - (0x54, 'M', 't'), - (0x55, 'M', 'u'), - (0x56, 'M', 'v'), - (0x57, 'M', 'w'), - (0x58, 'M', 'x'), - (0x59, 'M', 'y'), - (0x5A, 'M', 'z'), - (0x5B, '3'), - (0x5C, '3'), - (0x5D, '3'), - (0x5E, '3'), - (0x5F, '3'), - (0x60, '3'), - (0x61, 'V'), - (0x62, 'V'), - (0x63, 'V'), + (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", "a"), + (0x42, "M", "b"), + (0x43, "M", "c"), + (0x44, "M", "d"), + (0x45, "M", "e"), + (0x46, "M", "f"), + (0x47, "M", "g"), + (0x48, "M", "h"), + (0x49, "M", "i"), + (0x4A, "M", "j"), + (0x4B, "M", "k"), + (0x4C, "M", "l"), + (0x4D, "M", "m"), + (0x4E, "M", "n"), + (0x4F, "M", "o"), + (0x50, "M", "p"), + (0x51, "M", "q"), + (0x52, "M", "r"), + (0x53, "M", "s"), + (0x54, "M", "t"), + (0x55, "M", "u"), + (0x56, "M", "v"), + (0x57, "M", "w"), + (0x58, "M", "x"), + (0x59, "M", "y"), + (0x5A, "M", "z"), + (0x5B, "3"), + (0x5C, "3"), + (0x5D, "3"), + (0x5E, "3"), + (0x5F, "3"), + (0x60, "3"), + (0x61, "V"), + (0x62, "V"), + (0x63, "V"), ] + def _seg_1() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: 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', ' '), - (0xA1, 'V'), - (0xA2, 'V'), - (0xA3, 'V'), - (0xA4, 'V'), - (0xA5, 'V'), - (0xA6, 'V'), - (0xA7, 'V'), - (0xA8, '3', ' ̈'), - (0xA9, 'V'), - (0xAA, 'M', 'a'), - (0xAB, 'V'), - (0xAC, 'V'), - (0xAD, 'I'), - (0xAE, 'V'), - (0xAF, '3', ' Ģ„'), - (0xB0, 'V'), - (0xB1, 'V'), - (0xB2, 'M', '2'), - (0xB3, 'M', '3'), - (0xB4, '3', ' ́'), - (0xB5, 'M', 'μ'), - (0xB6, 'V'), - (0xB7, 'V'), - (0xB8, '3', ' ̧'), - (0xB9, 'M', '1'), - (0xBA, 'M', 'o'), - (0xBB, 'V'), - (0xBC, 'M', '1⁄4'), - (0xBD, 'M', '1⁄2'), - (0xBE, 'M', '3⁄4'), - (0xBF, 'V'), - (0xC0, 'M', 'Ć '), - (0xC1, 'M', 'Ć”'), - (0xC2, 'M', 'Ć¢'), - (0xC3, 'M', 'Ć£'), - (0xC4, 'M', 'Ƥ'), - (0xC5, 'M', 'Ć„'), - (0xC6, 'M', 'Ʀ'), - (0xC7, 'M', 'Ƨ'), + (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", " "), + (0xA1, "V"), + (0xA2, "V"), + (0xA3, "V"), + (0xA4, "V"), + (0xA5, "V"), + (0xA6, "V"), + (0xA7, "V"), + (0xA8, "3", " ̈"), + (0xA9, "V"), + (0xAA, "M", "a"), + (0xAB, "V"), + (0xAC, "V"), + (0xAD, "I"), + (0xAE, "V"), + (0xAF, "3", " Ģ„"), + (0xB0, "V"), + (0xB1, "V"), + (0xB2, "M", "2"), + (0xB3, "M", "3"), + (0xB4, "3", " ́"), + (0xB5, "M", "μ"), + (0xB6, "V"), + (0xB7, "V"), + (0xB8, "3", " ̧"), + (0xB9, "M", "1"), + (0xBA, "M", "o"), + (0xBB, "V"), + (0xBC, "M", "1⁄4"), + (0xBD, "M", "1⁄2"), + (0xBE, "M", "3⁄4"), + (0xBF, "V"), + (0xC0, "M", "Ć "), + (0xC1, "M", "Ć”"), + (0xC2, "M", "Ć¢"), + (0xC3, "M", "Ć£"), + (0xC4, "M", "Ƥ"), + (0xC5, "M", "Ć„"), + (0xC6, "M", "Ʀ"), + (0xC7, "M", "Ƨ"), ] + def _seg_2() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xC8, 'M', 'ĆØ'), - (0xC9, 'M', 'Ć©'), - (0xCA, 'M', 'ĆŖ'), - (0xCB, 'M', 'Ć«'), - (0xCC, 'M', 'Ƭ'), - (0xCD, 'M', 'Ć­'), - (0xCE, 'M', 'Ć®'), - (0xCF, 'M', 'ĆÆ'), - (0xD0, 'M', 'ư'), - (0xD1, 'M', 'Ʊ'), - (0xD2, 'M', 'ò'), - (0xD3, 'M', 'ó'), - (0xD4, 'M', 'Ć“'), - (0xD5, 'M', 'Ƶ'), - (0xD6, 'M', 'ƶ'), - (0xD7, 'V'), - (0xD8, 'M', 'Ćø'), - (0xD9, 'M', 'ù'), - (0xDA, 'M', 'Ćŗ'), - (0xDB, 'M', 'Ć»'), - (0xDC, 'M', 'ü'), - (0xDD, 'M', 'ý'), - (0xDE, 'M', 'þ'), - (0xDF, 'D', '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', 'ā'), - (0x101, 'V'), - (0x102, 'M', 'ă'), - (0x103, 'V'), - (0x104, 'M', 'ą'), - (0x105, 'V'), - (0x106, 'M', 'ć'), - (0x107, 'V'), - (0x108, 'M', 'ĉ'), - (0x109, 'V'), - (0x10A, 'M', 'ċ'), - (0x10B, 'V'), - (0x10C, 'M', 'č'), - (0x10D, 'V'), - (0x10E, 'M', 'ď'), - (0x10F, 'V'), - (0x110, 'M', 'đ'), - (0x111, 'V'), - (0x112, 'M', 'ē'), - (0x113, 'V'), - (0x114, 'M', 'ĕ'), - (0x115, 'V'), - (0x116, 'M', 'ė'), - (0x117, 'V'), - (0x118, 'M', 'ę'), - (0x119, 'V'), - (0x11A, 'M', 'ě'), - (0x11B, 'V'), - (0x11C, 'M', 'ĝ'), - (0x11D, 'V'), - (0x11E, 'M', 'ğ'), - (0x11F, 'V'), - (0x120, 'M', 'Ä”'), - (0x121, 'V'), - (0x122, 'M', 'Ä£'), - (0x123, 'V'), - (0x124, 'M', 'Ä„'), - (0x125, 'V'), - (0x126, 'M', 'ħ'), - (0x127, 'V'), - (0x128, 'M', 'Ä©'), - (0x129, 'V'), - (0x12A, 'M', 'Ä«'), - (0x12B, 'V'), + (0xC8, "M", "ĆØ"), + (0xC9, "M", "Ć©"), + (0xCA, "M", "ĆŖ"), + (0xCB, "M", "Ć«"), + (0xCC, "M", "Ƭ"), + (0xCD, "M", "Ć­"), + (0xCE, "M", "Ć®"), + (0xCF, "M", "ĆÆ"), + (0xD0, "M", "ư"), + (0xD1, "M", "Ʊ"), + (0xD2, "M", "ò"), + (0xD3, "M", "ó"), + (0xD4, "M", "Ć“"), + (0xD5, "M", "Ƶ"), + (0xD6, "M", "ƶ"), + (0xD7, "V"), + (0xD8, "M", "Ćø"), + (0xD9, "M", "ù"), + (0xDA, "M", "Ćŗ"), + (0xDB, "M", "Ć»"), + (0xDC, "M", "ü"), + (0xDD, "M", "ý"), + (0xDE, "M", "þ"), + (0xDF, "D", "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", "ā"), + (0x101, "V"), + (0x102, "M", "ă"), + (0x103, "V"), + (0x104, "M", "ą"), + (0x105, "V"), + (0x106, "M", "ć"), + (0x107, "V"), + (0x108, "M", "ĉ"), + (0x109, "V"), + (0x10A, "M", "ċ"), + (0x10B, "V"), + (0x10C, "M", "č"), + (0x10D, "V"), + (0x10E, "M", "ď"), + (0x10F, "V"), + (0x110, "M", "đ"), + (0x111, "V"), + (0x112, "M", "ē"), + (0x113, "V"), + (0x114, "M", "ĕ"), + (0x115, "V"), + (0x116, "M", "ė"), + (0x117, "V"), + (0x118, "M", "ę"), + (0x119, "V"), + (0x11A, "M", "ě"), + (0x11B, "V"), + (0x11C, "M", "ĝ"), + (0x11D, "V"), + (0x11E, "M", "ğ"), + (0x11F, "V"), + (0x120, "M", "Ä”"), + (0x121, "V"), + (0x122, "M", "Ä£"), + (0x123, "V"), + (0x124, "M", "Ä„"), + (0x125, "V"), + (0x126, "M", "ħ"), + (0x127, "V"), + (0x128, "M", "Ä©"), + (0x129, "V"), + (0x12A, "M", "Ä«"), + (0x12B, "V"), ] + def _seg_3() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x12C, 'M', 'Ä­'), - (0x12D, 'V'), - (0x12E, 'M', 'ÄÆ'), - (0x12F, 'V'), - (0x130, 'M', 'i̇'), - (0x131, 'V'), - (0x132, 'M', 'ij'), - (0x134, 'M', 'ĵ'), - (0x135, 'V'), - (0x136, 'M', 'Ä·'), - (0x137, 'V'), - (0x139, 'M', 'Äŗ'), - (0x13A, 'V'), - (0x13B, 'M', 'ļ'), - (0x13C, 'V'), - (0x13D, 'M', 'ľ'), - (0x13E, 'V'), - (0x13F, 'M', 'lĀ·'), - (0x141, 'M', 'ł'), - (0x142, 'V'), - (0x143, 'M', 'ń'), - (0x144, 'V'), - (0x145, 'M', 'ņ'), - (0x146, 'V'), - (0x147, 'M', 'ň'), - (0x148, 'V'), - (0x149, 'M', 'ʼn'), - (0x14A, 'M', 'ŋ'), - (0x14B, 'V'), - (0x14C, 'M', 'ō'), - (0x14D, 'V'), - (0x14E, 'M', 'ŏ'), - (0x14F, 'V'), - (0x150, 'M', 'ő'), - (0x151, 'V'), - (0x152, 'M', 'œ'), - (0x153, 'V'), - (0x154, 'M', 'ŕ'), - (0x155, 'V'), - (0x156, 'M', 'ŗ'), - (0x157, 'V'), - (0x158, 'M', 'ř'), - (0x159, 'V'), - (0x15A, 'M', 'ś'), - (0x15B, 'V'), - (0x15C, 'M', 'ŝ'), - (0x15D, 'V'), - (0x15E, 'M', 'ş'), - (0x15F, 'V'), - (0x160, 'M', 'Å”'), - (0x161, 'V'), - (0x162, 'M', 'Å£'), - (0x163, 'V'), - (0x164, 'M', 'Å„'), - (0x165, 'V'), - (0x166, 'M', 'ŧ'), - (0x167, 'V'), - (0x168, 'M', 'Å©'), - (0x169, 'V'), - (0x16A, 'M', 'Å«'), - (0x16B, 'V'), - (0x16C, 'M', 'Å­'), - (0x16D, 'V'), - (0x16E, 'M', 'ÅÆ'), - (0x16F, 'V'), - (0x170, 'M', 'ű'), - (0x171, 'V'), - (0x172, 'M', 'ų'), - (0x173, 'V'), - (0x174, 'M', 'ŵ'), - (0x175, 'V'), - (0x176, 'M', 'Å·'), - (0x177, 'V'), - (0x178, 'M', 'Ćæ'), - (0x179, 'M', 'Åŗ'), - (0x17A, 'V'), - (0x17B, 'M', 'ż'), - (0x17C, 'V'), - (0x17D, 'M', 'ž'), - (0x17E, 'V'), - (0x17F, 'M', 's'), - (0x180, 'V'), - (0x181, 'M', 'ɓ'), - (0x182, 'M', 'ʃ'), - (0x183, 'V'), - (0x184, 'M', 'ʅ'), - (0x185, 'V'), - (0x186, 'M', 'ɔ'), - (0x187, 'M', 'ʈ'), - (0x188, 'V'), - (0x189, 'M', 'ɖ'), - (0x18A, 'M', 'ɗ'), - (0x18B, 'M', 'ƌ'), - (0x18C, 'V'), - (0x18E, 'M', 'Ē'), - (0x18F, 'M', 'ə'), - (0x190, 'M', 'ɛ'), - (0x191, 'M', 'ʒ'), - (0x192, 'V'), - (0x193, 'M', 'É '), + (0x12C, "M", "Ä­"), + (0x12D, "V"), + (0x12E, "M", "ÄÆ"), + (0x12F, "V"), + (0x130, "M", "i̇"), + (0x131, "V"), + (0x132, "M", "ij"), + (0x134, "M", "ĵ"), + (0x135, "V"), + (0x136, "M", "Ä·"), + (0x137, "V"), + (0x139, "M", "Äŗ"), + (0x13A, "V"), + (0x13B, "M", "ļ"), + (0x13C, "V"), + (0x13D, "M", "ľ"), + (0x13E, "V"), + (0x13F, "M", "lĀ·"), + (0x141, "M", "ł"), + (0x142, "V"), + (0x143, "M", "ń"), + (0x144, "V"), + (0x145, "M", "ņ"), + (0x146, "V"), + (0x147, "M", "ň"), + (0x148, "V"), + (0x149, "M", "ʼn"), + (0x14A, "M", "ŋ"), + (0x14B, "V"), + (0x14C, "M", "ō"), + (0x14D, "V"), + (0x14E, "M", "ŏ"), + (0x14F, "V"), + (0x150, "M", "ő"), + (0x151, "V"), + (0x152, "M", "œ"), + (0x153, "V"), + (0x154, "M", "ŕ"), + (0x155, "V"), + (0x156, "M", "ŗ"), + (0x157, "V"), + (0x158, "M", "ř"), + (0x159, "V"), + (0x15A, "M", "ś"), + (0x15B, "V"), + (0x15C, "M", "ŝ"), + (0x15D, "V"), + (0x15E, "M", "ş"), + (0x15F, "V"), + (0x160, "M", "Å”"), + (0x161, "V"), + (0x162, "M", "Å£"), + (0x163, "V"), + (0x164, "M", "Å„"), + (0x165, "V"), + (0x166, "M", "ŧ"), + (0x167, "V"), + (0x168, "M", "Å©"), + (0x169, "V"), + (0x16A, "M", "Å«"), + (0x16B, "V"), + (0x16C, "M", "Å­"), + (0x16D, "V"), + (0x16E, "M", "ÅÆ"), + (0x16F, "V"), + (0x170, "M", "ű"), + (0x171, "V"), + (0x172, "M", "ų"), + (0x173, "V"), + (0x174, "M", "ŵ"), + (0x175, "V"), + (0x176, "M", "Å·"), + (0x177, "V"), + (0x178, "M", "Ćæ"), + (0x179, "M", "Åŗ"), + (0x17A, "V"), + (0x17B, "M", "ż"), + (0x17C, "V"), + (0x17D, "M", "ž"), + (0x17E, "V"), + (0x17F, "M", "s"), + (0x180, "V"), + (0x181, "M", "ɓ"), + (0x182, "M", "ʃ"), + (0x183, "V"), + (0x184, "M", "ʅ"), + (0x185, "V"), + (0x186, "M", "ɔ"), + (0x187, "M", "ʈ"), + (0x188, "V"), + (0x189, "M", "ɖ"), + (0x18A, "M", "ɗ"), + (0x18B, "M", "ƌ"), + (0x18C, "V"), + (0x18E, "M", "Ē"), + (0x18F, "M", "ə"), + (0x190, "M", "ɛ"), + (0x191, "M", "ʒ"), + (0x192, "V"), + (0x193, "M", "É "), ] + def _seg_4() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x194, 'M', 'É£'), - (0x195, 'V'), - (0x196, 'M', 'É©'), - (0x197, 'M', 'ÉØ'), - (0x198, 'M', 'ʙ'), - (0x199, 'V'), - (0x19C, 'M', 'ÉÆ'), - (0x19D, 'M', 'ɲ'), - (0x19E, 'V'), - (0x19F, 'M', 'ɵ'), - (0x1A0, 'M', 'Ę”'), - (0x1A1, 'V'), - (0x1A2, 'M', 'Ę£'), - (0x1A3, 'V'), - (0x1A4, 'M', 'Ę„'), - (0x1A5, 'V'), - (0x1A6, 'M', 'Ź€'), - (0x1A7, 'M', 'ĘØ'), - (0x1A8, 'V'), - (0x1A9, 'M', 'ʃ'), - (0x1AA, 'V'), - (0x1AC, 'M', 'Ę­'), - (0x1AD, 'V'), - (0x1AE, 'M', 'ʈ'), - (0x1AF, 'M', 'ʰ'), - (0x1B0, 'V'), - (0x1B1, 'M', 'ʊ'), - (0x1B2, 'M', 'Ź‹'), - (0x1B3, 'M', 'Ę“'), - (0x1B4, 'V'), - (0x1B5, 'M', 'ʶ'), - (0x1B6, 'V'), - (0x1B7, 'M', 'Ź’'), - (0x1B8, 'M', 'ƹ'), - (0x1B9, 'V'), - (0x1BC, 'M', 'ƽ'), - (0x1BD, 'V'), - (0x1C4, 'M', 'dž'), - (0x1C7, 'M', 'lj'), - (0x1CA, 'M', 'nj'), - (0x1CD, 'M', 'ĒŽ'), - (0x1CE, 'V'), - (0x1CF, 'M', 'ǐ'), - (0x1D0, 'V'), - (0x1D1, 'M', 'Ē’'), - (0x1D2, 'V'), - (0x1D3, 'M', 'Ē”'), - (0x1D4, 'V'), - (0x1D5, 'M', 'Ē–'), - (0x1D6, 'V'), - (0x1D7, 'M', 'ǘ'), - (0x1D8, 'V'), - (0x1D9, 'M', 'ǚ'), - (0x1DA, 'V'), - (0x1DB, 'M', 'ǜ'), - (0x1DC, 'V'), - (0x1DE, 'M', 'ǟ'), - (0x1DF, 'V'), - (0x1E0, 'M', 'Ē”'), - (0x1E1, 'V'), - (0x1E2, 'M', 'Ē£'), - (0x1E3, 'V'), - (0x1E4, 'M', 'Ē„'), - (0x1E5, 'V'), - (0x1E6, 'M', 'ǧ'), - (0x1E7, 'V'), - (0x1E8, 'M', 'Ē©'), - (0x1E9, 'V'), - (0x1EA, 'M', 'Ē«'), - (0x1EB, 'V'), - (0x1EC, 'M', 'Ē­'), - (0x1ED, 'V'), - (0x1EE, 'M', 'ĒÆ'), - (0x1EF, 'V'), - (0x1F1, 'M', 'dz'), - (0x1F4, 'M', 'ǵ'), - (0x1F5, 'V'), - (0x1F6, 'M', 'ʕ'), - (0x1F7, 'M', 'Ęæ'), - (0x1F8, 'M', 'ǹ'), - (0x1F9, 'V'), - (0x1FA, 'M', 'Ē»'), - (0x1FB, 'V'), - (0x1FC, 'M', 'ǽ'), - (0x1FD, 'V'), - (0x1FE, 'M', 'Ēæ'), - (0x1FF, 'V'), - (0x200, 'M', 'ȁ'), - (0x201, 'V'), - (0x202, 'M', 'ȃ'), - (0x203, 'V'), - (0x204, 'M', 'ȅ'), - (0x205, 'V'), - (0x206, 'M', 'ȇ'), - (0x207, 'V'), - (0x208, 'M', 'ȉ'), - (0x209, 'V'), - (0x20A, 'M', 'ȋ'), - (0x20B, 'V'), - (0x20C, 'M', 'ȍ'), + (0x194, "M", "É£"), + (0x195, "V"), + (0x196, "M", "É©"), + (0x197, "M", "ÉØ"), + (0x198, "M", "ʙ"), + (0x199, "V"), + (0x19C, "M", "ÉÆ"), + (0x19D, "M", "ɲ"), + (0x19E, "V"), + (0x19F, "M", "ɵ"), + (0x1A0, "M", "Ę”"), + (0x1A1, "V"), + (0x1A2, "M", "Ę£"), + (0x1A3, "V"), + (0x1A4, "M", "Ę„"), + (0x1A5, "V"), + (0x1A6, "M", "Ź€"), + (0x1A7, "M", "ĘØ"), + (0x1A8, "V"), + (0x1A9, "M", "ʃ"), + (0x1AA, "V"), + (0x1AC, "M", "Ę­"), + (0x1AD, "V"), + (0x1AE, "M", "ʈ"), + (0x1AF, "M", "ʰ"), + (0x1B0, "V"), + (0x1B1, "M", "ʊ"), + (0x1B2, "M", "Ź‹"), + (0x1B3, "M", "Ę“"), + (0x1B4, "V"), + (0x1B5, "M", "ʶ"), + (0x1B6, "V"), + (0x1B7, "M", "Ź’"), + (0x1B8, "M", "ƹ"), + (0x1B9, "V"), + (0x1BC, "M", "ƽ"), + (0x1BD, "V"), + (0x1C4, "M", "dž"), + (0x1C7, "M", "lj"), + (0x1CA, "M", "nj"), + (0x1CD, "M", "ĒŽ"), + (0x1CE, "V"), + (0x1CF, "M", "ǐ"), + (0x1D0, "V"), + (0x1D1, "M", "Ē’"), + (0x1D2, "V"), + (0x1D3, "M", "Ē”"), + (0x1D4, "V"), + (0x1D5, "M", "Ē–"), + (0x1D6, "V"), + (0x1D7, "M", "ǘ"), + (0x1D8, "V"), + (0x1D9, "M", "ǚ"), + (0x1DA, "V"), + (0x1DB, "M", "ǜ"), + (0x1DC, "V"), + (0x1DE, "M", "ǟ"), + (0x1DF, "V"), + (0x1E0, "M", "Ē”"), + (0x1E1, "V"), + (0x1E2, "M", "Ē£"), + (0x1E3, "V"), + (0x1E4, "M", "Ē„"), + (0x1E5, "V"), + (0x1E6, "M", "ǧ"), + (0x1E7, "V"), + (0x1E8, "M", "Ē©"), + (0x1E9, "V"), + (0x1EA, "M", "Ē«"), + (0x1EB, "V"), + (0x1EC, "M", "Ē­"), + (0x1ED, "V"), + (0x1EE, "M", "ĒÆ"), + (0x1EF, "V"), + (0x1F1, "M", "dz"), + (0x1F4, "M", "ǵ"), + (0x1F5, "V"), + (0x1F6, "M", "ʕ"), + (0x1F7, "M", "Ęæ"), + (0x1F8, "M", "ǹ"), + (0x1F9, "V"), + (0x1FA, "M", "Ē»"), + (0x1FB, "V"), + (0x1FC, "M", "ǽ"), + (0x1FD, "V"), + (0x1FE, "M", "Ēæ"), + (0x1FF, "V"), + (0x200, "M", "ȁ"), + (0x201, "V"), + (0x202, "M", "ȃ"), + (0x203, "V"), + (0x204, "M", "ȅ"), + (0x205, "V"), + (0x206, "M", "ȇ"), + (0x207, "V"), + (0x208, "M", "ȉ"), + (0x209, "V"), + (0x20A, "M", "ȋ"), + (0x20B, "V"), + (0x20C, "M", "ȍ"), ] + def _seg_5() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x20D, 'V'), - (0x20E, 'M', 'ȏ'), - (0x20F, 'V'), - (0x210, 'M', 'ȑ'), - (0x211, 'V'), - (0x212, 'M', 'ȓ'), - (0x213, 'V'), - (0x214, 'M', 'ȕ'), - (0x215, 'V'), - (0x216, 'M', 'ȗ'), - (0x217, 'V'), - (0x218, 'M', 'ș'), - (0x219, 'V'), - (0x21A, 'M', 'ț'), - (0x21B, 'V'), - (0x21C, 'M', 'ȝ'), - (0x21D, 'V'), - (0x21E, 'M', 'ȟ'), - (0x21F, 'V'), - (0x220, 'M', 'ʞ'), - (0x221, 'V'), - (0x222, 'M', 'Č£'), - (0x223, 'V'), - (0x224, 'M', 'Č„'), - (0x225, 'V'), - (0x226, 'M', 'ȧ'), - (0x227, 'V'), - (0x228, 'M', 'Č©'), - (0x229, 'V'), - (0x22A, 'M', 'Č«'), - (0x22B, 'V'), - (0x22C, 'M', 'Č­'), - (0x22D, 'V'), - (0x22E, 'M', 'ČÆ'), - (0x22F, 'V'), - (0x230, 'M', 'ȱ'), - (0x231, 'V'), - (0x232, 'M', 'ȳ'), - (0x233, 'V'), - (0x23A, 'M', 'ⱄ'), - (0x23B, 'M', 'ȼ'), - (0x23C, 'V'), - (0x23D, 'M', 'ƚ'), - (0x23E, 'M', 'ⱦ'), - (0x23F, 'V'), - (0x241, 'M', 'ɂ'), - (0x242, 'V'), - (0x243, 'M', 'ʀ'), - (0x244, 'M', 'ʉ'), - (0x245, 'M', 'ʌ'), - (0x246, 'M', 'ɇ'), - (0x247, 'V'), - (0x248, 'M', 'ɉ'), - (0x249, 'V'), - (0x24A, 'M', 'ɋ'), - (0x24B, 'V'), - (0x24C, 'M', 'ɍ'), - (0x24D, 'V'), - (0x24E, 'M', 'ɏ'), - (0x24F, 'V'), - (0x2B0, 'M', 'h'), - (0x2B1, 'M', 'ɦ'), - (0x2B2, 'M', 'j'), - (0x2B3, 'M', 'r'), - (0x2B4, 'M', 'ɹ'), - (0x2B5, 'M', 'É»'), - (0x2B6, 'M', 'ʁ'), - (0x2B7, 'M', 'w'), - (0x2B8, 'M', 'y'), - (0x2B9, 'V'), - (0x2D8, '3', ' ̆'), - (0x2D9, '3', ' ̇'), - (0x2DA, '3', ' ̊'), - (0x2DB, '3', ' ĢØ'), - (0x2DC, '3', ' ̃'), - (0x2DD, '3', ' Ģ‹'), - (0x2DE, 'V'), - (0x2E0, 'M', 'É£'), - (0x2E1, 'M', 'l'), - (0x2E2, 'M', 's'), - (0x2E3, 'M', 'x'), - (0x2E4, 'M', 'Ź•'), - (0x2E5, 'V'), - (0x340, 'M', 'Ģ€'), - (0x341, 'M', '́'), - (0x342, 'V'), - (0x343, 'M', 'Ģ“'), - (0x344, 'M', '̈́'), - (0x345, 'M', 'ι'), - (0x346, 'V'), - (0x34F, 'I'), - (0x350, 'V'), - (0x370, 'M', 'ͱ'), - (0x371, 'V'), - (0x372, 'M', 'ͳ'), - (0x373, 'V'), - (0x374, 'M', 'ʹ'), - (0x375, 'V'), - (0x376, 'M', 'Ķ·'), - (0x377, 'V'), + (0x20D, "V"), + (0x20E, "M", "ȏ"), + (0x20F, "V"), + (0x210, "M", "ȑ"), + (0x211, "V"), + (0x212, "M", "ȓ"), + (0x213, "V"), + (0x214, "M", "ȕ"), + (0x215, "V"), + (0x216, "M", "ȗ"), + (0x217, "V"), + (0x218, "M", "ș"), + (0x219, "V"), + (0x21A, "M", "ț"), + (0x21B, "V"), + (0x21C, "M", "ȝ"), + (0x21D, "V"), + (0x21E, "M", "ȟ"), + (0x21F, "V"), + (0x220, "M", "ʞ"), + (0x221, "V"), + (0x222, "M", "Č£"), + (0x223, "V"), + (0x224, "M", "Č„"), + (0x225, "V"), + (0x226, "M", "ȧ"), + (0x227, "V"), + (0x228, "M", "Č©"), + (0x229, "V"), + (0x22A, "M", "Č«"), + (0x22B, "V"), + (0x22C, "M", "Č­"), + (0x22D, "V"), + (0x22E, "M", "ČÆ"), + (0x22F, "V"), + (0x230, "M", "ȱ"), + (0x231, "V"), + (0x232, "M", "ȳ"), + (0x233, "V"), + (0x23A, "M", "ⱄ"), + (0x23B, "M", "ȼ"), + (0x23C, "V"), + (0x23D, "M", "ƚ"), + (0x23E, "M", "ⱦ"), + (0x23F, "V"), + (0x241, "M", "ɂ"), + (0x242, "V"), + (0x243, "M", "ʀ"), + (0x244, "M", "ʉ"), + (0x245, "M", "ʌ"), + (0x246, "M", "ɇ"), + (0x247, "V"), + (0x248, "M", "ɉ"), + (0x249, "V"), + (0x24A, "M", "ɋ"), + (0x24B, "V"), + (0x24C, "M", "ɍ"), + (0x24D, "V"), + (0x24E, "M", "ɏ"), + (0x24F, "V"), + (0x2B0, "M", "h"), + (0x2B1, "M", "ɦ"), + (0x2B2, "M", "j"), + (0x2B3, "M", "r"), + (0x2B4, "M", "ɹ"), + (0x2B5, "M", "É»"), + (0x2B6, "M", "ʁ"), + (0x2B7, "M", "w"), + (0x2B8, "M", "y"), + (0x2B9, "V"), + (0x2D8, "3", " ̆"), + (0x2D9, "3", " ̇"), + (0x2DA, "3", " ̊"), + (0x2DB, "3", " ĢØ"), + (0x2DC, "3", " ̃"), + (0x2DD, "3", " Ģ‹"), + (0x2DE, "V"), + (0x2E0, "M", "É£"), + (0x2E1, "M", "l"), + (0x2E2, "M", "s"), + (0x2E3, "M", "x"), + (0x2E4, "M", "Ź•"), + (0x2E5, "V"), + (0x340, "M", "Ģ€"), + (0x341, "M", "́"), + (0x342, "V"), + (0x343, "M", "Ģ“"), + (0x344, "M", "̈́"), + (0x345, "M", "ι"), + (0x346, "V"), + (0x34F, "I"), + (0x350, "V"), + (0x370, "M", "ͱ"), + (0x371, "V"), + (0x372, "M", "ͳ"), + (0x373, "V"), + (0x374, "M", "ʹ"), + (0x375, "V"), + (0x376, "M", "Ķ·"), + (0x377, "V"), ] + def _seg_6() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x378, 'X'), - (0x37A, '3', ' ι'), - (0x37B, 'V'), - (0x37E, '3', ';'), - (0x37F, 'M', 'ϳ'), - (0x380, 'X'), - (0x384, '3', ' ́'), - (0x385, '3', ' ̈́'), - (0x386, 'M', 'ά'), - (0x387, 'M', 'Ā·'), - (0x388, 'M', 'Ī­'), - (0x389, 'M', 'Ī®'), - (0x38A, 'M', 'ĪÆ'), - (0x38B, 'X'), - (0x38C, 'M', 'ό'), - (0x38D, 'X'), - (0x38E, 'M', 'Ļ'), - (0x38F, 'M', 'ĻŽ'), - (0x390, 'V'), - (0x391, 'M', 'α'), - (0x392, 'M', 'β'), - (0x393, 'M', 'γ'), - (0x394, 'M', 'Ī“'), - (0x395, 'M', 'ε'), - (0x396, 'M', 'ζ'), - (0x397, 'M', 'Ī·'), - (0x398, 'M', 'Īø'), - (0x399, 'M', 'ι'), - (0x39A, 'M', 'Īŗ'), - (0x39B, 'M', 'Ī»'), - (0x39C, 'M', 'μ'), - (0x39D, 'M', 'ν'), - (0x39E, 'M', 'ξ'), - (0x39F, 'M', 'Īæ'), - (0x3A0, 'M', 'Ļ€'), - (0x3A1, 'M', 'ρ'), - (0x3A2, 'X'), - (0x3A3, 'M', 'σ'), - (0x3A4, 'M', 'Ļ„'), - (0x3A5, 'M', 'Ļ…'), - (0x3A6, 'M', 'φ'), - (0x3A7, 'M', 'χ'), - (0x3A8, 'M', 'ψ'), - (0x3A9, 'M', 'ω'), - (0x3AA, 'M', 'ϊ'), - (0x3AB, 'M', 'Ļ‹'), - (0x3AC, 'V'), - (0x3C2, 'D', 'σ'), - (0x3C3, 'V'), - (0x3CF, 'M', 'Ļ—'), - (0x3D0, 'M', 'β'), - (0x3D1, 'M', 'Īø'), - (0x3D2, 'M', 'Ļ…'), - (0x3D3, 'M', 'Ļ'), - (0x3D4, 'M', 'Ļ‹'), - (0x3D5, 'M', 'φ'), - (0x3D6, 'M', 'Ļ€'), - (0x3D7, 'V'), - (0x3D8, 'M', 'Ļ™'), - (0x3D9, 'V'), - (0x3DA, 'M', 'Ļ›'), - (0x3DB, 'V'), - (0x3DC, 'M', 'Ļ'), - (0x3DD, 'V'), - (0x3DE, 'M', 'ϟ'), - (0x3DF, 'V'), - (0x3E0, 'M', 'Ļ”'), - (0x3E1, 'V'), - (0x3E2, 'M', 'Ļ£'), - (0x3E3, 'V'), - (0x3E4, 'M', 'Ļ„'), - (0x3E5, 'V'), - (0x3E6, 'M', 'ϧ'), - (0x3E7, 'V'), - (0x3E8, 'M', 'Ļ©'), - (0x3E9, 'V'), - (0x3EA, 'M', 'Ļ«'), - (0x3EB, 'V'), - (0x3EC, 'M', 'Ļ­'), - (0x3ED, 'V'), - (0x3EE, 'M', 'ĻÆ'), - (0x3EF, 'V'), - (0x3F0, 'M', 'Īŗ'), - (0x3F1, 'M', 'ρ'), - (0x3F2, 'M', 'σ'), - (0x3F3, 'V'), - (0x3F4, 'M', 'Īø'), - (0x3F5, 'M', 'ε'), - (0x3F6, 'V'), - (0x3F7, 'M', 'Ļø'), - (0x3F8, 'V'), - (0x3F9, 'M', 'σ'), - (0x3FA, 'M', 'Ļ»'), - (0x3FB, 'V'), - (0x3FD, 'M', 'Ķ»'), - (0x3FE, 'M', 'ͼ'), - (0x3FF, 'M', 'ͽ'), - (0x400, 'M', 'ѐ'), - (0x401, 'M', 'ё'), - (0x402, 'M', 'ђ'), + (0x378, "X"), + (0x37A, "3", " ι"), + (0x37B, "V"), + (0x37E, "3", ";"), + (0x37F, "M", "ϳ"), + (0x380, "X"), + (0x384, "3", " ́"), + (0x385, "3", " ̈́"), + (0x386, "M", "ά"), + (0x387, "M", "Ā·"), + (0x388, "M", "Ī­"), + (0x389, "M", "Ī®"), + (0x38A, "M", "ĪÆ"), + (0x38B, "X"), + (0x38C, "M", "ό"), + (0x38D, "X"), + (0x38E, "M", "Ļ"), + (0x38F, "M", "ĻŽ"), + (0x390, "V"), + (0x391, "M", "α"), + (0x392, "M", "β"), + (0x393, "M", "γ"), + (0x394, "M", "Ī“"), + (0x395, "M", "ε"), + (0x396, "M", "ζ"), + (0x397, "M", "Ī·"), + (0x398, "M", "Īø"), + (0x399, "M", "ι"), + (0x39A, "M", "Īŗ"), + (0x39B, "M", "Ī»"), + (0x39C, "M", "μ"), + (0x39D, "M", "ν"), + (0x39E, "M", "ξ"), + (0x39F, "M", "Īæ"), + (0x3A0, "M", "Ļ€"), + (0x3A1, "M", "ρ"), + (0x3A2, "X"), + (0x3A3, "M", "σ"), + (0x3A4, "M", "Ļ„"), + (0x3A5, "M", "Ļ…"), + (0x3A6, "M", "φ"), + (0x3A7, "M", "χ"), + (0x3A8, "M", "ψ"), + (0x3A9, "M", "ω"), + (0x3AA, "M", "ϊ"), + (0x3AB, "M", "Ļ‹"), + (0x3AC, "V"), + (0x3C2, "D", "σ"), + (0x3C3, "V"), + (0x3CF, "M", "Ļ—"), + (0x3D0, "M", "β"), + (0x3D1, "M", "Īø"), + (0x3D2, "M", "Ļ…"), + (0x3D3, "M", "Ļ"), + (0x3D4, "M", "Ļ‹"), + (0x3D5, "M", "φ"), + (0x3D6, "M", "Ļ€"), + (0x3D7, "V"), + (0x3D8, "M", "Ļ™"), + (0x3D9, "V"), + (0x3DA, "M", "Ļ›"), + (0x3DB, "V"), + (0x3DC, "M", "Ļ"), + (0x3DD, "V"), + (0x3DE, "M", "ϟ"), + (0x3DF, "V"), + (0x3E0, "M", "Ļ”"), + (0x3E1, "V"), + (0x3E2, "M", "Ļ£"), + (0x3E3, "V"), + (0x3E4, "M", "Ļ„"), + (0x3E5, "V"), + (0x3E6, "M", "ϧ"), + (0x3E7, "V"), + (0x3E8, "M", "Ļ©"), + (0x3E9, "V"), + (0x3EA, "M", "Ļ«"), + (0x3EB, "V"), + (0x3EC, "M", "Ļ­"), + (0x3ED, "V"), + (0x3EE, "M", "ĻÆ"), + (0x3EF, "V"), + (0x3F0, "M", "Īŗ"), + (0x3F1, "M", "ρ"), + (0x3F2, "M", "σ"), + (0x3F3, "V"), + (0x3F4, "M", "Īø"), + (0x3F5, "M", "ε"), + (0x3F6, "V"), + (0x3F7, "M", "Ļø"), + (0x3F8, "V"), + (0x3F9, "M", "σ"), + (0x3FA, "M", "Ļ»"), + (0x3FB, "V"), + (0x3FD, "M", "Ķ»"), + (0x3FE, "M", "ͼ"), + (0x3FF, "M", "ͽ"), + (0x400, "M", "ѐ"), + (0x401, "M", "ё"), + (0x402, "M", "ђ"), ] + def _seg_7() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x403, 'M', 'ѓ'), - (0x404, 'M', 'є'), - (0x405, 'M', 'ѕ'), - (0x406, 'M', 'і'), - (0x407, 'M', 'ї'), - (0x408, 'M', 'ј'), - (0x409, 'M', 'љ'), - (0x40A, 'M', 'њ'), - (0x40B, 'M', 'ћ'), - (0x40C, 'M', 'ќ'), - (0x40D, 'M', 'ѝ'), - (0x40E, 'M', 'ў'), - (0x40F, 'M', 'џ'), - (0x410, 'M', 'а'), - (0x411, 'M', 'б'), - (0x412, 'M', 'в'), - (0x413, 'M', 'г'), - (0x414, 'M', 'Š“'), - (0x415, 'M', 'е'), - (0x416, 'M', 'ж'), - (0x417, 'M', 'Š·'), - (0x418, 'M', 'Šø'), - (0x419, 'M', 'й'), - (0x41A, 'M', 'Šŗ'), - (0x41B, 'M', 'Š»'), - (0x41C, 'M', 'м'), - (0x41D, 'M', 'н'), - (0x41E, 'M', 'о'), - (0x41F, 'M', 'Šæ'), - (0x420, 'M', 'р'), - (0x421, 'M', 'с'), - (0x422, 'M', 'т'), - (0x423, 'M', 'у'), - (0x424, 'M', 'ф'), - (0x425, 'M', 'х'), - (0x426, 'M', 'ц'), - (0x427, 'M', 'ч'), - (0x428, 'M', 'ш'), - (0x429, 'M', 'щ'), - (0x42A, 'M', 'ъ'), - (0x42B, 'M', 'ы'), - (0x42C, 'M', 'ь'), - (0x42D, 'M', 'э'), - (0x42E, 'M', 'ю'), - (0x42F, 'M', 'я'), - (0x430, 'V'), - (0x460, 'M', 'Ń”'), - (0x461, 'V'), - (0x462, 'M', 'Ń£'), - (0x463, 'V'), - (0x464, 'M', 'Ń„'), - (0x465, 'V'), - (0x466, 'M', 'ѧ'), - (0x467, 'V'), - (0x468, 'M', 'Ń©'), - (0x469, 'V'), - (0x46A, 'M', 'Ń«'), - (0x46B, 'V'), - (0x46C, 'M', 'Ń­'), - (0x46D, 'V'), - (0x46E, 'M', 'ŃÆ'), - (0x46F, 'V'), - (0x470, 'M', 'ѱ'), - (0x471, 'V'), - (0x472, 'M', 'ѳ'), - (0x473, 'V'), - (0x474, 'M', 'ѵ'), - (0x475, 'V'), - (0x476, 'M', 'Ń·'), - (0x477, 'V'), - (0x478, 'M', 'ѹ'), - (0x479, 'V'), - (0x47A, 'M', 'Ń»'), - (0x47B, 'V'), - (0x47C, 'M', 'ѽ'), - (0x47D, 'V'), - (0x47E, 'M', 'Ńæ'), - (0x47F, 'V'), - (0x480, 'M', 'ҁ'), - (0x481, 'V'), - (0x48A, 'M', 'Ņ‹'), - (0x48B, 'V'), - (0x48C, 'M', 'Ņ'), - (0x48D, 'V'), - (0x48E, 'M', 'Ņ'), - (0x48F, 'V'), - (0x490, 'M', 'Ņ‘'), - (0x491, 'V'), - (0x492, 'M', 'Ņ“'), - (0x493, 'V'), - (0x494, 'M', 'Ņ•'), - (0x495, 'V'), - (0x496, 'M', 'Ņ—'), - (0x497, 'V'), - (0x498, 'M', 'Ņ™'), - (0x499, 'V'), - (0x49A, 'M', 'Ņ›'), - (0x49B, 'V'), - (0x49C, 'M', 'Ņ'), - (0x49D, 'V'), + (0x403, "M", "ѓ"), + (0x404, "M", "є"), + (0x405, "M", "ѕ"), + (0x406, "M", "і"), + (0x407, "M", "ї"), + (0x408, "M", "ј"), + (0x409, "M", "љ"), + (0x40A, "M", "њ"), + (0x40B, "M", "ћ"), + (0x40C, "M", "ќ"), + (0x40D, "M", "ѝ"), + (0x40E, "M", "ў"), + (0x40F, "M", "џ"), + (0x410, "M", "а"), + (0x411, "M", "б"), + (0x412, "M", "в"), + (0x413, "M", "г"), + (0x414, "M", "Š“"), + (0x415, "M", "е"), + (0x416, "M", "ж"), + (0x417, "M", "Š·"), + (0x418, "M", "Šø"), + (0x419, "M", "й"), + (0x41A, "M", "Šŗ"), + (0x41B, "M", "Š»"), + (0x41C, "M", "м"), + (0x41D, "M", "н"), + (0x41E, "M", "о"), + (0x41F, "M", "Šæ"), + (0x420, "M", "р"), + (0x421, "M", "с"), + (0x422, "M", "т"), + (0x423, "M", "у"), + (0x424, "M", "ф"), + (0x425, "M", "х"), + (0x426, "M", "ц"), + (0x427, "M", "ч"), + (0x428, "M", "ш"), + (0x429, "M", "щ"), + (0x42A, "M", "ъ"), + (0x42B, "M", "ы"), + (0x42C, "M", "ь"), + (0x42D, "M", "э"), + (0x42E, "M", "ю"), + (0x42F, "M", "я"), + (0x430, "V"), + (0x460, "M", "Ń”"), + (0x461, "V"), + (0x462, "M", "Ń£"), + (0x463, "V"), + (0x464, "M", "Ń„"), + (0x465, "V"), + (0x466, "M", "ѧ"), + (0x467, "V"), + (0x468, "M", "Ń©"), + (0x469, "V"), + (0x46A, "M", "Ń«"), + (0x46B, "V"), + (0x46C, "M", "Ń­"), + (0x46D, "V"), + (0x46E, "M", "ŃÆ"), + (0x46F, "V"), + (0x470, "M", "ѱ"), + (0x471, "V"), + (0x472, "M", "ѳ"), + (0x473, "V"), + (0x474, "M", "ѵ"), + (0x475, "V"), + (0x476, "M", "Ń·"), + (0x477, "V"), + (0x478, "M", "ѹ"), + (0x479, "V"), + (0x47A, "M", "Ń»"), + (0x47B, "V"), + (0x47C, "M", "ѽ"), + (0x47D, "V"), + (0x47E, "M", "Ńæ"), + (0x47F, "V"), + (0x480, "M", "ҁ"), + (0x481, "V"), + (0x48A, "M", "Ņ‹"), + (0x48B, "V"), + (0x48C, "M", "Ņ"), + (0x48D, "V"), + (0x48E, "M", "Ņ"), + (0x48F, "V"), + (0x490, "M", "Ņ‘"), + (0x491, "V"), + (0x492, "M", "Ņ“"), + (0x493, "V"), + (0x494, "M", "Ņ•"), + (0x495, "V"), + (0x496, "M", "Ņ—"), + (0x497, "V"), + (0x498, "M", "Ņ™"), + (0x499, "V"), + (0x49A, "M", "Ņ›"), + (0x49B, "V"), + (0x49C, "M", "Ņ"), + (0x49D, "V"), ] + def _seg_8() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x49E, 'M', 'ҟ'), - (0x49F, 'V'), - (0x4A0, 'M', 'Ņ”'), - (0x4A1, 'V'), - (0x4A2, 'M', 'Ņ£'), - (0x4A3, 'V'), - (0x4A4, 'M', 'Ņ„'), - (0x4A5, 'V'), - (0x4A6, 'M', 'ҧ'), - (0x4A7, 'V'), - (0x4A8, 'M', 'Ņ©'), - (0x4A9, 'V'), - (0x4AA, 'M', 'Ņ«'), - (0x4AB, 'V'), - (0x4AC, 'M', 'Ņ­'), - (0x4AD, 'V'), - (0x4AE, 'M', 'ŅÆ'), - (0x4AF, 'V'), - (0x4B0, 'M', 'ұ'), - (0x4B1, 'V'), - (0x4B2, 'M', 'ҳ'), - (0x4B3, 'V'), - (0x4B4, 'M', 'ҵ'), - (0x4B5, 'V'), - (0x4B6, 'M', 'Ņ·'), - (0x4B7, 'V'), - (0x4B8, 'M', 'ҹ'), - (0x4B9, 'V'), - (0x4BA, 'M', 'Ņ»'), - (0x4BB, 'V'), - (0x4BC, 'M', 'ҽ'), - (0x4BD, 'V'), - (0x4BE, 'M', 'Ņæ'), - (0x4BF, 'V'), - (0x4C0, 'X'), - (0x4C1, 'M', 'ӂ'), - (0x4C2, 'V'), - (0x4C3, 'M', 'ӄ'), - (0x4C4, 'V'), - (0x4C5, 'M', 'ӆ'), - (0x4C6, 'V'), - (0x4C7, 'M', 'ӈ'), - (0x4C8, 'V'), - (0x4C9, 'M', 'ӊ'), - (0x4CA, 'V'), - (0x4CB, 'M', 'ӌ'), - (0x4CC, 'V'), - (0x4CD, 'M', 'ӎ'), - (0x4CE, 'V'), - (0x4D0, 'M', 'ӑ'), - (0x4D1, 'V'), - (0x4D2, 'M', 'ӓ'), - (0x4D3, 'V'), - (0x4D4, 'M', 'ӕ'), - (0x4D5, 'V'), - (0x4D6, 'M', 'ӗ'), - (0x4D7, 'V'), - (0x4D8, 'M', 'ә'), - (0x4D9, 'V'), - (0x4DA, 'M', 'ӛ'), - (0x4DB, 'V'), - (0x4DC, 'M', 'ӝ'), - (0x4DD, 'V'), - (0x4DE, 'M', 'ӟ'), - (0x4DF, 'V'), - (0x4E0, 'M', 'Ó”'), - (0x4E1, 'V'), - (0x4E2, 'M', 'Ó£'), - (0x4E3, 'V'), - (0x4E4, 'M', 'Ó„'), - (0x4E5, 'V'), - (0x4E6, 'M', 'Ó§'), - (0x4E7, 'V'), - (0x4E8, 'M', 'Ó©'), - (0x4E9, 'V'), - (0x4EA, 'M', 'Ó«'), - (0x4EB, 'V'), - (0x4EC, 'M', 'Ó­'), - (0x4ED, 'V'), - (0x4EE, 'M', 'ÓÆ'), - (0x4EF, 'V'), - (0x4F0, 'M', 'Ó±'), - (0x4F1, 'V'), - (0x4F2, 'M', 'Ó³'), - (0x4F3, 'V'), - (0x4F4, 'M', 'Óµ'), - (0x4F5, 'V'), - (0x4F6, 'M', 'Ó·'), - (0x4F7, 'V'), - (0x4F8, 'M', 'Ó¹'), - (0x4F9, 'V'), - (0x4FA, 'M', 'Ó»'), - (0x4FB, 'V'), - (0x4FC, 'M', 'Ó½'), - (0x4FD, 'V'), - (0x4FE, 'M', 'Óæ'), - (0x4FF, 'V'), - (0x500, 'M', 'ԁ'), - (0x501, 'V'), - (0x502, 'M', 'ԃ'), + (0x49E, "M", "ҟ"), + (0x49F, "V"), + (0x4A0, "M", "Ņ”"), + (0x4A1, "V"), + (0x4A2, "M", "Ņ£"), + (0x4A3, "V"), + (0x4A4, "M", "Ņ„"), + (0x4A5, "V"), + (0x4A6, "M", "ҧ"), + (0x4A7, "V"), + (0x4A8, "M", "Ņ©"), + (0x4A9, "V"), + (0x4AA, "M", "Ņ«"), + (0x4AB, "V"), + (0x4AC, "M", "Ņ­"), + (0x4AD, "V"), + (0x4AE, "M", "ŅÆ"), + (0x4AF, "V"), + (0x4B0, "M", "ұ"), + (0x4B1, "V"), + (0x4B2, "M", "ҳ"), + (0x4B3, "V"), + (0x4B4, "M", "ҵ"), + (0x4B5, "V"), + (0x4B6, "M", "Ņ·"), + (0x4B7, "V"), + (0x4B8, "M", "ҹ"), + (0x4B9, "V"), + (0x4BA, "M", "Ņ»"), + (0x4BB, "V"), + (0x4BC, "M", "ҽ"), + (0x4BD, "V"), + (0x4BE, "M", "Ņæ"), + (0x4BF, "V"), + (0x4C0, "X"), + (0x4C1, "M", "ӂ"), + (0x4C2, "V"), + (0x4C3, "M", "ӄ"), + (0x4C4, "V"), + (0x4C5, "M", "ӆ"), + (0x4C6, "V"), + (0x4C7, "M", "ӈ"), + (0x4C8, "V"), + (0x4C9, "M", "ӊ"), + (0x4CA, "V"), + (0x4CB, "M", "ӌ"), + (0x4CC, "V"), + (0x4CD, "M", "ӎ"), + (0x4CE, "V"), + (0x4D0, "M", "ӑ"), + (0x4D1, "V"), + (0x4D2, "M", "ӓ"), + (0x4D3, "V"), + (0x4D4, "M", "ӕ"), + (0x4D5, "V"), + (0x4D6, "M", "ӗ"), + (0x4D7, "V"), + (0x4D8, "M", "ә"), + (0x4D9, "V"), + (0x4DA, "M", "ӛ"), + (0x4DB, "V"), + (0x4DC, "M", "ӝ"), + (0x4DD, "V"), + (0x4DE, "M", "ӟ"), + (0x4DF, "V"), + (0x4E0, "M", "Ó”"), + (0x4E1, "V"), + (0x4E2, "M", "Ó£"), + (0x4E3, "V"), + (0x4E4, "M", "Ó„"), + (0x4E5, "V"), + (0x4E6, "M", "Ó§"), + (0x4E7, "V"), + (0x4E8, "M", "Ó©"), + (0x4E9, "V"), + (0x4EA, "M", "Ó«"), + (0x4EB, "V"), + (0x4EC, "M", "Ó­"), + (0x4ED, "V"), + (0x4EE, "M", "ÓÆ"), + (0x4EF, "V"), + (0x4F0, "M", "Ó±"), + (0x4F1, "V"), + (0x4F2, "M", "Ó³"), + (0x4F3, "V"), + (0x4F4, "M", "Óµ"), + (0x4F5, "V"), + (0x4F6, "M", "Ó·"), + (0x4F7, "V"), + (0x4F8, "M", "Ó¹"), + (0x4F9, "V"), + (0x4FA, "M", "Ó»"), + (0x4FB, "V"), + (0x4FC, "M", "Ó½"), + (0x4FD, "V"), + (0x4FE, "M", "Óæ"), + (0x4FF, "V"), + (0x500, "M", "ԁ"), + (0x501, "V"), + (0x502, "M", "ԃ"), ] + def _seg_9() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x503, 'V'), - (0x504, 'M', 'Ō…'), - (0x505, 'V'), - (0x506, 'M', 'Ō‡'), - (0x507, 'V'), - (0x508, 'M', 'Ō‰'), - (0x509, 'V'), - (0x50A, 'M', 'Ō‹'), - (0x50B, 'V'), - (0x50C, 'M', 'Ō'), - (0x50D, 'V'), - (0x50E, 'M', 'Ō'), - (0x50F, 'V'), - (0x510, 'M', 'Ō‘'), - (0x511, 'V'), - (0x512, 'M', 'Ō“'), - (0x513, 'V'), - (0x514, 'M', 'Ō•'), - (0x515, 'V'), - (0x516, 'M', 'Ō—'), - (0x517, 'V'), - (0x518, 'M', 'Ō™'), - (0x519, 'V'), - (0x51A, 'M', 'Ō›'), - (0x51B, 'V'), - (0x51C, 'M', 'Ō'), - (0x51D, 'V'), - (0x51E, 'M', 'ԟ'), - (0x51F, 'V'), - (0x520, 'M', 'Ō”'), - (0x521, 'V'), - (0x522, 'M', 'Ō£'), - (0x523, 'V'), - (0x524, 'M', 'Ō„'), - (0x525, 'V'), - (0x526, 'M', 'Ō§'), - (0x527, 'V'), - (0x528, 'M', 'Ō©'), - (0x529, 'V'), - (0x52A, 'M', 'Ō«'), - (0x52B, 'V'), - (0x52C, 'M', 'Ō­'), - (0x52D, 'V'), - (0x52E, 'M', 'ŌÆ'), - (0x52F, 'V'), - (0x530, 'X'), - (0x531, 'M', 'Õ”'), - (0x532, 'M', 'Õ¢'), - (0x533, 'M', 'Õ£'), - (0x534, 'M', 'Õ¤'), - (0x535, 'M', 'Õ„'), - (0x536, 'M', 'Õ¦'), - (0x537, 'M', 'Õ§'), - (0x538, 'M', 'ÕØ'), - (0x539, 'M', 'Õ©'), - (0x53A, 'M', 'ÕŖ'), - (0x53B, 'M', 'Õ«'), - (0x53C, 'M', 'Õ¬'), - (0x53D, 'M', 'Õ­'), - (0x53E, 'M', 'Õ®'), - (0x53F, 'M', 'ÕÆ'), - (0x540, 'M', 'Õ°'), - (0x541, 'M', 'Õ±'), - (0x542, 'M', 'Õ²'), - (0x543, 'M', 'Õ³'), - (0x544, 'M', 'Õ“'), - (0x545, 'M', 'Õµ'), - (0x546, 'M', 'Õ¶'), - (0x547, 'M', 'Õ·'), - (0x548, 'M', 'Õø'), - (0x549, 'M', 'Õ¹'), - (0x54A, 'M', 'Õŗ'), - (0x54B, 'M', 'Õ»'), - (0x54C, 'M', 'Õ¼'), - (0x54D, 'M', 'Õ½'), - (0x54E, 'M', 'Õ¾'), - (0x54F, 'M', 'Õæ'), - (0x550, 'M', 'ր'), - (0x551, 'M', 'ց'), - (0x552, 'M', 'ւ'), - (0x553, 'M', 'փ'), - (0x554, 'M', 'ք'), - (0x555, 'M', 'օ'), - (0x556, 'M', 'ֆ'), - (0x557, 'X'), - (0x559, 'V'), - (0x587, 'M', 'Õ„Ö‚'), - (0x588, 'V'), - (0x58B, 'X'), - (0x58D, 'V'), - (0x590, 'X'), - (0x591, 'V'), - (0x5C8, 'X'), - (0x5D0, 'V'), - (0x5EB, 'X'), - (0x5EF, 'V'), - (0x5F5, 'X'), - (0x606, 'V'), - (0x61C, 'X'), - (0x61D, 'V'), + (0x503, "V"), + (0x504, "M", "Ō…"), + (0x505, "V"), + (0x506, "M", "Ō‡"), + (0x507, "V"), + (0x508, "M", "Ō‰"), + (0x509, "V"), + (0x50A, "M", "Ō‹"), + (0x50B, "V"), + (0x50C, "M", "Ō"), + (0x50D, "V"), + (0x50E, "M", "Ō"), + (0x50F, "V"), + (0x510, "M", "Ō‘"), + (0x511, "V"), + (0x512, "M", "Ō“"), + (0x513, "V"), + (0x514, "M", "Ō•"), + (0x515, "V"), + (0x516, "M", "Ō—"), + (0x517, "V"), + (0x518, "M", "Ō™"), + (0x519, "V"), + (0x51A, "M", "Ō›"), + (0x51B, "V"), + (0x51C, "M", "Ō"), + (0x51D, "V"), + (0x51E, "M", "ԟ"), + (0x51F, "V"), + (0x520, "M", "Ō”"), + (0x521, "V"), + (0x522, "M", "Ō£"), + (0x523, "V"), + (0x524, "M", "Ō„"), + (0x525, "V"), + (0x526, "M", "Ō§"), + (0x527, "V"), + (0x528, "M", "Ō©"), + (0x529, "V"), + (0x52A, "M", "Ō«"), + (0x52B, "V"), + (0x52C, "M", "Ō­"), + (0x52D, "V"), + (0x52E, "M", "ŌÆ"), + (0x52F, "V"), + (0x530, "X"), + (0x531, "M", "Õ”"), + (0x532, "M", "Õ¢"), + (0x533, "M", "Õ£"), + (0x534, "M", "Õ¤"), + (0x535, "M", "Õ„"), + (0x536, "M", "Õ¦"), + (0x537, "M", "Õ§"), + (0x538, "M", "ÕØ"), + (0x539, "M", "Õ©"), + (0x53A, "M", "ÕŖ"), + (0x53B, "M", "Õ«"), + (0x53C, "M", "Õ¬"), + (0x53D, "M", "Õ­"), + (0x53E, "M", "Õ®"), + (0x53F, "M", "ÕÆ"), + (0x540, "M", "Õ°"), + (0x541, "M", "Õ±"), + (0x542, "M", "Õ²"), + (0x543, "M", "Õ³"), + (0x544, "M", "Õ“"), + (0x545, "M", "Õµ"), + (0x546, "M", "Õ¶"), + (0x547, "M", "Õ·"), + (0x548, "M", "Õø"), + (0x549, "M", "Õ¹"), + (0x54A, "M", "Õŗ"), + (0x54B, "M", "Õ»"), + (0x54C, "M", "Õ¼"), + (0x54D, "M", "Õ½"), + (0x54E, "M", "Õ¾"), + (0x54F, "M", "Õæ"), + (0x550, "M", "ր"), + (0x551, "M", "ց"), + (0x552, "M", "ւ"), + (0x553, "M", "փ"), + (0x554, "M", "ք"), + (0x555, "M", "օ"), + (0x556, "M", "ֆ"), + (0x557, "X"), + (0x559, "V"), + (0x587, "M", "Õ„Ö‚"), + (0x588, "V"), + (0x58B, "X"), + (0x58D, "V"), + (0x590, "X"), + (0x591, "V"), + (0x5C8, "X"), + (0x5D0, "V"), + (0x5EB, "X"), + (0x5EF, "V"), + (0x5F5, "X"), + (0x606, "V"), + (0x61C, "X"), + (0x61D, "V"), ] + def _seg_10() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x675, 'M', 'Ų§Ł“'), - (0x676, 'M', 'وٓ'), - (0x677, 'M', 'ۇٓ'), - (0x678, 'M', 'يٓ'), - (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'), - (0x870, 'V'), - (0x88F, 'X'), - (0x898, 'V'), - (0x8E2, 'X'), - (0x8E3, 'V'), - (0x958, 'M', 'क़'), - (0x959, 'M', 'ख़'), - (0x95A, 'M', 'ग़'), - (0x95B, 'M', 'ज़'), - (0x95C, 'M', 'औ़'), - (0x95D, 'M', 'ढ़'), - (0x95E, 'M', 'फ़'), - (0x95F, 'M', 'य़'), - (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', 'ঔ়'), - (0x9DD, 'M', 'ঢ়'), - (0x9DE, 'X'), - (0x9DF, 'M', 'য়'), - (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', 'ਲ਼'), - (0xA34, 'X'), - (0xA35, 'V'), - (0xA36, 'M', 'ਸ਼'), - (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', 'ਖ਼'), - (0xA5A, 'M', 'ਗ਼'), - (0xA5B, 'M', 'ਜ਼'), - (0xA5C, 'V'), - (0xA5D, 'X'), + (0x675, "M", "Ų§Ł“"), + (0x676, "M", "وٓ"), + (0x677, "M", "ۇٓ"), + (0x678, "M", "يٓ"), + (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"), + (0x870, "V"), + (0x88F, "X"), + (0x898, "V"), + (0x8E2, "X"), + (0x8E3, "V"), + (0x958, "M", "क़"), + (0x959, "M", "ख़"), + (0x95A, "M", "ग़"), + (0x95B, "M", "ज़"), + (0x95C, "M", "औ़"), + (0x95D, "M", "ढ़"), + (0x95E, "M", "फ़"), + (0x95F, "M", "य़"), + (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", "ঔ়"), + (0x9DD, "M", "ঢ়"), + (0x9DE, "X"), + (0x9DF, "M", "য়"), + (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", "ਲ਼"), + (0xA34, "X"), + (0xA35, "V"), + (0xA36, "M", "ਸ਼"), + (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", "ਖ਼"), + (0xA5A, "M", "ਗ਼"), + (0xA5B, "M", "ਜ਼"), + (0xA5C, "V"), + (0xA5D, "X"), ] + def _seg_11() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xA5E, 'M', 'ਫ਼'), - (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', 'ଔ଼'), - (0xB5D, 'M', 'ଢ଼'), - (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'), - (0xC29, 'X'), - (0xC2A, 'V'), + (0xA5E, "M", "ਫ਼"), + (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", "ଔ଼"), + (0xB5D, "M", "ଢ଼"), + (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"), + (0xC29, "X"), + (0xC2A, "V"), ] + def _seg_12() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xC3A, 'X'), - (0xC3C, 'V'), - (0xC45, 'X'), - (0xC46, 'V'), - (0xC49, 'X'), - (0xC4A, 'V'), - (0xC4E, 'X'), - (0xC55, 'V'), - (0xC57, 'X'), - (0xC58, 'V'), - (0xC5B, 'X'), - (0xC5D, 'V'), - (0xC5E, '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'), - (0xCDD, 'V'), - (0xCDF, 'X'), - (0xCE0, 'V'), - (0xCE4, 'X'), - (0xCE6, 'V'), - (0xCF0, 'X'), - (0xCF1, 'V'), - (0xCF4, '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', 'ą¹ąø²'), - (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', 'ą»ąŗ²'), - (0xEB4, 'V'), + (0xC3A, "X"), + (0xC3C, "V"), + (0xC45, "X"), + (0xC46, "V"), + (0xC49, "X"), + (0xC4A, "V"), + (0xC4E, "X"), + (0xC55, "V"), + (0xC57, "X"), + (0xC58, "V"), + (0xC5B, "X"), + (0xC5D, "V"), + (0xC5E, "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"), + (0xCDD, "V"), + (0xCDF, "X"), + (0xCE0, "V"), + (0xCE4, "X"), + (0xCE6, "V"), + (0xCF0, "X"), + (0xCF1, "V"), + (0xCF4, "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", "ą¹ąø²"), + (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", "ą»ąŗ²"), + (0xEB4, "V"), ] + def _seg_13() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xEBE, 'X'), - (0xEC0, 'V'), - (0xEC5, 'X'), - (0xEC6, 'V'), - (0xEC7, 'X'), - (0xEC8, 'V'), - (0xECF, 'X'), - (0xED0, 'V'), - (0xEDA, 'X'), - (0xEDC, 'M', 'ąŗ«ąŗ™'), - (0xEDD, 'M', 'ąŗ«ąŗ”'), - (0xEDE, 'V'), - (0xEE0, 'X'), - (0xF00, 'V'), - (0xF0C, 'M', '་'), - (0xF0D, 'V'), - (0xF43, 'M', 'གྷ'), - (0xF44, 'V'), - (0xF48, 'X'), - (0xF49, 'V'), - (0xF4D, 'M', 'ཌྷ'), - (0xF4E, 'V'), - (0xF52, 'M', 'དྷ'), - (0xF53, 'V'), - (0xF57, 'M', 'ą½–ą¾·'), - (0xF58, 'V'), - (0xF5C, 'M', 'ཛྷ'), - (0xF5D, 'V'), - (0xF69, 'M', 'ཀྵ'), - (0xF6A, 'V'), - (0xF6D, 'X'), - (0xF71, 'V'), - (0xF73, 'M', 'ཱི'), - (0xF74, 'V'), - (0xF75, 'M', 'ཱན'), - (0xF76, 'M', 'ྲྀ'), - (0xF77, 'M', 'ྲཱྀ'), - (0xF78, 'M', 'ླྀ'), - (0xF79, 'M', 'ླཱྀ'), - (0xF7A, 'V'), - (0xF81, 'M', 'ཱྀ'), - (0xF82, 'V'), - (0xF93, 'M', 'ą¾’ą¾·'), - (0xF94, 'V'), - (0xF98, 'X'), - (0xF99, 'V'), - (0xF9D, 'M', 'ྜྷ'), - (0xF9E, 'V'), - (0xFA2, 'M', 'ྔྷ'), - (0xFA3, 'V'), - (0xFA7, 'M', 'ྦྷ'), - (0xFA8, 'V'), - (0xFAC, 'M', 'ྫྷ'), - (0xFAD, 'V'), - (0xFB9, 'M', 'ྐྵ'), - (0xFBA, 'V'), - (0xFBD, 'X'), - (0xFBE, 'V'), - (0xFCD, 'X'), - (0xFCE, 'V'), - (0xFDB, 'X'), - (0x1000, 'V'), - (0x10A0, 'X'), - (0x10C7, 'M', 'ā“§'), - (0x10C8, 'X'), - (0x10CD, 'M', 'ā“­'), - (0x10CE, 'X'), - (0x10D0, 'V'), - (0x10FC, 'M', 'ნ'), - (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'), + (0xEBE, "X"), + (0xEC0, "V"), + (0xEC5, "X"), + (0xEC6, "V"), + (0xEC7, "X"), + (0xEC8, "V"), + (0xECF, "X"), + (0xED0, "V"), + (0xEDA, "X"), + (0xEDC, "M", "ąŗ«ąŗ™"), + (0xEDD, "M", "ąŗ«ąŗ”"), + (0xEDE, "V"), + (0xEE0, "X"), + (0xF00, "V"), + (0xF0C, "M", "་"), + (0xF0D, "V"), + (0xF43, "M", "གྷ"), + (0xF44, "V"), + (0xF48, "X"), + (0xF49, "V"), + (0xF4D, "M", "ཌྷ"), + (0xF4E, "V"), + (0xF52, "M", "དྷ"), + (0xF53, "V"), + (0xF57, "M", "ą½–ą¾·"), + (0xF58, "V"), + (0xF5C, "M", "ཛྷ"), + (0xF5D, "V"), + (0xF69, "M", "ཀྵ"), + (0xF6A, "V"), + (0xF6D, "X"), + (0xF71, "V"), + (0xF73, "M", "ཱི"), + (0xF74, "V"), + (0xF75, "M", "ཱན"), + (0xF76, "M", "ྲྀ"), + (0xF77, "M", "ྲཱྀ"), + (0xF78, "M", "ླྀ"), + (0xF79, "M", "ླཱྀ"), + (0xF7A, "V"), + (0xF81, "M", "ཱྀ"), + (0xF82, "V"), + (0xF93, "M", "ą¾’ą¾·"), + (0xF94, "V"), + (0xF98, "X"), + (0xF99, "V"), + (0xF9D, "M", "ྜྷ"), + (0xF9E, "V"), + (0xFA2, "M", "ྔྷ"), + (0xFA3, "V"), + (0xFA7, "M", "ྦྷ"), + (0xFA8, "V"), + (0xFAC, "M", "ྫྷ"), + (0xFAD, "V"), + (0xFB9, "M", "ྐྵ"), + (0xFBA, "V"), + (0xFBD, "X"), + (0xFBE, "V"), + (0xFCD, "X"), + (0xFCE, "V"), + (0xFDB, "X"), + (0x1000, "V"), + (0x10A0, "X"), + (0x10C7, "M", "ā“§"), + (0x10C8, "X"), + (0x10CD, "M", "ā“­"), + (0x10CE, "X"), + (0x10D0, "V"), + (0x10FC, "M", "ნ"), + (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() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1316, 'X'), - (0x1318, 'V'), - (0x135B, 'X'), - (0x135D, 'V'), - (0x137D, 'X'), - (0x1380, 'V'), - (0x139A, 'X'), - (0x13A0, 'V'), - (0x13F6, 'X'), - (0x13F8, 'M', 'į°'), - (0x13F9, 'M', 'į±'), - (0x13FA, 'M', 'į²'), - (0x13FB, 'M', 'į³'), - (0x13FC, 'M', 'į“'), - (0x13FD, 'M', 'įµ'), - (0x13FE, 'X'), - (0x1400, 'V'), - (0x1680, 'X'), - (0x1681, 'V'), - (0x169D, 'X'), - (0x16A0, 'V'), - (0x16F9, 'X'), - (0x1700, 'V'), - (0x1716, 'X'), - (0x171F, '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'), - (0x180F, 'I'), - (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'), - (0x1ACF, 'X'), - (0x1B00, 'V'), - (0x1B4D, 'X'), - (0x1B50, 'V'), - (0x1B7F, 'X'), - (0x1B80, 'V'), - (0x1BF4, 'X'), - (0x1BFC, 'V'), - (0x1C38, 'X'), - (0x1C3B, 'V'), - (0x1C4A, 'X'), - (0x1C4D, 'V'), - (0x1C80, 'M', 'в'), + (0x1316, "X"), + (0x1318, "V"), + (0x135B, "X"), + (0x135D, "V"), + (0x137D, "X"), + (0x1380, "V"), + (0x139A, "X"), + (0x13A0, "V"), + (0x13F6, "X"), + (0x13F8, "M", "į°"), + (0x13F9, "M", "į±"), + (0x13FA, "M", "į²"), + (0x13FB, "M", "į³"), + (0x13FC, "M", "į“"), + (0x13FD, "M", "įµ"), + (0x13FE, "X"), + (0x1400, "V"), + (0x1680, "X"), + (0x1681, "V"), + (0x169D, "X"), + (0x16A0, "V"), + (0x16F9, "X"), + (0x1700, "V"), + (0x1716, "X"), + (0x171F, "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"), + (0x180F, "I"), + (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"), + (0x1ACF, "X"), + (0x1B00, "V"), + (0x1B4D, "X"), + (0x1B50, "V"), + (0x1B7F, "X"), + (0x1B80, "V"), + (0x1BF4, "X"), + (0x1BFC, "V"), + (0x1C38, "X"), + (0x1C3B, "V"), + (0x1C4A, "X"), + (0x1C4D, "V"), + (0x1C80, "M", "в"), ] + def _seg_15() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1C81, 'M', 'Š“'), - (0x1C82, 'M', 'о'), - (0x1C83, 'M', 'с'), - (0x1C84, 'M', 'т'), - (0x1C86, 'M', 'ъ'), - (0x1C87, 'M', 'Ń£'), - (0x1C88, 'M', 'ꙋ'), - (0x1C89, 'X'), - (0x1C90, 'M', 'ა'), - (0x1C91, 'M', 'įƒ‘'), - (0x1C92, 'M', 'įƒ’'), - (0x1C93, 'M', 'įƒ“'), - (0x1C94, 'M', 'įƒ”'), - (0x1C95, 'M', 'įƒ•'), - (0x1C96, 'M', 'įƒ–'), - (0x1C97, 'M', 'įƒ—'), - (0x1C98, 'M', 'ი'), - (0x1C99, 'M', 'įƒ™'), - (0x1C9A, 'M', 'ლ'), - (0x1C9B, 'M', 'įƒ›'), - (0x1C9C, 'M', 'ნ'), - (0x1C9D, 'M', 'įƒ'), - (0x1C9E, 'M', 'įƒž'), - (0x1C9F, 'M', 'ჟ'), - (0x1CA0, 'M', 'რ'), - (0x1CA1, 'M', 'ე'), - (0x1CA2, 'M', 'ტ'), - (0x1CA3, 'M', 'უ'), - (0x1CA4, 'M', 'ფ'), - (0x1CA5, 'M', 'Ⴤ'), - (0x1CA6, 'M', 'ღ'), - (0x1CA7, 'M', 'ყ'), - (0x1CA8, 'M', 'შ'), - (0x1CA9, 'M', 'ჩ'), - (0x1CAA, 'M', 'ც'), - (0x1CAB, 'M', 'ძ'), - (0x1CAC, 'M', 'წ'), - (0x1CAD, 'M', 'ჭ'), - (0x1CAE, 'M', 'ხ'), - (0x1CAF, 'M', 'ჯ'), - (0x1CB0, 'M', 'ჰ'), - (0x1CB1, 'M', 'ჱ'), - (0x1CB2, 'M', 'ჲ'), - (0x1CB3, 'M', 'ჳ'), - (0x1CB4, 'M', 'დ'), - (0x1CB5, 'M', 'ჵ'), - (0x1CB6, 'M', 'ჶ'), - (0x1CB7, 'M', 'ჷ'), - (0x1CB8, 'M', 'ჸ'), - (0x1CB9, 'M', 'ჹ'), - (0x1CBA, 'M', 'ჺ'), - (0x1CBB, 'X'), - (0x1CBD, 'M', 'ჽ'), - (0x1CBE, 'M', 'ჾ'), - (0x1CBF, 'M', 'ჿ'), - (0x1CC0, 'V'), - (0x1CC8, 'X'), - (0x1CD0, 'V'), - (0x1CFB, 'X'), - (0x1D00, 'V'), - (0x1D2C, 'M', 'a'), - (0x1D2D, 'M', 'Ʀ'), - (0x1D2E, 'M', 'b'), - (0x1D2F, 'V'), - (0x1D30, 'M', 'd'), - (0x1D31, 'M', 'e'), - (0x1D32, 'M', 'Ē'), - (0x1D33, 'M', 'g'), - (0x1D34, 'M', 'h'), - (0x1D35, 'M', 'i'), - (0x1D36, 'M', 'j'), - (0x1D37, 'M', 'k'), - (0x1D38, 'M', 'l'), - (0x1D39, 'M', 'm'), - (0x1D3A, 'M', 'n'), - (0x1D3B, 'V'), - (0x1D3C, 'M', 'o'), - (0x1D3D, 'M', 'Č£'), - (0x1D3E, 'M', 'p'), - (0x1D3F, 'M', 'r'), - (0x1D40, 'M', 't'), - (0x1D41, 'M', 'u'), - (0x1D42, 'M', 'w'), - (0x1D43, 'M', 'a'), - (0x1D44, 'M', 'ɐ'), - (0x1D45, 'M', 'ɑ'), - (0x1D46, 'M', 'į“‚'), - (0x1D47, 'M', 'b'), - (0x1D48, 'M', 'd'), - (0x1D49, 'M', 'e'), - (0x1D4A, 'M', 'ə'), - (0x1D4B, 'M', 'ɛ'), - (0x1D4C, 'M', 'ɜ'), - (0x1D4D, 'M', 'g'), - (0x1D4E, 'V'), - (0x1D4F, 'M', 'k'), - (0x1D50, 'M', 'm'), - (0x1D51, 'M', 'ŋ'), - (0x1D52, 'M', 'o'), - (0x1D53, 'M', 'ɔ'), + (0x1C81, "M", "Š“"), + (0x1C82, "M", "о"), + (0x1C83, "M", "с"), + (0x1C84, "M", "т"), + (0x1C86, "M", "ъ"), + (0x1C87, "M", "Ń£"), + (0x1C88, "M", "ꙋ"), + (0x1C89, "X"), + (0x1C90, "M", "ა"), + (0x1C91, "M", "įƒ‘"), + (0x1C92, "M", "įƒ’"), + (0x1C93, "M", "įƒ“"), + (0x1C94, "M", "įƒ”"), + (0x1C95, "M", "įƒ•"), + (0x1C96, "M", "įƒ–"), + (0x1C97, "M", "įƒ—"), + (0x1C98, "M", "ი"), + (0x1C99, "M", "įƒ™"), + (0x1C9A, "M", "ლ"), + (0x1C9B, "M", "įƒ›"), + (0x1C9C, "M", "ნ"), + (0x1C9D, "M", "įƒ"), + (0x1C9E, "M", "įƒž"), + (0x1C9F, "M", "ჟ"), + (0x1CA0, "M", "რ"), + (0x1CA1, "M", "ე"), + (0x1CA2, "M", "ტ"), + (0x1CA3, "M", "უ"), + (0x1CA4, "M", "ფ"), + (0x1CA5, "M", "Ⴤ"), + (0x1CA6, "M", "ღ"), + (0x1CA7, "M", "ყ"), + (0x1CA8, "M", "შ"), + (0x1CA9, "M", "ჩ"), + (0x1CAA, "M", "ც"), + (0x1CAB, "M", "ძ"), + (0x1CAC, "M", "წ"), + (0x1CAD, "M", "ჭ"), + (0x1CAE, "M", "ხ"), + (0x1CAF, "M", "ჯ"), + (0x1CB0, "M", "ჰ"), + (0x1CB1, "M", "ჱ"), + (0x1CB2, "M", "ჲ"), + (0x1CB3, "M", "ჳ"), + (0x1CB4, "M", "დ"), + (0x1CB5, "M", "ჵ"), + (0x1CB6, "M", "ჶ"), + (0x1CB7, "M", "ჷ"), + (0x1CB8, "M", "ჸ"), + (0x1CB9, "M", "ჹ"), + (0x1CBA, "M", "ჺ"), + (0x1CBB, "X"), + (0x1CBD, "M", "ჽ"), + (0x1CBE, "M", "ჾ"), + (0x1CBF, "M", "ჿ"), + (0x1CC0, "V"), + (0x1CC8, "X"), + (0x1CD0, "V"), + (0x1CFB, "X"), + (0x1D00, "V"), + (0x1D2C, "M", "a"), + (0x1D2D, "M", "Ʀ"), + (0x1D2E, "M", "b"), + (0x1D2F, "V"), + (0x1D30, "M", "d"), + (0x1D31, "M", "e"), + (0x1D32, "M", "Ē"), + (0x1D33, "M", "g"), + (0x1D34, "M", "h"), + (0x1D35, "M", "i"), + (0x1D36, "M", "j"), + (0x1D37, "M", "k"), + (0x1D38, "M", "l"), + (0x1D39, "M", "m"), + (0x1D3A, "M", "n"), + (0x1D3B, "V"), + (0x1D3C, "M", "o"), + (0x1D3D, "M", "Č£"), + (0x1D3E, "M", "p"), + (0x1D3F, "M", "r"), + (0x1D40, "M", "t"), + (0x1D41, "M", "u"), + (0x1D42, "M", "w"), + (0x1D43, "M", "a"), + (0x1D44, "M", "ɐ"), + (0x1D45, "M", "ɑ"), + (0x1D46, "M", "į“‚"), + (0x1D47, "M", "b"), + (0x1D48, "M", "d"), + (0x1D49, "M", "e"), + (0x1D4A, "M", "ə"), + (0x1D4B, "M", "ɛ"), + (0x1D4C, "M", "ɜ"), + (0x1D4D, "M", "g"), + (0x1D4E, "V"), + (0x1D4F, "M", "k"), + (0x1D50, "M", "m"), + (0x1D51, "M", "ŋ"), + (0x1D52, "M", "o"), + (0x1D53, "M", "ɔ"), ] + def _seg_16() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D54, 'M', 'į“–'), - (0x1D55, 'M', 'į“—'), - (0x1D56, 'M', 'p'), - (0x1D57, 'M', 't'), - (0x1D58, 'M', 'u'), - (0x1D59, 'M', 'į“'), - (0x1D5A, 'M', 'ÉÆ'), - (0x1D5B, 'M', 'v'), - (0x1D5C, 'M', 'į“„'), - (0x1D5D, 'M', 'β'), - (0x1D5E, 'M', 'γ'), - (0x1D5F, 'M', 'Ī“'), - (0x1D60, 'M', 'φ'), - (0x1D61, 'M', 'χ'), - (0x1D62, 'M', 'i'), - (0x1D63, 'M', 'r'), - (0x1D64, 'M', 'u'), - (0x1D65, 'M', 'v'), - (0x1D66, 'M', 'β'), - (0x1D67, 'M', 'γ'), - (0x1D68, 'M', 'ρ'), - (0x1D69, 'M', 'φ'), - (0x1D6A, 'M', 'χ'), - (0x1D6B, 'V'), - (0x1D78, 'M', 'н'), - (0x1D79, 'V'), - (0x1D9B, 'M', 'ɒ'), - (0x1D9C, 'M', 'c'), - (0x1D9D, 'M', 'ɕ'), - (0x1D9E, 'M', 'ư'), - (0x1D9F, 'M', 'ɜ'), - (0x1DA0, 'M', 'f'), - (0x1DA1, 'M', 'ɟ'), - (0x1DA2, 'M', 'É”'), - (0x1DA3, 'M', 'É„'), - (0x1DA4, 'M', 'ÉØ'), - (0x1DA5, 'M', 'É©'), - (0x1DA6, 'M', 'ÉŖ'), - (0x1DA7, 'M', 'įµ»'), - (0x1DA8, 'M', 'Ź'), - (0x1DA9, 'M', 'É­'), - (0x1DAA, 'M', 'į¶…'), - (0x1DAB, 'M', 'ʟ'), - (0x1DAC, 'M', 'ɱ'), - (0x1DAD, 'M', 'ɰ'), - (0x1DAE, 'M', 'ɲ'), - (0x1DAF, 'M', 'ɳ'), - (0x1DB0, 'M', 'É“'), - (0x1DB1, 'M', 'ɵ'), - (0x1DB2, 'M', 'Éø'), - (0x1DB3, 'M', 'Ź‚'), - (0x1DB4, 'M', 'ʃ'), - (0x1DB5, 'M', 'Ę«'), - (0x1DB6, 'M', 'ʉ'), - (0x1DB7, 'M', 'ʊ'), - (0x1DB8, 'M', 'ᓜ'), - (0x1DB9, 'M', 'Ź‹'), - (0x1DBA, 'M', 'ʌ'), - (0x1DBB, 'M', 'z'), - (0x1DBC, 'M', 'ʐ'), - (0x1DBD, 'M', 'Ź‘'), - (0x1DBE, 'M', 'Ź’'), - (0x1DBF, 'M', 'Īø'), - (0x1DC0, 'V'), - (0x1E00, 'M', 'ḁ'), - (0x1E01, 'V'), - (0x1E02, 'M', 'ḃ'), - (0x1E03, 'V'), - (0x1E04, 'M', 'įø…'), - (0x1E05, 'V'), - (0x1E06, 'M', 'įø‡'), - (0x1E07, 'V'), - (0x1E08, 'M', 'įø‰'), - (0x1E09, 'V'), - (0x1E0A, 'M', 'įø‹'), - (0x1E0B, 'V'), - (0x1E0C, 'M', 'įø'), - (0x1E0D, 'V'), - (0x1E0E, 'M', 'įø'), - (0x1E0F, 'V'), - (0x1E10, 'M', 'įø‘'), - (0x1E11, 'V'), - (0x1E12, 'M', 'įø“'), - (0x1E13, 'V'), - (0x1E14, 'M', 'įø•'), - (0x1E15, 'V'), - (0x1E16, 'M', 'įø—'), - (0x1E17, 'V'), - (0x1E18, 'M', 'įø™'), - (0x1E19, 'V'), - (0x1E1A, 'M', 'įø›'), - (0x1E1B, 'V'), - (0x1E1C, 'M', 'įø'), - (0x1E1D, 'V'), - (0x1E1E, 'M', 'ḟ'), - (0x1E1F, 'V'), - (0x1E20, 'M', 'įø”'), - (0x1E21, 'V'), - (0x1E22, 'M', 'įø£'), - (0x1E23, 'V'), + (0x1D54, "M", "į“–"), + (0x1D55, "M", "į“—"), + (0x1D56, "M", "p"), + (0x1D57, "M", "t"), + (0x1D58, "M", "u"), + (0x1D59, "M", "į“"), + (0x1D5A, "M", "ÉÆ"), + (0x1D5B, "M", "v"), + (0x1D5C, "M", "į“„"), + (0x1D5D, "M", "β"), + (0x1D5E, "M", "γ"), + (0x1D5F, "M", "Ī“"), + (0x1D60, "M", "φ"), + (0x1D61, "M", "χ"), + (0x1D62, "M", "i"), + (0x1D63, "M", "r"), + (0x1D64, "M", "u"), + (0x1D65, "M", "v"), + (0x1D66, "M", "β"), + (0x1D67, "M", "γ"), + (0x1D68, "M", "ρ"), + (0x1D69, "M", "φ"), + (0x1D6A, "M", "χ"), + (0x1D6B, "V"), + (0x1D78, "M", "н"), + (0x1D79, "V"), + (0x1D9B, "M", "ɒ"), + (0x1D9C, "M", "c"), + (0x1D9D, "M", "ɕ"), + (0x1D9E, "M", "ư"), + (0x1D9F, "M", "ɜ"), + (0x1DA0, "M", "f"), + (0x1DA1, "M", "ɟ"), + (0x1DA2, "M", "É”"), + (0x1DA3, "M", "É„"), + (0x1DA4, "M", "ÉØ"), + (0x1DA5, "M", "É©"), + (0x1DA6, "M", "ÉŖ"), + (0x1DA7, "M", "įµ»"), + (0x1DA8, "M", "Ź"), + (0x1DA9, "M", "É­"), + (0x1DAA, "M", "į¶…"), + (0x1DAB, "M", "ʟ"), + (0x1DAC, "M", "ɱ"), + (0x1DAD, "M", "ɰ"), + (0x1DAE, "M", "ɲ"), + (0x1DAF, "M", "ɳ"), + (0x1DB0, "M", "É“"), + (0x1DB1, "M", "ɵ"), + (0x1DB2, "M", "Éø"), + (0x1DB3, "M", "Ź‚"), + (0x1DB4, "M", "ʃ"), + (0x1DB5, "M", "Ę«"), + (0x1DB6, "M", "ʉ"), + (0x1DB7, "M", "ʊ"), + (0x1DB8, "M", "ᓜ"), + (0x1DB9, "M", "Ź‹"), + (0x1DBA, "M", "ʌ"), + (0x1DBB, "M", "z"), + (0x1DBC, "M", "ʐ"), + (0x1DBD, "M", "Ź‘"), + (0x1DBE, "M", "Ź’"), + (0x1DBF, "M", "Īø"), + (0x1DC0, "V"), + (0x1E00, "M", "ḁ"), + (0x1E01, "V"), + (0x1E02, "M", "ḃ"), + (0x1E03, "V"), + (0x1E04, "M", "įø…"), + (0x1E05, "V"), + (0x1E06, "M", "įø‡"), + (0x1E07, "V"), + (0x1E08, "M", "įø‰"), + (0x1E09, "V"), + (0x1E0A, "M", "įø‹"), + (0x1E0B, "V"), + (0x1E0C, "M", "įø"), + (0x1E0D, "V"), + (0x1E0E, "M", "įø"), + (0x1E0F, "V"), + (0x1E10, "M", "įø‘"), + (0x1E11, "V"), + (0x1E12, "M", "įø“"), + (0x1E13, "V"), + (0x1E14, "M", "įø•"), + (0x1E15, "V"), + (0x1E16, "M", "įø—"), + (0x1E17, "V"), + (0x1E18, "M", "įø™"), + (0x1E19, "V"), + (0x1E1A, "M", "įø›"), + (0x1E1B, "V"), + (0x1E1C, "M", "įø"), + (0x1E1D, "V"), + (0x1E1E, "M", "ḟ"), + (0x1E1F, "V"), + (0x1E20, "M", "įø”"), + (0x1E21, "V"), + (0x1E22, "M", "įø£"), + (0x1E23, "V"), ] + def _seg_17() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1E24, 'M', 'įø„'), - (0x1E25, 'V'), - (0x1E26, 'M', 'įø§'), - (0x1E27, 'V'), - (0x1E28, 'M', 'įø©'), - (0x1E29, 'V'), - (0x1E2A, 'M', 'įø«'), - (0x1E2B, 'V'), - (0x1E2C, 'M', 'įø­'), - (0x1E2D, 'V'), - (0x1E2E, 'M', 'įøÆ'), - (0x1E2F, 'V'), - (0x1E30, 'M', 'įø±'), - (0x1E31, 'V'), - (0x1E32, 'M', 'įø³'), - (0x1E33, 'V'), - (0x1E34, 'M', 'įøµ'), - (0x1E35, 'V'), - (0x1E36, 'M', 'įø·'), - (0x1E37, 'V'), - (0x1E38, 'M', 'įø¹'), - (0x1E39, 'V'), - (0x1E3A, 'M', 'įø»'), - (0x1E3B, 'V'), - (0x1E3C, 'M', 'įø½'), - (0x1E3D, 'V'), - (0x1E3E, 'M', 'įøæ'), - (0x1E3F, 'V'), - (0x1E40, 'M', 'ṁ'), - (0x1E41, 'V'), - (0x1E42, 'M', 'ṃ'), - (0x1E43, 'V'), - (0x1E44, 'M', 'į¹…'), - (0x1E45, 'V'), - (0x1E46, 'M', 'ṇ'), - (0x1E47, 'V'), - (0x1E48, 'M', 'ṉ'), - (0x1E49, 'V'), - (0x1E4A, 'M', 'ṋ'), - (0x1E4B, 'V'), - (0x1E4C, 'M', 'į¹'), - (0x1E4D, 'V'), - (0x1E4E, 'M', 'į¹'), - (0x1E4F, 'V'), - (0x1E50, 'M', 'ṑ'), - (0x1E51, 'V'), - (0x1E52, 'M', 'ṓ'), - (0x1E53, 'V'), - (0x1E54, 'M', 'ṕ'), - (0x1E55, 'V'), - (0x1E56, 'M', 'į¹—'), - (0x1E57, 'V'), - (0x1E58, 'M', 'į¹™'), - (0x1E59, 'V'), - (0x1E5A, 'M', 'į¹›'), - (0x1E5B, 'V'), - (0x1E5C, 'M', 'į¹'), - (0x1E5D, 'V'), - (0x1E5E, 'M', 'ṟ'), - (0x1E5F, 'V'), - (0x1E60, 'M', 'į¹”'), - (0x1E61, 'V'), - (0x1E62, 'M', 'į¹£'), - (0x1E63, 'V'), - (0x1E64, 'M', 'Ṅ'), - (0x1E65, 'V'), - (0x1E66, 'M', 'į¹§'), - (0x1E67, 'V'), - (0x1E68, 'M', 'ṩ'), - (0x1E69, 'V'), - (0x1E6A, 'M', 'ṫ'), - (0x1E6B, 'V'), - (0x1E6C, 'M', 'į¹­'), - (0x1E6D, 'V'), - (0x1E6E, 'M', 'ṯ'), - (0x1E6F, 'V'), - (0x1E70, 'M', 'į¹±'), - (0x1E71, 'V'), - (0x1E72, 'M', 'į¹³'), - (0x1E73, 'V'), - (0x1E74, 'M', 'į¹µ'), - (0x1E75, 'V'), - (0x1E76, 'M', 'į¹·'), - (0x1E77, 'V'), - (0x1E78, 'M', 'į¹¹'), - (0x1E79, 'V'), - (0x1E7A, 'M', 'į¹»'), - (0x1E7B, 'V'), - (0x1E7C, 'M', 'į¹½'), - (0x1E7D, 'V'), - (0x1E7E, 'M', 'ṿ'), - (0x1E7F, 'V'), - (0x1E80, 'M', 'ẁ'), - (0x1E81, 'V'), - (0x1E82, 'M', 'ẃ'), - (0x1E83, 'V'), - (0x1E84, 'M', 'įŗ…'), - (0x1E85, 'V'), - (0x1E86, 'M', 'įŗ‡'), - (0x1E87, 'V'), + (0x1E24, "M", "įø„"), + (0x1E25, "V"), + (0x1E26, "M", "įø§"), + (0x1E27, "V"), + (0x1E28, "M", "įø©"), + (0x1E29, "V"), + (0x1E2A, "M", "įø«"), + (0x1E2B, "V"), + (0x1E2C, "M", "įø­"), + (0x1E2D, "V"), + (0x1E2E, "M", "įøÆ"), + (0x1E2F, "V"), + (0x1E30, "M", "įø±"), + (0x1E31, "V"), + (0x1E32, "M", "įø³"), + (0x1E33, "V"), + (0x1E34, "M", "įøµ"), + (0x1E35, "V"), + (0x1E36, "M", "įø·"), + (0x1E37, "V"), + (0x1E38, "M", "įø¹"), + (0x1E39, "V"), + (0x1E3A, "M", "įø»"), + (0x1E3B, "V"), + (0x1E3C, "M", "įø½"), + (0x1E3D, "V"), + (0x1E3E, "M", "įøæ"), + (0x1E3F, "V"), + (0x1E40, "M", "ṁ"), + (0x1E41, "V"), + (0x1E42, "M", "ṃ"), + (0x1E43, "V"), + (0x1E44, "M", "į¹…"), + (0x1E45, "V"), + (0x1E46, "M", "ṇ"), + (0x1E47, "V"), + (0x1E48, "M", "ṉ"), + (0x1E49, "V"), + (0x1E4A, "M", "ṋ"), + (0x1E4B, "V"), + (0x1E4C, "M", "į¹"), + (0x1E4D, "V"), + (0x1E4E, "M", "į¹"), + (0x1E4F, "V"), + (0x1E50, "M", "ṑ"), + (0x1E51, "V"), + (0x1E52, "M", "ṓ"), + (0x1E53, "V"), + (0x1E54, "M", "ṕ"), + (0x1E55, "V"), + (0x1E56, "M", "į¹—"), + (0x1E57, "V"), + (0x1E58, "M", "į¹™"), + (0x1E59, "V"), + (0x1E5A, "M", "į¹›"), + (0x1E5B, "V"), + (0x1E5C, "M", "į¹"), + (0x1E5D, "V"), + (0x1E5E, "M", "ṟ"), + (0x1E5F, "V"), + (0x1E60, "M", "į¹”"), + (0x1E61, "V"), + (0x1E62, "M", "į¹£"), + (0x1E63, "V"), + (0x1E64, "M", "Ṅ"), + (0x1E65, "V"), + (0x1E66, "M", "į¹§"), + (0x1E67, "V"), + (0x1E68, "M", "ṩ"), + (0x1E69, "V"), + (0x1E6A, "M", "ṫ"), + (0x1E6B, "V"), + (0x1E6C, "M", "į¹­"), + (0x1E6D, "V"), + (0x1E6E, "M", "ṯ"), + (0x1E6F, "V"), + (0x1E70, "M", "į¹±"), + (0x1E71, "V"), + (0x1E72, "M", "į¹³"), + (0x1E73, "V"), + (0x1E74, "M", "į¹µ"), + (0x1E75, "V"), + (0x1E76, "M", "į¹·"), + (0x1E77, "V"), + (0x1E78, "M", "į¹¹"), + (0x1E79, "V"), + (0x1E7A, "M", "į¹»"), + (0x1E7B, "V"), + (0x1E7C, "M", "į¹½"), + (0x1E7D, "V"), + (0x1E7E, "M", "ṿ"), + (0x1E7F, "V"), + (0x1E80, "M", "ẁ"), + (0x1E81, "V"), + (0x1E82, "M", "ẃ"), + (0x1E83, "V"), + (0x1E84, "M", "įŗ…"), + (0x1E85, "V"), + (0x1E86, "M", "įŗ‡"), + (0x1E87, "V"), ] + def _seg_18() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1E88, 'M', 'įŗ‰'), - (0x1E89, 'V'), - (0x1E8A, 'M', 'įŗ‹'), - (0x1E8B, 'V'), - (0x1E8C, 'M', 'įŗ'), - (0x1E8D, 'V'), - (0x1E8E, 'M', 'įŗ'), - (0x1E8F, 'V'), - (0x1E90, 'M', 'įŗ‘'), - (0x1E91, 'V'), - (0x1E92, 'M', 'įŗ“'), - (0x1E93, 'V'), - (0x1E94, 'M', 'įŗ•'), - (0x1E95, 'V'), - (0x1E9A, 'M', 'aʾ'), - (0x1E9B, 'M', 'į¹”'), - (0x1E9C, 'V'), - (0x1E9E, 'M', 'ss'), - (0x1E9F, 'V'), - (0x1EA0, 'M', 'įŗ”'), - (0x1EA1, 'V'), - (0x1EA2, 'M', 'įŗ£'), - (0x1EA3, 'V'), - (0x1EA4, 'M', 'įŗ„'), - (0x1EA5, 'V'), - (0x1EA6, 'M', 'įŗ§'), - (0x1EA7, 'V'), - (0x1EA8, 'M', 'įŗ©'), - (0x1EA9, 'V'), - (0x1EAA, 'M', 'įŗ«'), - (0x1EAB, 'V'), - (0x1EAC, 'M', 'įŗ­'), - (0x1EAD, 'V'), - (0x1EAE, 'M', 'įŗÆ'), - (0x1EAF, 'V'), - (0x1EB0, 'M', 'įŗ±'), - (0x1EB1, 'V'), - (0x1EB2, 'M', 'įŗ³'), - (0x1EB3, 'V'), - (0x1EB4, 'M', 'įŗµ'), - (0x1EB5, 'V'), - (0x1EB6, 'M', 'įŗ·'), - (0x1EB7, 'V'), - (0x1EB8, 'M', 'įŗ¹'), - (0x1EB9, 'V'), - (0x1EBA, 'M', 'įŗ»'), - (0x1EBB, 'V'), - (0x1EBC, 'M', 'įŗ½'), - (0x1EBD, 'V'), - (0x1EBE, 'M', 'įŗæ'), - (0x1EBF, 'V'), - (0x1EC0, 'M', 'ề'), - (0x1EC1, 'V'), - (0x1EC2, 'M', 'ể'), - (0x1EC3, 'V'), - (0x1EC4, 'M', 'į»…'), - (0x1EC5, 'V'), - (0x1EC6, 'M', 'ệ'), - (0x1EC7, 'V'), - (0x1EC8, 'M', 'ỉ'), - (0x1EC9, 'V'), - (0x1ECA, 'M', 'ị'), - (0x1ECB, 'V'), - (0x1ECC, 'M', 'į»'), - (0x1ECD, 'V'), - (0x1ECE, 'M', 'į»'), - (0x1ECF, 'V'), - (0x1ED0, 'M', 'ố'), - (0x1ED1, 'V'), - (0x1ED2, 'M', 'ồ'), - (0x1ED3, 'V'), - (0x1ED4, 'M', 'ổ'), - (0x1ED5, 'V'), - (0x1ED6, 'M', 'į»—'), - (0x1ED7, 'V'), - (0x1ED8, 'M', 'į»™'), - (0x1ED9, 'V'), - (0x1EDA, 'M', 'į»›'), - (0x1EDB, 'V'), - (0x1EDC, 'M', 'į»'), - (0x1EDD, 'V'), - (0x1EDE, 'M', 'ở'), - (0x1EDF, 'V'), - (0x1EE0, 'M', 'į»”'), - (0x1EE1, 'V'), - (0x1EE2, 'M', 'ợ'), - (0x1EE3, 'V'), - (0x1EE4, 'M', 'Ễ'), - (0x1EE5, 'V'), - (0x1EE6, 'M', 'į»§'), - (0x1EE7, 'V'), - (0x1EE8, 'M', 'ứ'), - (0x1EE9, 'V'), - (0x1EEA, 'M', 'ừ'), - (0x1EEB, 'V'), - (0x1EEC, 'M', 'į»­'), - (0x1EED, 'V'), - (0x1EEE, 'M', 'ữ'), - (0x1EEF, 'V'), - (0x1EF0, 'M', 'į»±'), + (0x1E88, "M", "įŗ‰"), + (0x1E89, "V"), + (0x1E8A, "M", "įŗ‹"), + (0x1E8B, "V"), + (0x1E8C, "M", "įŗ"), + (0x1E8D, "V"), + (0x1E8E, "M", "įŗ"), + (0x1E8F, "V"), + (0x1E90, "M", "įŗ‘"), + (0x1E91, "V"), + (0x1E92, "M", "įŗ“"), + (0x1E93, "V"), + (0x1E94, "M", "įŗ•"), + (0x1E95, "V"), + (0x1E9A, "M", "aʾ"), + (0x1E9B, "M", "į¹”"), + (0x1E9C, "V"), + (0x1E9E, "M", "ß"), + (0x1E9F, "V"), + (0x1EA0, "M", "įŗ”"), + (0x1EA1, "V"), + (0x1EA2, "M", "įŗ£"), + (0x1EA3, "V"), + (0x1EA4, "M", "įŗ„"), + (0x1EA5, "V"), + (0x1EA6, "M", "įŗ§"), + (0x1EA7, "V"), + (0x1EA8, "M", "įŗ©"), + (0x1EA9, "V"), + (0x1EAA, "M", "įŗ«"), + (0x1EAB, "V"), + (0x1EAC, "M", "įŗ­"), + (0x1EAD, "V"), + (0x1EAE, "M", "įŗÆ"), + (0x1EAF, "V"), + (0x1EB0, "M", "įŗ±"), + (0x1EB1, "V"), + (0x1EB2, "M", "įŗ³"), + (0x1EB3, "V"), + (0x1EB4, "M", "įŗµ"), + (0x1EB5, "V"), + (0x1EB6, "M", "įŗ·"), + (0x1EB7, "V"), + (0x1EB8, "M", "įŗ¹"), + (0x1EB9, "V"), + (0x1EBA, "M", "įŗ»"), + (0x1EBB, "V"), + (0x1EBC, "M", "įŗ½"), + (0x1EBD, "V"), + (0x1EBE, "M", "įŗæ"), + (0x1EBF, "V"), + (0x1EC0, "M", "ề"), + (0x1EC1, "V"), + (0x1EC2, "M", "ể"), + (0x1EC3, "V"), + (0x1EC4, "M", "į»…"), + (0x1EC5, "V"), + (0x1EC6, "M", "ệ"), + (0x1EC7, "V"), + (0x1EC8, "M", "ỉ"), + (0x1EC9, "V"), + (0x1ECA, "M", "ị"), + (0x1ECB, "V"), + (0x1ECC, "M", "į»"), + (0x1ECD, "V"), + (0x1ECE, "M", "į»"), + (0x1ECF, "V"), + (0x1ED0, "M", "ố"), + (0x1ED1, "V"), + (0x1ED2, "M", "ồ"), + (0x1ED3, "V"), + (0x1ED4, "M", "ổ"), + (0x1ED5, "V"), + (0x1ED6, "M", "į»—"), + (0x1ED7, "V"), + (0x1ED8, "M", "į»™"), + (0x1ED9, "V"), + (0x1EDA, "M", "į»›"), + (0x1EDB, "V"), + (0x1EDC, "M", "į»"), + (0x1EDD, "V"), + (0x1EDE, "M", "ở"), + (0x1EDF, "V"), + (0x1EE0, "M", "į»”"), + (0x1EE1, "V"), + (0x1EE2, "M", "ợ"), + (0x1EE3, "V"), + (0x1EE4, "M", "Ễ"), + (0x1EE5, "V"), + (0x1EE6, "M", "į»§"), + (0x1EE7, "V"), + (0x1EE8, "M", "ứ"), + (0x1EE9, "V"), + (0x1EEA, "M", "ừ"), + (0x1EEB, "V"), + (0x1EEC, "M", "į»­"), + (0x1EED, "V"), + (0x1EEE, "M", "ữ"), + (0x1EEF, "V"), + (0x1EF0, "M", "į»±"), ] + def _seg_19() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1EF1, 'V'), - (0x1EF2, 'M', 'ỳ'), - (0x1EF3, 'V'), - (0x1EF4, 'M', 'ỵ'), - (0x1EF5, 'V'), - (0x1EF6, 'M', 'į»·'), - (0x1EF7, 'V'), - (0x1EF8, 'M', 'ỹ'), - (0x1EF9, 'V'), - (0x1EFA, 'M', 'į»»'), - (0x1EFB, 'V'), - (0x1EFC, 'M', 'ỽ'), - (0x1EFD, 'V'), - (0x1EFE, 'M', 'ỿ'), - (0x1EFF, 'V'), - (0x1F08, 'M', 'į¼€'), - (0x1F09, 'M', 'ἁ'), - (0x1F0A, 'M', 'ἂ'), - (0x1F0B, 'M', 'ἃ'), - (0x1F0C, 'M', 'ἄ'), - (0x1F0D, 'M', 'į¼…'), - (0x1F0E, 'M', 'ἆ'), - (0x1F0F, 'M', 'ἇ'), - (0x1F10, 'V'), - (0x1F16, 'X'), - (0x1F18, 'M', 'ἐ'), - (0x1F19, 'M', 'ἑ'), - (0x1F1A, 'M', 'į¼’'), - (0x1F1B, 'M', 'ἓ'), - (0x1F1C, 'M', 'į¼”'), - (0x1F1D, 'M', 'ἕ'), - (0x1F1E, 'X'), - (0x1F20, 'V'), - (0x1F28, 'M', 'į¼ '), - (0x1F29, 'M', 'į¼”'), - (0x1F2A, 'M', 'į¼¢'), - (0x1F2B, 'M', 'į¼£'), - (0x1F2C, 'M', 'ἤ'), - (0x1F2D, 'M', 'ἄ'), - (0x1F2E, 'M', 'ἦ'), - (0x1F2F, 'M', 'į¼§'), - (0x1F30, 'V'), - (0x1F38, 'M', 'į¼°'), - (0x1F39, 'M', 'į¼±'), - (0x1F3A, 'M', 'į¼²'), - (0x1F3B, 'M', 'į¼³'), - (0x1F3C, 'M', 'ἓ'), - (0x1F3D, 'M', 'į¼µ'), - (0x1F3E, 'M', 'į¼¶'), - (0x1F3F, 'M', 'į¼·'), - (0x1F40, 'V'), - (0x1F46, 'X'), - (0x1F48, 'M', 'į½€'), - (0x1F49, 'M', 'ὁ'), - (0x1F4A, 'M', 'ὂ'), - (0x1F4B, 'M', 'ὃ'), - (0x1F4C, 'M', 'ὄ'), - (0x1F4D, 'M', 'į½…'), - (0x1F4E, 'X'), - (0x1F50, 'V'), - (0x1F58, 'X'), - (0x1F59, 'M', 'ὑ'), - (0x1F5A, 'X'), - (0x1F5B, 'M', 'ὓ'), - (0x1F5C, 'X'), - (0x1F5D, 'M', 'ὕ'), - (0x1F5E, 'X'), - (0x1F5F, 'M', 'į½—'), - (0x1F60, 'V'), - (0x1F68, 'M', 'į½ '), - (0x1F69, 'M', 'į½”'), - (0x1F6A, 'M', 'į½¢'), - (0x1F6B, 'M', 'į½£'), - (0x1F6C, 'M', 'ὤ'), - (0x1F6D, 'M', 'ὄ'), - (0x1F6E, 'M', 'ὦ'), - (0x1F6F, 'M', 'į½§'), - (0x1F70, 'V'), - (0x1F71, 'M', 'ά'), - (0x1F72, 'V'), - (0x1F73, 'M', 'Ī­'), - (0x1F74, 'V'), - (0x1F75, 'M', 'Ī®'), - (0x1F76, 'V'), - (0x1F77, 'M', 'ĪÆ'), - (0x1F78, 'V'), - (0x1F79, 'M', 'ό'), - (0x1F7A, 'V'), - (0x1F7B, 'M', 'Ļ'), - (0x1F7C, 'V'), - (0x1F7D, 'M', 'ĻŽ'), - (0x1F7E, 'X'), - (0x1F80, 'M', 'ἀι'), - (0x1F81, 'M', 'ἁι'), - (0x1F82, 'M', 'ἂι'), - (0x1F83, 'M', 'ἃι'), - (0x1F84, 'M', 'ἄι'), - (0x1F85, 'M', 'ἅι'), - (0x1F86, 'M', 'ἆι'), - (0x1F87, 'M', 'ἇι'), + (0x1EF1, "V"), + (0x1EF2, "M", "ỳ"), + (0x1EF3, "V"), + (0x1EF4, "M", "ỵ"), + (0x1EF5, "V"), + (0x1EF6, "M", "į»·"), + (0x1EF7, "V"), + (0x1EF8, "M", "ỹ"), + (0x1EF9, "V"), + (0x1EFA, "M", "į»»"), + (0x1EFB, "V"), + (0x1EFC, "M", "ỽ"), + (0x1EFD, "V"), + (0x1EFE, "M", "ỿ"), + (0x1EFF, "V"), + (0x1F08, "M", "į¼€"), + (0x1F09, "M", "ἁ"), + (0x1F0A, "M", "ἂ"), + (0x1F0B, "M", "ἃ"), + (0x1F0C, "M", "ἄ"), + (0x1F0D, "M", "į¼…"), + (0x1F0E, "M", "ἆ"), + (0x1F0F, "M", "ἇ"), + (0x1F10, "V"), + (0x1F16, "X"), + (0x1F18, "M", "ἐ"), + (0x1F19, "M", "ἑ"), + (0x1F1A, "M", "į¼’"), + (0x1F1B, "M", "ἓ"), + (0x1F1C, "M", "į¼”"), + (0x1F1D, "M", "ἕ"), + (0x1F1E, "X"), + (0x1F20, "V"), + (0x1F28, "M", "į¼ "), + (0x1F29, "M", "į¼”"), + (0x1F2A, "M", "į¼¢"), + (0x1F2B, "M", "į¼£"), + (0x1F2C, "M", "ἤ"), + (0x1F2D, "M", "ἄ"), + (0x1F2E, "M", "ἦ"), + (0x1F2F, "M", "į¼§"), + (0x1F30, "V"), + (0x1F38, "M", "į¼°"), + (0x1F39, "M", "į¼±"), + (0x1F3A, "M", "į¼²"), + (0x1F3B, "M", "į¼³"), + (0x1F3C, "M", "ἓ"), + (0x1F3D, "M", "į¼µ"), + (0x1F3E, "M", "į¼¶"), + (0x1F3F, "M", "į¼·"), + (0x1F40, "V"), + (0x1F46, "X"), + (0x1F48, "M", "į½€"), + (0x1F49, "M", "ὁ"), + (0x1F4A, "M", "ὂ"), + (0x1F4B, "M", "ὃ"), + (0x1F4C, "M", "ὄ"), + (0x1F4D, "M", "į½…"), + (0x1F4E, "X"), + (0x1F50, "V"), + (0x1F58, "X"), + (0x1F59, "M", "ὑ"), + (0x1F5A, "X"), + (0x1F5B, "M", "ὓ"), + (0x1F5C, "X"), + (0x1F5D, "M", "ὕ"), + (0x1F5E, "X"), + (0x1F5F, "M", "į½—"), + (0x1F60, "V"), + (0x1F68, "M", "į½ "), + (0x1F69, "M", "į½”"), + (0x1F6A, "M", "į½¢"), + (0x1F6B, "M", "į½£"), + (0x1F6C, "M", "ὤ"), + (0x1F6D, "M", "ὄ"), + (0x1F6E, "M", "ὦ"), + (0x1F6F, "M", "į½§"), + (0x1F70, "V"), + (0x1F71, "M", "ά"), + (0x1F72, "V"), + (0x1F73, "M", "Ī­"), + (0x1F74, "V"), + (0x1F75, "M", "Ī®"), + (0x1F76, "V"), + (0x1F77, "M", "ĪÆ"), + (0x1F78, "V"), + (0x1F79, "M", "ό"), + (0x1F7A, "V"), + (0x1F7B, "M", "Ļ"), + (0x1F7C, "V"), + (0x1F7D, "M", "ĻŽ"), + (0x1F7E, "X"), + (0x1F80, "M", "ἀι"), + (0x1F81, "M", "ἁι"), + (0x1F82, "M", "ἂι"), + (0x1F83, "M", "ἃι"), + (0x1F84, "M", "ἄι"), + (0x1F85, "M", "ἅι"), + (0x1F86, "M", "ἆι"), + (0x1F87, "M", "ἇι"), ] + def _seg_20() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1F88, 'M', 'ἀι'), - (0x1F89, 'M', 'ἁι'), - (0x1F8A, 'M', 'ἂι'), - (0x1F8B, 'M', 'ἃι'), - (0x1F8C, 'M', 'ἄι'), - (0x1F8D, 'M', 'ἅι'), - (0x1F8E, 'M', 'ἆι'), - (0x1F8F, 'M', 'ἇι'), - (0x1F90, 'M', 'ἠι'), - (0x1F91, 'M', 'ἔι'), - (0x1F92, 'M', 'ἢι'), - (0x1F93, 'M', 'ἣι'), - (0x1F94, 'M', 'ἤι'), - (0x1F95, 'M', 'ἄι'), - (0x1F96, 'M', 'ἦι'), - (0x1F97, 'M', 'ἧι'), - (0x1F98, 'M', 'ἠι'), - (0x1F99, 'M', 'ἔι'), - (0x1F9A, 'M', 'ἢι'), - (0x1F9B, 'M', 'ἣι'), - (0x1F9C, 'M', 'ἤι'), - (0x1F9D, 'M', 'ἄι'), - (0x1F9E, 'M', 'ἦι'), - (0x1F9F, 'M', 'ἧι'), - (0x1FA0, 'M', 'ὠι'), - (0x1FA1, 'M', 'ὔι'), - (0x1FA2, 'M', 'ὢι'), - (0x1FA3, 'M', 'ὣι'), - (0x1FA4, 'M', 'ὤι'), - (0x1FA5, 'M', 'ὄι'), - (0x1FA6, 'M', 'ὦι'), - (0x1FA7, 'M', 'ὧι'), - (0x1FA8, 'M', 'ὠι'), - (0x1FA9, 'M', 'ὔι'), - (0x1FAA, 'M', 'ὢι'), - (0x1FAB, 'M', 'ὣι'), - (0x1FAC, 'M', 'ὤι'), - (0x1FAD, 'M', 'ὄι'), - (0x1FAE, 'M', 'ὦι'), - (0x1FAF, 'M', 'ὧι'), - (0x1FB0, 'V'), - (0x1FB2, 'M', 'ὰι'), - (0x1FB3, 'M', 'αι'), - (0x1FB4, 'M', 'άι'), - (0x1FB5, 'X'), - (0x1FB6, 'V'), - (0x1FB7, 'M', 'ᾶι'), - (0x1FB8, 'M', 'į¾°'), - (0x1FB9, 'M', 'į¾±'), - (0x1FBA, 'M', 'į½°'), - (0x1FBB, 'M', 'ά'), - (0x1FBC, 'M', 'αι'), - (0x1FBD, '3', ' Ģ“'), - (0x1FBE, 'M', 'ι'), - (0x1FBF, '3', ' Ģ“'), - (0x1FC0, '3', ' Ķ‚'), - (0x1FC1, '3', ' ĢˆĶ‚'), - (0x1FC2, 'M', 'ὓι'), - (0x1FC3, 'M', 'ηι'), - (0x1FC4, 'M', 'ήι'), - (0x1FC5, 'X'), - (0x1FC6, 'V'), - (0x1FC7, 'M', 'ῆι'), - (0x1FC8, 'M', 'į½²'), - (0x1FC9, 'M', 'Ī­'), - (0x1FCA, 'M', 'ὓ'), - (0x1FCB, 'M', 'Ī®'), - (0x1FCC, 'M', 'ηι'), - (0x1FCD, '3', ' ̓̀'), - (0x1FCE, '3', ' ̓́'), - (0x1FCF, '3', ' ̓͂'), - (0x1FD0, 'V'), - (0x1FD3, 'M', 'ΐ'), - (0x1FD4, 'X'), - (0x1FD6, 'V'), - (0x1FD8, 'M', 'ῐ'), - (0x1FD9, 'M', 'įæ‘'), - (0x1FDA, 'M', 'į½¶'), - (0x1FDB, 'M', 'ĪÆ'), - (0x1FDC, 'X'), - (0x1FDD, '3', ' ̔̀'), - (0x1FDE, '3', ' ̔́'), - (0x1FDF, '3', ' ̔͂'), - (0x1FE0, 'V'), - (0x1FE3, 'M', 'ΰ'), - (0x1FE4, 'V'), - (0x1FE8, 'M', 'įæ '), - (0x1FE9, 'M', 'įæ”'), - (0x1FEA, 'M', 'į½ŗ'), - (0x1FEB, 'M', 'Ļ'), - (0x1FEC, 'M', 'įæ„'), - (0x1FED, '3', ' ĢˆĢ€'), - (0x1FEE, '3', ' ̈́'), - (0x1FEF, '3', '`'), - (0x1FF0, 'X'), - (0x1FF2, 'M', 'ὼι'), - (0x1FF3, 'M', 'ωι'), - (0x1FF4, 'M', 'ĻŽĪ¹'), - (0x1FF5, 'X'), - (0x1FF6, 'V'), + (0x1F88, "M", "ἀι"), + (0x1F89, "M", "ἁι"), + (0x1F8A, "M", "ἂι"), + (0x1F8B, "M", "ἃι"), + (0x1F8C, "M", "ἄι"), + (0x1F8D, "M", "ἅι"), + (0x1F8E, "M", "ἆι"), + (0x1F8F, "M", "ἇι"), + (0x1F90, "M", "ἠι"), + (0x1F91, "M", "ἔι"), + (0x1F92, "M", "ἢι"), + (0x1F93, "M", "ἣι"), + (0x1F94, "M", "ἤι"), + (0x1F95, "M", "ἄι"), + (0x1F96, "M", "ἦι"), + (0x1F97, "M", "ἧι"), + (0x1F98, "M", "ἠι"), + (0x1F99, "M", "ἔι"), + (0x1F9A, "M", "ἢι"), + (0x1F9B, "M", "ἣι"), + (0x1F9C, "M", "ἤι"), + (0x1F9D, "M", "ἄι"), + (0x1F9E, "M", "ἦι"), + (0x1F9F, "M", "ἧι"), + (0x1FA0, "M", "ὠι"), + (0x1FA1, "M", "ὔι"), + (0x1FA2, "M", "ὢι"), + (0x1FA3, "M", "ὣι"), + (0x1FA4, "M", "ὤι"), + (0x1FA5, "M", "ὄι"), + (0x1FA6, "M", "ὦι"), + (0x1FA7, "M", "ὧι"), + (0x1FA8, "M", "ὠι"), + (0x1FA9, "M", "ὔι"), + (0x1FAA, "M", "ὢι"), + (0x1FAB, "M", "ὣι"), + (0x1FAC, "M", "ὤι"), + (0x1FAD, "M", "ὄι"), + (0x1FAE, "M", "ὦι"), + (0x1FAF, "M", "ὧι"), + (0x1FB0, "V"), + (0x1FB2, "M", "ὰι"), + (0x1FB3, "M", "αι"), + (0x1FB4, "M", "άι"), + (0x1FB5, "X"), + (0x1FB6, "V"), + (0x1FB7, "M", "ᾶι"), + (0x1FB8, "M", "į¾°"), + (0x1FB9, "M", "į¾±"), + (0x1FBA, "M", "į½°"), + (0x1FBB, "M", "ά"), + (0x1FBC, "M", "αι"), + (0x1FBD, "3", " Ģ“"), + (0x1FBE, "M", "ι"), + (0x1FBF, "3", " Ģ“"), + (0x1FC0, "3", " Ķ‚"), + (0x1FC1, "3", " ĢˆĶ‚"), + (0x1FC2, "M", "ὓι"), + (0x1FC3, "M", "ηι"), + (0x1FC4, "M", "ήι"), + (0x1FC5, "X"), + (0x1FC6, "V"), + (0x1FC7, "M", "ῆι"), + (0x1FC8, "M", "į½²"), + (0x1FC9, "M", "Ī­"), + (0x1FCA, "M", "ὓ"), + (0x1FCB, "M", "Ī®"), + (0x1FCC, "M", "ηι"), + (0x1FCD, "3", " ̓̀"), + (0x1FCE, "3", " ̓́"), + (0x1FCF, "3", " ̓͂"), + (0x1FD0, "V"), + (0x1FD3, "M", "ΐ"), + (0x1FD4, "X"), + (0x1FD6, "V"), + (0x1FD8, "M", "ῐ"), + (0x1FD9, "M", "įæ‘"), + (0x1FDA, "M", "į½¶"), + (0x1FDB, "M", "ĪÆ"), + (0x1FDC, "X"), + (0x1FDD, "3", " ̔̀"), + (0x1FDE, "3", " ̔́"), + (0x1FDF, "3", " ̔͂"), + (0x1FE0, "V"), + (0x1FE3, "M", "ΰ"), + (0x1FE4, "V"), + (0x1FE8, "M", "įæ "), + (0x1FE9, "M", "įæ”"), + (0x1FEA, "M", "į½ŗ"), + (0x1FEB, "M", "Ļ"), + (0x1FEC, "M", "įæ„"), + (0x1FED, "3", " ĢˆĢ€"), + (0x1FEE, "3", " ̈́"), + (0x1FEF, "3", "`"), + (0x1FF0, "X"), + (0x1FF2, "M", "ὼι"), + (0x1FF3, "M", "ωι"), + (0x1FF4, "M", "ĻŽĪ¹"), + (0x1FF5, "X"), + (0x1FF6, "V"), ] + def _seg_21() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1FF7, 'M', 'ῶι'), - (0x1FF8, 'M', 'į½ø'), - (0x1FF9, 'M', 'ό'), - (0x1FFA, 'M', 'į½¼'), - (0x1FFB, 'M', 'ĻŽ'), - (0x1FFC, 'M', 'ωι'), - (0x1FFD, '3', ' ́'), - (0x1FFE, '3', ' Ģ”'), - (0x1FFF, 'X'), - (0x2000, '3', ' '), - (0x200B, 'I'), - (0x200C, 'D', ''), - (0x200E, 'X'), - (0x2010, 'V'), - (0x2011, 'M', '‐'), - (0x2012, 'V'), - (0x2017, '3', ' ̳'), - (0x2018, 'V'), - (0x2024, 'X'), - (0x2027, 'V'), - (0x2028, 'X'), - (0x202F, '3', ' '), - (0x2030, 'V'), - (0x2033, 'M', '′′'), - (0x2034, 'M', '′′′'), - (0x2035, 'V'), - (0x2036, 'M', '‵‵'), - (0x2037, 'M', '‵‵‵'), - (0x2038, 'V'), - (0x203C, '3', '!!'), - (0x203D, 'V'), - (0x203E, '3', ' Ģ…'), - (0x203F, 'V'), - (0x2047, '3', '??'), - (0x2048, '3', '?!'), - (0x2049, '3', '!?'), - (0x204A, 'V'), - (0x2057, 'M', '′′′′'), - (0x2058, 'V'), - (0x205F, '3', ' '), - (0x2060, 'I'), - (0x2061, 'X'), - (0x2064, 'I'), - (0x2065, 'X'), - (0x2070, 'M', '0'), - (0x2071, 'M', 'i'), - (0x2072, 'X'), - (0x2074, 'M', '4'), - (0x2075, 'M', '5'), - (0x2076, 'M', '6'), - (0x2077, 'M', '7'), - (0x2078, 'M', '8'), - (0x2079, 'M', '9'), - (0x207A, '3', '+'), - (0x207B, 'M', 'āˆ’'), - (0x207C, '3', '='), - (0x207D, '3', '('), - (0x207E, '3', ')'), - (0x207F, 'M', 'n'), - (0x2080, 'M', '0'), - (0x2081, 'M', '1'), - (0x2082, 'M', '2'), - (0x2083, 'M', '3'), - (0x2084, 'M', '4'), - (0x2085, 'M', '5'), - (0x2086, 'M', '6'), - (0x2087, 'M', '7'), - (0x2088, 'M', '8'), - (0x2089, 'M', '9'), - (0x208A, '3', '+'), - (0x208B, 'M', 'āˆ’'), - (0x208C, '3', '='), - (0x208D, '3', '('), - (0x208E, '3', ')'), - (0x208F, 'X'), - (0x2090, 'M', 'a'), - (0x2091, 'M', 'e'), - (0x2092, 'M', 'o'), - (0x2093, 'M', 'x'), - (0x2094, 'M', 'ə'), - (0x2095, 'M', 'h'), - (0x2096, 'M', 'k'), - (0x2097, 'M', 'l'), - (0x2098, 'M', 'm'), - (0x2099, 'M', 'n'), - (0x209A, 'M', 'p'), - (0x209B, 'M', 's'), - (0x209C, 'M', 't'), - (0x209D, 'X'), - (0x20A0, 'V'), - (0x20A8, 'M', 'rs'), - (0x20A9, 'V'), - (0x20C1, 'X'), - (0x20D0, 'V'), - (0x20F1, 'X'), - (0x2100, '3', 'a/c'), - (0x2101, '3', 'a/s'), - (0x2102, 'M', 'c'), - (0x2103, 'M', '°c'), - (0x2104, 'V'), + (0x1FF7, "M", "ῶι"), + (0x1FF8, "M", "į½ø"), + (0x1FF9, "M", "ό"), + (0x1FFA, "M", "į½¼"), + (0x1FFB, "M", "ĻŽ"), + (0x1FFC, "M", "ωι"), + (0x1FFD, "3", " ́"), + (0x1FFE, "3", " Ģ”"), + (0x1FFF, "X"), + (0x2000, "3", " "), + (0x200B, "I"), + (0x200C, "D", ""), + (0x200E, "X"), + (0x2010, "V"), + (0x2011, "M", "‐"), + (0x2012, "V"), + (0x2017, "3", " ̳"), + (0x2018, "V"), + (0x2024, "X"), + (0x2027, "V"), + (0x2028, "X"), + (0x202F, "3", " "), + (0x2030, "V"), + (0x2033, "M", "′′"), + (0x2034, "M", "′′′"), + (0x2035, "V"), + (0x2036, "M", "‵‵"), + (0x2037, "M", "‵‵‵"), + (0x2038, "V"), + (0x203C, "3", "!!"), + (0x203D, "V"), + (0x203E, "3", " Ģ…"), + (0x203F, "V"), + (0x2047, "3", "??"), + (0x2048, "3", "?!"), + (0x2049, "3", "!?"), + (0x204A, "V"), + (0x2057, "M", "′′′′"), + (0x2058, "V"), + (0x205F, "3", " "), + (0x2060, "I"), + (0x2061, "X"), + (0x2064, "I"), + (0x2065, "X"), + (0x2070, "M", "0"), + (0x2071, "M", "i"), + (0x2072, "X"), + (0x2074, "M", "4"), + (0x2075, "M", "5"), + (0x2076, "M", "6"), + (0x2077, "M", "7"), + (0x2078, "M", "8"), + (0x2079, "M", "9"), + (0x207A, "3", "+"), + (0x207B, "M", "āˆ’"), + (0x207C, "3", "="), + (0x207D, "3", "("), + (0x207E, "3", ")"), + (0x207F, "M", "n"), + (0x2080, "M", "0"), + (0x2081, "M", "1"), + (0x2082, "M", "2"), + (0x2083, "M", "3"), + (0x2084, "M", "4"), + (0x2085, "M", "5"), + (0x2086, "M", "6"), + (0x2087, "M", "7"), + (0x2088, "M", "8"), + (0x2089, "M", "9"), + (0x208A, "3", "+"), + (0x208B, "M", "āˆ’"), + (0x208C, "3", "="), + (0x208D, "3", "("), + (0x208E, "3", ")"), + (0x208F, "X"), + (0x2090, "M", "a"), + (0x2091, "M", "e"), + (0x2092, "M", "o"), + (0x2093, "M", "x"), + (0x2094, "M", "ə"), + (0x2095, "M", "h"), + (0x2096, "M", "k"), + (0x2097, "M", "l"), + (0x2098, "M", "m"), + (0x2099, "M", "n"), + (0x209A, "M", "p"), + (0x209B, "M", "s"), + (0x209C, "M", "t"), + (0x209D, "X"), + (0x20A0, "V"), + (0x20A8, "M", "rs"), + (0x20A9, "V"), + (0x20C1, "X"), + (0x20D0, "V"), + (0x20F1, "X"), + (0x2100, "3", "a/c"), + (0x2101, "3", "a/s"), + (0x2102, "M", "c"), + (0x2103, "M", "°c"), + (0x2104, "V"), ] + def _seg_22() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2105, '3', 'c/o'), - (0x2106, '3', 'c/u'), - (0x2107, 'M', 'ɛ'), - (0x2108, 'V'), - (0x2109, 'M', '°f'), - (0x210A, 'M', 'g'), - (0x210B, 'M', 'h'), - (0x210F, 'M', 'ħ'), - (0x2110, 'M', 'i'), - (0x2112, 'M', 'l'), - (0x2114, 'V'), - (0x2115, 'M', 'n'), - (0x2116, 'M', 'no'), - (0x2117, 'V'), - (0x2119, 'M', 'p'), - (0x211A, 'M', 'q'), - (0x211B, 'M', 'r'), - (0x211E, 'V'), - (0x2120, 'M', 'sm'), - (0x2121, 'M', 'tel'), - (0x2122, 'M', 'tm'), - (0x2123, 'V'), - (0x2124, 'M', 'z'), - (0x2125, 'V'), - (0x2126, 'M', 'ω'), - (0x2127, 'V'), - (0x2128, 'M', 'z'), - (0x2129, 'V'), - (0x212A, 'M', 'k'), - (0x212B, 'M', 'Ć„'), - (0x212C, 'M', 'b'), - (0x212D, 'M', 'c'), - (0x212E, 'V'), - (0x212F, 'M', 'e'), - (0x2131, 'M', 'f'), - (0x2132, 'X'), - (0x2133, 'M', 'm'), - (0x2134, 'M', 'o'), - (0x2135, 'M', 'א'), - (0x2136, 'M', 'ב'), - (0x2137, 'M', 'ג'), - (0x2138, 'M', 'ד'), - (0x2139, 'M', 'i'), - (0x213A, 'V'), - (0x213B, 'M', 'fax'), - (0x213C, 'M', 'Ļ€'), - (0x213D, 'M', 'γ'), - (0x213F, 'M', 'Ļ€'), - (0x2140, 'M', 'āˆ‘'), - (0x2141, 'V'), - (0x2145, 'M', 'd'), - (0x2147, 'M', 'e'), - (0x2148, 'M', 'i'), - (0x2149, 'M', 'j'), - (0x214A, 'V'), - (0x2150, 'M', '1⁄7'), - (0x2151, 'M', '1⁄9'), - (0x2152, 'M', '1⁄10'), - (0x2153, 'M', '1⁄3'), - (0x2154, 'M', '2⁄3'), - (0x2155, 'M', '1⁄5'), - (0x2156, 'M', '2⁄5'), - (0x2157, 'M', '3⁄5'), - (0x2158, 'M', '4⁄5'), - (0x2159, 'M', '1⁄6'), - (0x215A, 'M', '5⁄6'), - (0x215B, 'M', '1⁄8'), - (0x215C, 'M', '3⁄8'), - (0x215D, 'M', '5⁄8'), - (0x215E, 'M', '7⁄8'), - (0x215F, 'M', '1⁄'), - (0x2160, 'M', 'i'), - (0x2161, 'M', 'ii'), - (0x2162, 'M', 'iii'), - (0x2163, 'M', 'iv'), - (0x2164, 'M', 'v'), - (0x2165, 'M', 'vi'), - (0x2166, 'M', 'vii'), - (0x2167, 'M', 'viii'), - (0x2168, 'M', 'ix'), - (0x2169, 'M', 'x'), - (0x216A, 'M', 'xi'), - (0x216B, 'M', 'xii'), - (0x216C, 'M', 'l'), - (0x216D, 'M', 'c'), - (0x216E, 'M', 'd'), - (0x216F, 'M', 'm'), - (0x2170, 'M', 'i'), - (0x2171, 'M', 'ii'), - (0x2172, 'M', 'iii'), - (0x2173, 'M', 'iv'), - (0x2174, 'M', 'v'), - (0x2175, 'M', 'vi'), - (0x2176, 'M', 'vii'), - (0x2177, 'M', 'viii'), - (0x2178, 'M', 'ix'), - (0x2179, 'M', 'x'), - (0x217A, 'M', 'xi'), - (0x217B, 'M', 'xii'), - (0x217C, 'M', 'l'), + (0x2105, "3", "c/o"), + (0x2106, "3", "c/u"), + (0x2107, "M", "ɛ"), + (0x2108, "V"), + (0x2109, "M", "°f"), + (0x210A, "M", "g"), + (0x210B, "M", "h"), + (0x210F, "M", "ħ"), + (0x2110, "M", "i"), + (0x2112, "M", "l"), + (0x2114, "V"), + (0x2115, "M", "n"), + (0x2116, "M", "no"), + (0x2117, "V"), + (0x2119, "M", "p"), + (0x211A, "M", "q"), + (0x211B, "M", "r"), + (0x211E, "V"), + (0x2120, "M", "sm"), + (0x2121, "M", "tel"), + (0x2122, "M", "tm"), + (0x2123, "V"), + (0x2124, "M", "z"), + (0x2125, "V"), + (0x2126, "M", "ω"), + (0x2127, "V"), + (0x2128, "M", "z"), + (0x2129, "V"), + (0x212A, "M", "k"), + (0x212B, "M", "Ć„"), + (0x212C, "M", "b"), + (0x212D, "M", "c"), + (0x212E, "V"), + (0x212F, "M", "e"), + (0x2131, "M", "f"), + (0x2132, "X"), + (0x2133, "M", "m"), + (0x2134, "M", "o"), + (0x2135, "M", "א"), + (0x2136, "M", "ב"), + (0x2137, "M", "ג"), + (0x2138, "M", "ד"), + (0x2139, "M", "i"), + (0x213A, "V"), + (0x213B, "M", "fax"), + (0x213C, "M", "Ļ€"), + (0x213D, "M", "γ"), + (0x213F, "M", "Ļ€"), + (0x2140, "M", "āˆ‘"), + (0x2141, "V"), + (0x2145, "M", "d"), + (0x2147, "M", "e"), + (0x2148, "M", "i"), + (0x2149, "M", "j"), + (0x214A, "V"), + (0x2150, "M", "1⁄7"), + (0x2151, "M", "1⁄9"), + (0x2152, "M", "1⁄10"), + (0x2153, "M", "1⁄3"), + (0x2154, "M", "2⁄3"), + (0x2155, "M", "1⁄5"), + (0x2156, "M", "2⁄5"), + (0x2157, "M", "3⁄5"), + (0x2158, "M", "4⁄5"), + (0x2159, "M", "1⁄6"), + (0x215A, "M", "5⁄6"), + (0x215B, "M", "1⁄8"), + (0x215C, "M", "3⁄8"), + (0x215D, "M", "5⁄8"), + (0x215E, "M", "7⁄8"), + (0x215F, "M", "1⁄"), + (0x2160, "M", "i"), + (0x2161, "M", "ii"), + (0x2162, "M", "iii"), + (0x2163, "M", "iv"), + (0x2164, "M", "v"), + (0x2165, "M", "vi"), + (0x2166, "M", "vii"), + (0x2167, "M", "viii"), + (0x2168, "M", "ix"), + (0x2169, "M", "x"), + (0x216A, "M", "xi"), + (0x216B, "M", "xii"), + (0x216C, "M", "l"), + (0x216D, "M", "c"), + (0x216E, "M", "d"), + (0x216F, "M", "m"), + (0x2170, "M", "i"), + (0x2171, "M", "ii"), + (0x2172, "M", "iii"), + (0x2173, "M", "iv"), + (0x2174, "M", "v"), + (0x2175, "M", "vi"), + (0x2176, "M", "vii"), + (0x2177, "M", "viii"), + (0x2178, "M", "ix"), + (0x2179, "M", "x"), + (0x217A, "M", "xi"), + (0x217B, "M", "xii"), + (0x217C, "M", "l"), ] + def _seg_23() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x217D, 'M', 'c'), - (0x217E, 'M', 'd'), - (0x217F, 'M', 'm'), - (0x2180, 'V'), - (0x2183, 'X'), - (0x2184, 'V'), - (0x2189, 'M', '0⁄3'), - (0x218A, 'V'), - (0x218C, 'X'), - (0x2190, 'V'), - (0x222C, 'M', '∫∫'), - (0x222D, 'M', '∫∫∫'), - (0x222E, 'V'), - (0x222F, 'M', '∮∮'), - (0x2230, 'M', '∮∮∮'), - (0x2231, 'V'), - (0x2260, '3'), - (0x2261, 'V'), - (0x226E, '3'), - (0x2270, 'V'), - (0x2329, 'M', '怈'), - (0x232A, 'M', '怉'), - (0x232B, 'V'), - (0x2427, 'X'), - (0x2440, 'V'), - (0x244B, 'X'), - (0x2460, 'M', '1'), - (0x2461, 'M', '2'), - (0x2462, 'M', '3'), - (0x2463, 'M', '4'), - (0x2464, 'M', '5'), - (0x2465, 'M', '6'), - (0x2466, 'M', '7'), - (0x2467, 'M', '8'), - (0x2468, 'M', '9'), - (0x2469, 'M', '10'), - (0x246A, 'M', '11'), - (0x246B, 'M', '12'), - (0x246C, 'M', '13'), - (0x246D, 'M', '14'), - (0x246E, 'M', '15'), - (0x246F, 'M', '16'), - (0x2470, 'M', '17'), - (0x2471, 'M', '18'), - (0x2472, 'M', '19'), - (0x2473, 'M', '20'), - (0x2474, '3', '(1)'), - (0x2475, '3', '(2)'), - (0x2476, '3', '(3)'), - (0x2477, '3', '(4)'), - (0x2478, '3', '(5)'), - (0x2479, '3', '(6)'), - (0x247A, '3', '(7)'), - (0x247B, '3', '(8)'), - (0x247C, '3', '(9)'), - (0x247D, '3', '(10)'), - (0x247E, '3', '(11)'), - (0x247F, '3', '(12)'), - (0x2480, '3', '(13)'), - (0x2481, '3', '(14)'), - (0x2482, '3', '(15)'), - (0x2483, '3', '(16)'), - (0x2484, '3', '(17)'), - (0x2485, '3', '(18)'), - (0x2486, '3', '(19)'), - (0x2487, '3', '(20)'), - (0x2488, 'X'), - (0x249C, '3', '(a)'), - (0x249D, '3', '(b)'), - (0x249E, '3', '(c)'), - (0x249F, '3', '(d)'), - (0x24A0, '3', '(e)'), - (0x24A1, '3', '(f)'), - (0x24A2, '3', '(g)'), - (0x24A3, '3', '(h)'), - (0x24A4, '3', '(i)'), - (0x24A5, '3', '(j)'), - (0x24A6, '3', '(k)'), - (0x24A7, '3', '(l)'), - (0x24A8, '3', '(m)'), - (0x24A9, '3', '(n)'), - (0x24AA, '3', '(o)'), - (0x24AB, '3', '(p)'), - (0x24AC, '3', '(q)'), - (0x24AD, '3', '(r)'), - (0x24AE, '3', '(s)'), - (0x24AF, '3', '(t)'), - (0x24B0, '3', '(u)'), - (0x24B1, '3', '(v)'), - (0x24B2, '3', '(w)'), - (0x24B3, '3', '(x)'), - (0x24B4, '3', '(y)'), - (0x24B5, '3', '(z)'), - (0x24B6, 'M', 'a'), - (0x24B7, 'M', 'b'), - (0x24B8, 'M', 'c'), - (0x24B9, 'M', 'd'), - (0x24BA, 'M', 'e'), - (0x24BB, 'M', 'f'), - (0x24BC, 'M', 'g'), + (0x217D, "M", "c"), + (0x217E, "M", "d"), + (0x217F, "M", "m"), + (0x2180, "V"), + (0x2183, "X"), + (0x2184, "V"), + (0x2189, "M", "0⁄3"), + (0x218A, "V"), + (0x218C, "X"), + (0x2190, "V"), + (0x222C, "M", "∫∫"), + (0x222D, "M", "∫∫∫"), + (0x222E, "V"), + (0x222F, "M", "∮∮"), + (0x2230, "M", "∮∮∮"), + (0x2231, "V"), + (0x2329, "M", "怈"), + (0x232A, "M", "怉"), + (0x232B, "V"), + (0x2427, "X"), + (0x2440, "V"), + (0x244B, "X"), + (0x2460, "M", "1"), + (0x2461, "M", "2"), + (0x2462, "M", "3"), + (0x2463, "M", "4"), + (0x2464, "M", "5"), + (0x2465, "M", "6"), + (0x2466, "M", "7"), + (0x2467, "M", "8"), + (0x2468, "M", "9"), + (0x2469, "M", "10"), + (0x246A, "M", "11"), + (0x246B, "M", "12"), + (0x246C, "M", "13"), + (0x246D, "M", "14"), + (0x246E, "M", "15"), + (0x246F, "M", "16"), + (0x2470, "M", "17"), + (0x2471, "M", "18"), + (0x2472, "M", "19"), + (0x2473, "M", "20"), + (0x2474, "3", "(1)"), + (0x2475, "3", "(2)"), + (0x2476, "3", "(3)"), + (0x2477, "3", "(4)"), + (0x2478, "3", "(5)"), + (0x2479, "3", "(6)"), + (0x247A, "3", "(7)"), + (0x247B, "3", "(8)"), + (0x247C, "3", "(9)"), + (0x247D, "3", "(10)"), + (0x247E, "3", "(11)"), + (0x247F, "3", "(12)"), + (0x2480, "3", "(13)"), + (0x2481, "3", "(14)"), + (0x2482, "3", "(15)"), + (0x2483, "3", "(16)"), + (0x2484, "3", "(17)"), + (0x2485, "3", "(18)"), + (0x2486, "3", "(19)"), + (0x2487, "3", "(20)"), + (0x2488, "X"), + (0x249C, "3", "(a)"), + (0x249D, "3", "(b)"), + (0x249E, "3", "(c)"), + (0x249F, "3", "(d)"), + (0x24A0, "3", "(e)"), + (0x24A1, "3", "(f)"), + (0x24A2, "3", "(g)"), + (0x24A3, "3", "(h)"), + (0x24A4, "3", "(i)"), + (0x24A5, "3", "(j)"), + (0x24A6, "3", "(k)"), + (0x24A7, "3", "(l)"), + (0x24A8, "3", "(m)"), + (0x24A9, "3", "(n)"), + (0x24AA, "3", "(o)"), + (0x24AB, "3", "(p)"), + (0x24AC, "3", "(q)"), + (0x24AD, "3", "(r)"), + (0x24AE, "3", "(s)"), + (0x24AF, "3", "(t)"), + (0x24B0, "3", "(u)"), + (0x24B1, "3", "(v)"), + (0x24B2, "3", "(w)"), + (0x24B3, "3", "(x)"), + (0x24B4, "3", "(y)"), + (0x24B5, "3", "(z)"), + (0x24B6, "M", "a"), + (0x24B7, "M", "b"), + (0x24B8, "M", "c"), + (0x24B9, "M", "d"), + (0x24BA, "M", "e"), + (0x24BB, "M", "f"), + (0x24BC, "M", "g"), + (0x24BD, "M", "h"), + (0x24BE, "M", "i"), + (0x24BF, "M", "j"), + (0x24C0, "M", "k"), ] + def _seg_24() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x24BD, 'M', 'h'), - (0x24BE, 'M', 'i'), - (0x24BF, 'M', 'j'), - (0x24C0, 'M', 'k'), - (0x24C1, 'M', 'l'), - (0x24C2, 'M', 'm'), - (0x24C3, 'M', 'n'), - (0x24C4, 'M', 'o'), - (0x24C5, 'M', 'p'), - (0x24C6, 'M', 'q'), - (0x24C7, 'M', 'r'), - (0x24C8, 'M', 's'), - (0x24C9, 'M', 't'), - (0x24CA, 'M', 'u'), - (0x24CB, 'M', 'v'), - (0x24CC, 'M', 'w'), - (0x24CD, 'M', 'x'), - (0x24CE, 'M', 'y'), - (0x24CF, 'M', 'z'), - (0x24D0, 'M', 'a'), - (0x24D1, 'M', 'b'), - (0x24D2, 'M', 'c'), - (0x24D3, 'M', 'd'), - (0x24D4, 'M', 'e'), - (0x24D5, 'M', 'f'), - (0x24D6, 'M', 'g'), - (0x24D7, 'M', 'h'), - (0x24D8, 'M', 'i'), - (0x24D9, 'M', 'j'), - (0x24DA, 'M', 'k'), - (0x24DB, 'M', 'l'), - (0x24DC, 'M', 'm'), - (0x24DD, 'M', 'n'), - (0x24DE, 'M', 'o'), - (0x24DF, 'M', 'p'), - (0x24E0, 'M', 'q'), - (0x24E1, 'M', 'r'), - (0x24E2, 'M', 's'), - (0x24E3, 'M', 't'), - (0x24E4, 'M', 'u'), - (0x24E5, 'M', 'v'), - (0x24E6, 'M', 'w'), - (0x24E7, 'M', 'x'), - (0x24E8, 'M', 'y'), - (0x24E9, 'M', 'z'), - (0x24EA, 'M', '0'), - (0x24EB, 'V'), - (0x2A0C, 'M', '∫∫∫∫'), - (0x2A0D, 'V'), - (0x2A74, '3', '::='), - (0x2A75, '3', '=='), - (0x2A76, '3', '==='), - (0x2A77, 'V'), - (0x2ADC, 'M', 'ā«Ģø'), - (0x2ADD, 'V'), - (0x2B74, 'X'), - (0x2B76, 'V'), - (0x2B96, 'X'), - (0x2B97, 'V'), - (0x2C00, 'M', 'ā°°'), - (0x2C01, 'M', 'ā°±'), - (0x2C02, 'M', 'ā°²'), - (0x2C03, 'M', 'ā°³'), - (0x2C04, 'M', 'ā°“'), - (0x2C05, 'M', 'ā°µ'), - (0x2C06, 'M', 'ā°¶'), - (0x2C07, 'M', 'ā°·'), - (0x2C08, 'M', 'ā°ø'), - (0x2C09, 'M', 'ā°¹'), - (0x2C0A, 'M', 'ā°ŗ'), - (0x2C0B, 'M', 'ā°»'), - (0x2C0C, 'M', 'ā°¼'), - (0x2C0D, 'M', 'ā°½'), - (0x2C0E, 'M', 'ā°¾'), - (0x2C0F, 'M', 'ā°æ'), - (0x2C10, 'M', 'ā±€'), - (0x2C11, 'M', 'ⱁ'), - (0x2C12, 'M', 'ⱂ'), - (0x2C13, 'M', 'ⱃ'), - (0x2C14, 'M', 'ⱄ'), - (0x2C15, 'M', 'ā±…'), - (0x2C16, 'M', 'ⱆ'), - (0x2C17, 'M', 'ⱇ'), - (0x2C18, 'M', 'ⱈ'), - (0x2C19, 'M', 'ⱉ'), - (0x2C1A, 'M', 'ⱊ'), - (0x2C1B, 'M', 'ⱋ'), - (0x2C1C, 'M', 'ⱌ'), - (0x2C1D, 'M', 'ā±'), - (0x2C1E, 'M', 'ā±Ž'), - (0x2C1F, 'M', 'ā±'), - (0x2C20, 'M', 'ⱐ'), - (0x2C21, 'M', 'ⱑ'), - (0x2C22, 'M', 'ā±’'), - (0x2C23, 'M', 'ⱓ'), - (0x2C24, 'M', 'ā±”'), - (0x2C25, 'M', 'ⱕ'), - (0x2C26, 'M', 'ā±–'), - (0x2C27, 'M', 'ā±—'), - (0x2C28, 'M', 'ⱘ'), + (0x24C1, "M", "l"), + (0x24C2, "M", "m"), + (0x24C3, "M", "n"), + (0x24C4, "M", "o"), + (0x24C5, "M", "p"), + (0x24C6, "M", "q"), + (0x24C7, "M", "r"), + (0x24C8, "M", "s"), + (0x24C9, "M", "t"), + (0x24CA, "M", "u"), + (0x24CB, "M", "v"), + (0x24CC, "M", "w"), + (0x24CD, "M", "x"), + (0x24CE, "M", "y"), + (0x24CF, "M", "z"), + (0x24D0, "M", "a"), + (0x24D1, "M", "b"), + (0x24D2, "M", "c"), + (0x24D3, "M", "d"), + (0x24D4, "M", "e"), + (0x24D5, "M", "f"), + (0x24D6, "M", "g"), + (0x24D7, "M", "h"), + (0x24D8, "M", "i"), + (0x24D9, "M", "j"), + (0x24DA, "M", "k"), + (0x24DB, "M", "l"), + (0x24DC, "M", "m"), + (0x24DD, "M", "n"), + (0x24DE, "M", "o"), + (0x24DF, "M", "p"), + (0x24E0, "M", "q"), + (0x24E1, "M", "r"), + (0x24E2, "M", "s"), + (0x24E3, "M", "t"), + (0x24E4, "M", "u"), + (0x24E5, "M", "v"), + (0x24E6, "M", "w"), + (0x24E7, "M", "x"), + (0x24E8, "M", "y"), + (0x24E9, "M", "z"), + (0x24EA, "M", "0"), + (0x24EB, "V"), + (0x2A0C, "M", "∫∫∫∫"), + (0x2A0D, "V"), + (0x2A74, "3", "::="), + (0x2A75, "3", "=="), + (0x2A76, "3", "==="), + (0x2A77, "V"), + (0x2ADC, "M", "ā«Ģø"), + (0x2ADD, "V"), + (0x2B74, "X"), + (0x2B76, "V"), + (0x2B96, "X"), + (0x2B97, "V"), + (0x2C00, "M", "ā°°"), + (0x2C01, "M", "ā°±"), + (0x2C02, "M", "ā°²"), + (0x2C03, "M", "ā°³"), + (0x2C04, "M", "ā°“"), + (0x2C05, "M", "ā°µ"), + (0x2C06, "M", "ā°¶"), + (0x2C07, "M", "ā°·"), + (0x2C08, "M", "ā°ø"), + (0x2C09, "M", "ā°¹"), + (0x2C0A, "M", "ā°ŗ"), + (0x2C0B, "M", "ā°»"), + (0x2C0C, "M", "ā°¼"), + (0x2C0D, "M", "ā°½"), + (0x2C0E, "M", "ā°¾"), + (0x2C0F, "M", "ā°æ"), + (0x2C10, "M", "ā±€"), + (0x2C11, "M", "ⱁ"), + (0x2C12, "M", "ⱂ"), + (0x2C13, "M", "ⱃ"), + (0x2C14, "M", "ⱄ"), + (0x2C15, "M", "ā±…"), + (0x2C16, "M", "ⱆ"), + (0x2C17, "M", "ⱇ"), + (0x2C18, "M", "ⱈ"), + (0x2C19, "M", "ⱉ"), + (0x2C1A, "M", "ⱊ"), + (0x2C1B, "M", "ⱋ"), + (0x2C1C, "M", "ⱌ"), + (0x2C1D, "M", "ā±"), + (0x2C1E, "M", "ā±Ž"), + (0x2C1F, "M", "ā±"), + (0x2C20, "M", "ⱐ"), + (0x2C21, "M", "ⱑ"), + (0x2C22, "M", "ā±’"), + (0x2C23, "M", "ⱓ"), + (0x2C24, "M", "ā±”"), + (0x2C25, "M", "ⱕ"), + (0x2C26, "M", "ā±–"), + (0x2C27, "M", "ā±—"), + (0x2C28, "M", "ⱘ"), + (0x2C29, "M", "ā±™"), + (0x2C2A, "M", "ⱚ"), + (0x2C2B, "M", "ā±›"), + (0x2C2C, "M", "ⱜ"), ] + def _seg_25() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2C29, 'M', 'ā±™'), - (0x2C2A, 'M', 'ⱚ'), - (0x2C2B, 'M', 'ā±›'), - (0x2C2C, 'M', 'ⱜ'), - (0x2C2D, 'M', 'ā±'), - (0x2C2E, 'M', 'ā±ž'), - (0x2C2F, 'M', 'ⱟ'), - (0x2C30, 'V'), - (0x2C60, 'M', 'ā±”'), - (0x2C61, 'V'), - (0x2C62, 'M', 'É«'), - (0x2C63, 'M', 'įµ½'), - (0x2C64, 'M', 'ɽ'), - (0x2C65, 'V'), - (0x2C67, 'M', 'ⱨ'), - (0x2C68, 'V'), - (0x2C69, 'M', 'ā±Ŗ'), - (0x2C6A, 'V'), - (0x2C6B, 'M', 'ⱬ'), - (0x2C6C, 'V'), - (0x2C6D, 'M', 'ɑ'), - (0x2C6E, 'M', 'ɱ'), - (0x2C6F, 'M', 'ɐ'), - (0x2C70, 'M', 'ɒ'), - (0x2C71, 'V'), - (0x2C72, 'M', 'ā±³'), - (0x2C73, 'V'), - (0x2C75, 'M', 'ā±¶'), - (0x2C76, 'V'), - (0x2C7C, 'M', 'j'), - (0x2C7D, 'M', 'v'), - (0x2C7E, 'M', 'Čæ'), - (0x2C7F, 'M', 'ɀ'), - (0x2C80, 'M', 'ⲁ'), - (0x2C81, 'V'), - (0x2C82, 'M', 'ⲃ'), - (0x2C83, 'V'), - (0x2C84, 'M', 'ā²…'), - (0x2C85, 'V'), - (0x2C86, 'M', 'ⲇ'), - (0x2C87, 'V'), - (0x2C88, 'M', 'ⲉ'), - (0x2C89, 'V'), - (0x2C8A, 'M', 'ⲋ'), - (0x2C8B, 'V'), - (0x2C8C, 'M', 'ā²'), - (0x2C8D, 'V'), - (0x2C8E, 'M', 'ā²'), - (0x2C8F, 'V'), - (0x2C90, 'M', 'ⲑ'), - (0x2C91, 'V'), - (0x2C92, 'M', 'ⲓ'), - (0x2C93, 'V'), - (0x2C94, 'M', 'ⲕ'), - (0x2C95, 'V'), - (0x2C96, 'M', 'ā²—'), - (0x2C97, 'V'), - (0x2C98, 'M', 'ā²™'), - (0x2C99, 'V'), - (0x2C9A, 'M', 'ā²›'), - (0x2C9B, 'V'), - (0x2C9C, 'M', 'ā²'), - (0x2C9D, 'V'), - (0x2C9E, 'M', 'ⲟ'), - (0x2C9F, 'V'), - (0x2CA0, 'M', 'ā²”'), - (0x2CA1, 'V'), - (0x2CA2, 'M', 'ā²£'), - (0x2CA3, 'V'), - (0x2CA4, 'M', 'Ⲅ'), - (0x2CA5, 'V'), - (0x2CA6, 'M', 'ā²§'), - (0x2CA7, 'V'), - (0x2CA8, 'M', 'ⲩ'), - (0x2CA9, 'V'), - (0x2CAA, 'M', 'ⲫ'), - (0x2CAB, 'V'), - (0x2CAC, 'M', 'ā²­'), - (0x2CAD, 'V'), - (0x2CAE, 'M', 'ⲯ'), - (0x2CAF, 'V'), - (0x2CB0, 'M', 'ā²±'), - (0x2CB1, 'V'), - (0x2CB2, 'M', 'ā²³'), - (0x2CB3, 'V'), - (0x2CB4, 'M', 'ā²µ'), - (0x2CB5, 'V'), - (0x2CB6, 'M', 'ā²·'), - (0x2CB7, 'V'), - (0x2CB8, 'M', 'ā²¹'), - (0x2CB9, 'V'), - (0x2CBA, 'M', 'ā²»'), - (0x2CBB, 'V'), - (0x2CBC, 'M', 'ā²½'), - (0x2CBD, 'V'), - (0x2CBE, 'M', 'ⲿ'), - (0x2CBF, 'V'), - (0x2CC0, 'M', 'ⳁ'), - (0x2CC1, 'V'), - (0x2CC2, 'M', 'ⳃ'), + (0x2C2D, "M", "ā±"), + (0x2C2E, "M", "ā±ž"), + (0x2C2F, "M", "ⱟ"), + (0x2C30, "V"), + (0x2C60, "M", "ā±”"), + (0x2C61, "V"), + (0x2C62, "M", "É«"), + (0x2C63, "M", "įµ½"), + (0x2C64, "M", "ɽ"), + (0x2C65, "V"), + (0x2C67, "M", "ⱨ"), + (0x2C68, "V"), + (0x2C69, "M", "ā±Ŗ"), + (0x2C6A, "V"), + (0x2C6B, "M", "ⱬ"), + (0x2C6C, "V"), + (0x2C6D, "M", "ɑ"), + (0x2C6E, "M", "ɱ"), + (0x2C6F, "M", "ɐ"), + (0x2C70, "M", "ɒ"), + (0x2C71, "V"), + (0x2C72, "M", "ā±³"), + (0x2C73, "V"), + (0x2C75, "M", "ā±¶"), + (0x2C76, "V"), + (0x2C7C, "M", "j"), + (0x2C7D, "M", "v"), + (0x2C7E, "M", "Čæ"), + (0x2C7F, "M", "ɀ"), + (0x2C80, "M", "ⲁ"), + (0x2C81, "V"), + (0x2C82, "M", "ⲃ"), + (0x2C83, "V"), + (0x2C84, "M", "ā²…"), + (0x2C85, "V"), + (0x2C86, "M", "ⲇ"), + (0x2C87, "V"), + (0x2C88, "M", "ⲉ"), + (0x2C89, "V"), + (0x2C8A, "M", "ⲋ"), + (0x2C8B, "V"), + (0x2C8C, "M", "ā²"), + (0x2C8D, "V"), + (0x2C8E, "M", "ā²"), + (0x2C8F, "V"), + (0x2C90, "M", "ⲑ"), + (0x2C91, "V"), + (0x2C92, "M", "ⲓ"), + (0x2C93, "V"), + (0x2C94, "M", "ⲕ"), + (0x2C95, "V"), + (0x2C96, "M", "ā²—"), + (0x2C97, "V"), + (0x2C98, "M", "ā²™"), + (0x2C99, "V"), + (0x2C9A, "M", "ā²›"), + (0x2C9B, "V"), + (0x2C9C, "M", "ā²"), + (0x2C9D, "V"), + (0x2C9E, "M", "ⲟ"), + (0x2C9F, "V"), + (0x2CA0, "M", "ā²”"), + (0x2CA1, "V"), + (0x2CA2, "M", "ā²£"), + (0x2CA3, "V"), + (0x2CA4, "M", "Ⲅ"), + (0x2CA5, "V"), + (0x2CA6, "M", "ā²§"), + (0x2CA7, "V"), + (0x2CA8, "M", "ⲩ"), + (0x2CA9, "V"), + (0x2CAA, "M", "ⲫ"), + (0x2CAB, "V"), + (0x2CAC, "M", "ā²­"), + (0x2CAD, "V"), + (0x2CAE, "M", "ⲯ"), + (0x2CAF, "V"), + (0x2CB0, "M", "ā²±"), + (0x2CB1, "V"), + (0x2CB2, "M", "ā²³"), + (0x2CB3, "V"), + (0x2CB4, "M", "ā²µ"), + (0x2CB5, "V"), + (0x2CB6, "M", "ā²·"), + (0x2CB7, "V"), + (0x2CB8, "M", "ā²¹"), + (0x2CB9, "V"), + (0x2CBA, "M", "ā²»"), + (0x2CBB, "V"), + (0x2CBC, "M", "ā²½"), + (0x2CBD, "V"), + (0x2CBE, "M", "ⲿ"), + (0x2CBF, "V"), + (0x2CC0, "M", "ⳁ"), + (0x2CC1, "V"), + (0x2CC2, "M", "ⳃ"), + (0x2CC3, "V"), + (0x2CC4, "M", "ā³…"), + (0x2CC5, "V"), + (0x2CC6, "M", "ⳇ"), ] + def _seg_26() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2CC3, 'V'), - (0x2CC4, 'M', 'ā³…'), - (0x2CC5, 'V'), - (0x2CC6, 'M', 'ⳇ'), - (0x2CC7, 'V'), - (0x2CC8, 'M', 'ⳉ'), - (0x2CC9, 'V'), - (0x2CCA, 'M', 'ⳋ'), - (0x2CCB, 'V'), - (0x2CCC, 'M', 'ā³'), - (0x2CCD, 'V'), - (0x2CCE, 'M', 'ā³'), - (0x2CCF, 'V'), - (0x2CD0, 'M', 'ⳑ'), - (0x2CD1, 'V'), - (0x2CD2, 'M', 'ⳓ'), - (0x2CD3, 'V'), - (0x2CD4, 'M', 'ⳕ'), - (0x2CD5, 'V'), - (0x2CD6, 'M', 'ā³—'), - (0x2CD7, 'V'), - (0x2CD8, 'M', 'ā³™'), - (0x2CD9, 'V'), - (0x2CDA, 'M', 'ā³›'), - (0x2CDB, 'V'), - (0x2CDC, 'M', 'ā³'), - (0x2CDD, 'V'), - (0x2CDE, 'M', 'ⳟ'), - (0x2CDF, 'V'), - (0x2CE0, 'M', 'ā³”'), - (0x2CE1, 'V'), - (0x2CE2, 'M', 'ā³£'), - (0x2CE3, 'V'), - (0x2CEB, 'M', 'ⳬ'), - (0x2CEC, 'V'), - (0x2CED, 'M', 'ā³®'), - (0x2CEE, 'V'), - (0x2CF2, 'M', 'ā³³'), - (0x2CF3, 'V'), - (0x2CF4, 'X'), - (0x2CF9, 'V'), - (0x2D26, 'X'), - (0x2D27, 'V'), - (0x2D28, 'X'), - (0x2D2D, 'V'), - (0x2D2E, 'X'), - (0x2D30, 'V'), - (0x2D68, 'X'), - (0x2D6F, 'M', 'āµ”'), - (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'), - (0x2E5E, 'X'), - (0x2E80, 'V'), - (0x2E9A, 'X'), - (0x2E9B, 'V'), - (0x2E9F, 'M', 'ęÆ'), - (0x2EA0, 'V'), - (0x2EF3, 'M', '龟'), - (0x2EF4, 'X'), - (0x2F00, 'M', 'äø€'), - (0x2F01, 'M', 'äøØ'), - (0x2F02, 'M', 'äø¶'), - (0x2F03, 'M', 'äøæ'), - (0x2F04, 'M', '乙'), - (0x2F05, 'M', 'äŗ…'), - (0x2F06, 'M', '二'), - (0x2F07, 'M', 'äŗ '), - (0x2F08, 'M', 'äŗŗ'), - (0x2F09, 'M', '儿'), - (0x2F0A, 'M', 'å…„'), - (0x2F0B, 'M', '八'), - (0x2F0C, 'M', '冂'), - (0x2F0D, 'M', '冖'), - (0x2F0E, 'M', '冫'), - (0x2F0F, 'M', '几'), - (0x2F10, 'M', '凵'), - (0x2F11, 'M', '刀'), - (0x2F12, 'M', '力'), - (0x2F13, 'M', '勹'), - (0x2F14, 'M', '匕'), - (0x2F15, 'M', '匚'), + (0x2CC7, "V"), + (0x2CC8, "M", "ⳉ"), + (0x2CC9, "V"), + (0x2CCA, "M", "ⳋ"), + (0x2CCB, "V"), + (0x2CCC, "M", "ā³"), + (0x2CCD, "V"), + (0x2CCE, "M", "ā³"), + (0x2CCF, "V"), + (0x2CD0, "M", "ⳑ"), + (0x2CD1, "V"), + (0x2CD2, "M", "ⳓ"), + (0x2CD3, "V"), + (0x2CD4, "M", "ⳕ"), + (0x2CD5, "V"), + (0x2CD6, "M", "ā³—"), + (0x2CD7, "V"), + (0x2CD8, "M", "ā³™"), + (0x2CD9, "V"), + (0x2CDA, "M", "ā³›"), + (0x2CDB, "V"), + (0x2CDC, "M", "ā³"), + (0x2CDD, "V"), + (0x2CDE, "M", "ⳟ"), + (0x2CDF, "V"), + (0x2CE0, "M", "ā³”"), + (0x2CE1, "V"), + (0x2CE2, "M", "ā³£"), + (0x2CE3, "V"), + (0x2CEB, "M", "ⳬ"), + (0x2CEC, "V"), + (0x2CED, "M", "ā³®"), + (0x2CEE, "V"), + (0x2CF2, "M", "ā³³"), + (0x2CF3, "V"), + (0x2CF4, "X"), + (0x2CF9, "V"), + (0x2D26, "X"), + (0x2D27, "V"), + (0x2D28, "X"), + (0x2D2D, "V"), + (0x2D2E, "X"), + (0x2D30, "V"), + (0x2D68, "X"), + (0x2D6F, "M", "āµ”"), + (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"), + (0x2E5E, "X"), + (0x2E80, "V"), + (0x2E9A, "X"), + (0x2E9B, "V"), + (0x2E9F, "M", "ęÆ"), + (0x2EA0, "V"), + (0x2EF3, "M", "龟"), + (0x2EF4, "X"), + (0x2F00, "M", "äø€"), + (0x2F01, "M", "äøØ"), + (0x2F02, "M", "äø¶"), + (0x2F03, "M", "äøæ"), + (0x2F04, "M", "乙"), + (0x2F05, "M", "äŗ…"), + (0x2F06, "M", "二"), + (0x2F07, "M", "äŗ "), + (0x2F08, "M", "äŗŗ"), + (0x2F09, "M", "儿"), + (0x2F0A, "M", "å…„"), + (0x2F0B, "M", "八"), + (0x2F0C, "M", "冂"), + (0x2F0D, "M", "冖"), + (0x2F0E, "M", "冫"), + (0x2F0F, "M", "几"), + (0x2F10, "M", "凵"), + (0x2F11, "M", "刀"), + (0x2F12, "M", "力"), + (0x2F13, "M", "勹"), + (0x2F14, "M", "匕"), + (0x2F15, "M", "匚"), + (0x2F16, "M", "匸"), + (0x2F17, "M", "十"), + (0x2F18, "M", "卜"), + (0x2F19, "M", "卩"), ] + def _seg_27() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F16, 'M', '匸'), - (0x2F17, 'M', '十'), - (0x2F18, 'M', '卜'), - (0x2F19, 'M', '卩'), - (0x2F1A, 'M', '厂'), - (0x2F1B, 'M', '厶'), - (0x2F1C, 'M', '又'), - (0x2F1D, 'M', '口'), - (0x2F1E, 'M', '囗'), - (0x2F1F, 'M', '土'), - (0x2F20, 'M', '士'), - (0x2F21, 'M', '夂'), - (0x2F22, 'M', '夊'), - (0x2F23, 'M', '夕'), - (0x2F24, 'M', '大'), - (0x2F25, 'M', '儳'), - (0x2F26, 'M', '子'), - (0x2F27, 'M', '宀'), - (0x2F28, 'M', '寸'), - (0x2F29, 'M', '小'), - (0x2F2A, 'M', 'å°¢'), - (0x2F2B, 'M', 'å°ø'), - (0x2F2C, 'M', 'å±®'), - (0x2F2D, 'M', 'å±±'), - (0x2F2E, 'M', '巛'), - (0x2F2F, 'M', 'å·„'), - (0x2F30, 'M', 'å·±'), - (0x2F31, 'M', 'å·¾'), - (0x2F32, 'M', 'å¹²'), - (0x2F33, 'M', 'å¹ŗ'), - (0x2F34, 'M', '广'), - (0x2F35, 'M', '廓'), - (0x2F36, 'M', '廾'), - (0x2F37, 'M', '弋'), - (0x2F38, 'M', '弓'), - (0x2F39, 'M', '彐'), - (0x2F3A, 'M', 'å½”'), - (0x2F3B, 'M', 'å½³'), - (0x2F3C, 'M', '心'), - (0x2F3D, 'M', 'ꈈ'), - (0x2F3E, 'M', 'ꈶ'), - (0x2F3F, 'M', 'ꉋ'), - (0x2F40, 'M', '支'), - (0x2F41, 'M', 'ꔓ'), - (0x2F42, 'M', 'ꖇ'), - (0x2F43, 'M', 'ꖗ'), - (0x2F44, 'M', 'ꖤ'), - (0x2F45, 'M', 'ę–¹'), - (0x2F46, 'M', 'ꗠ'), - (0x2F47, 'M', 'ę—„'), - (0x2F48, 'M', '꛰'), - (0x2F49, 'M', '月'), - (0x2F4A, 'M', '木'), - (0x2F4B, 'M', 'ꬠ'), - (0x2F4C, 'M', 'ę­¢'), - (0x2F4D, 'M', 'ę­¹'), - (0x2F4E, 'M', '殳'), - (0x2F4F, 'M', '毋'), - (0x2F50, 'M', '比'), - (0x2F51, 'M', '毛'), - (0x2F52, 'M', '갏'), - (0x2F53, 'M', '갔'), - (0x2F54, 'M', 'ę°“'), - (0x2F55, 'M', '火'), - (0x2F56, 'M', '爪'), - (0x2F57, 'M', '父'), - (0x2F58, 'M', '爻'), - (0x2F59, 'M', '爿'), - (0x2F5A, 'M', '片'), - (0x2F5B, 'M', '牙'), - (0x2F5C, 'M', '牛'), - (0x2F5D, 'M', '犬'), - (0x2F5E, 'M', 'ēŽ„'), - (0x2F5F, 'M', 'ēŽ‰'), - (0x2F60, 'M', 'ē“œ'), - (0x2F61, 'M', '瓦'), - (0x2F62, 'M', 'ē”˜'), - (0x2F63, 'M', 'ē”Ÿ'), - (0x2F64, 'M', '用'), - (0x2F65, 'M', 'ē”°'), - (0x2F66, 'M', 'ē–‹'), - (0x2F67, 'M', 'ē–’'), - (0x2F68, 'M', 'ē™¶'), - (0x2F69, 'M', '白'), - (0x2F6A, 'M', '皮'), - (0x2F6B, 'M', '皿'), - (0x2F6C, 'M', 'ē›®'), - (0x2F6D, 'M', 'ēŸ›'), - (0x2F6E, 'M', '矢'), - (0x2F6F, 'M', '石'), - (0x2F70, 'M', '示'), - (0x2F71, 'M', '禸'), - (0x2F72, 'M', '禾'), - (0x2F73, 'M', 'ē©“'), - (0x2F74, 'M', 'ē«‹'), - (0x2F75, 'M', '竹'), - (0x2F76, 'M', 'ē±³'), - (0x2F77, 'M', 'ē³ø'), - (0x2F78, 'M', 'ē¼¶'), - (0x2F79, 'M', '网'), + (0x2F1A, "M", "厂"), + (0x2F1B, "M", "厶"), + (0x2F1C, "M", "又"), + (0x2F1D, "M", "口"), + (0x2F1E, "M", "囗"), + (0x2F1F, "M", "土"), + (0x2F20, "M", "士"), + (0x2F21, "M", "夂"), + (0x2F22, "M", "夊"), + (0x2F23, "M", "夕"), + (0x2F24, "M", "大"), + (0x2F25, "M", "儳"), + (0x2F26, "M", "子"), + (0x2F27, "M", "宀"), + (0x2F28, "M", "寸"), + (0x2F29, "M", "小"), + (0x2F2A, "M", "å°¢"), + (0x2F2B, "M", "å°ø"), + (0x2F2C, "M", "å±®"), + (0x2F2D, "M", "å±±"), + (0x2F2E, "M", "巛"), + (0x2F2F, "M", "å·„"), + (0x2F30, "M", "å·±"), + (0x2F31, "M", "å·¾"), + (0x2F32, "M", "å¹²"), + (0x2F33, "M", "å¹ŗ"), + (0x2F34, "M", "广"), + (0x2F35, "M", "廓"), + (0x2F36, "M", "廾"), + (0x2F37, "M", "弋"), + (0x2F38, "M", "弓"), + (0x2F39, "M", "彐"), + (0x2F3A, "M", "å½”"), + (0x2F3B, "M", "å½³"), + (0x2F3C, "M", "心"), + (0x2F3D, "M", "ꈈ"), + (0x2F3E, "M", "ꈶ"), + (0x2F3F, "M", "ꉋ"), + (0x2F40, "M", "支"), + (0x2F41, "M", "ꔓ"), + (0x2F42, "M", "ꖇ"), + (0x2F43, "M", "ꖗ"), + (0x2F44, "M", "ꖤ"), + (0x2F45, "M", "ę–¹"), + (0x2F46, "M", "ꗠ"), + (0x2F47, "M", "ę—„"), + (0x2F48, "M", "꛰"), + (0x2F49, "M", "月"), + (0x2F4A, "M", "木"), + (0x2F4B, "M", "ꬠ"), + (0x2F4C, "M", "ę­¢"), + (0x2F4D, "M", "ę­¹"), + (0x2F4E, "M", "殳"), + (0x2F4F, "M", "毋"), + (0x2F50, "M", "比"), + (0x2F51, "M", "毛"), + (0x2F52, "M", "갏"), + (0x2F53, "M", "갔"), + (0x2F54, "M", "ę°“"), + (0x2F55, "M", "火"), + (0x2F56, "M", "爪"), + (0x2F57, "M", "父"), + (0x2F58, "M", "爻"), + (0x2F59, "M", "爿"), + (0x2F5A, "M", "片"), + (0x2F5B, "M", "牙"), + (0x2F5C, "M", "牛"), + (0x2F5D, "M", "犬"), + (0x2F5E, "M", "ēŽ„"), + (0x2F5F, "M", "ēŽ‰"), + (0x2F60, "M", "ē“œ"), + (0x2F61, "M", "瓦"), + (0x2F62, "M", "ē”˜"), + (0x2F63, "M", "ē”Ÿ"), + (0x2F64, "M", "用"), + (0x2F65, "M", "ē”°"), + (0x2F66, "M", "ē–‹"), + (0x2F67, "M", "ē–’"), + (0x2F68, "M", "ē™¶"), + (0x2F69, "M", "白"), + (0x2F6A, "M", "皮"), + (0x2F6B, "M", "皿"), + (0x2F6C, "M", "ē›®"), + (0x2F6D, "M", "ēŸ›"), + (0x2F6E, "M", "矢"), + (0x2F6F, "M", "石"), + (0x2F70, "M", "示"), + (0x2F71, "M", "禸"), + (0x2F72, "M", "禾"), + (0x2F73, "M", "ē©“"), + (0x2F74, "M", "ē«‹"), + (0x2F75, "M", "竹"), + (0x2F76, "M", "ē±³"), + (0x2F77, "M", "ē³ø"), + (0x2F78, "M", "ē¼¶"), + (0x2F79, "M", "网"), + (0x2F7A, "M", "羊"), + (0x2F7B, "M", "ē¾½"), + (0x2F7C, "M", "老"), + (0x2F7D, "M", "而"), ] + def _seg_28() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F7A, 'M', '羊'), - (0x2F7B, 'M', 'ē¾½'), - (0x2F7C, 'M', '老'), - (0x2F7D, 'M', '而'), - (0x2F7E, 'M', '耒'), - (0x2F7F, 'M', '耳'), - (0x2F80, 'M', '聿'), - (0x2F81, 'M', '肉'), - (0x2F82, 'M', '臣'), - (0x2F83, 'M', '自'), - (0x2F84, 'M', '至'), - (0x2F85, 'M', '臼'), - (0x2F86, 'M', '舌'), - (0x2F87, 'M', '舛'), - (0x2F88, 'M', '舟'), - (0x2F89, 'M', '艮'), - (0x2F8A, 'M', '色'), - (0x2F8B, 'M', '艸'), - (0x2F8C, 'M', '虍'), - (0x2F8D, 'M', '虫'), - (0x2F8E, 'M', '蔀'), - (0x2F8F, 'M', '蔌'), - (0x2F90, 'M', '蔣'), - (0x2F91, 'M', '脾'), - (0x2F92, 'M', '見'), - (0x2F93, 'M', '角'), - (0x2F94, 'M', '言'), - (0x2F95, 'M', 'č°·'), - (0x2F96, 'M', '豆'), - (0x2F97, 'M', '豕'), - (0x2F98, 'M', 'č±ø'), - (0x2F99, 'M', 'č²'), - (0x2F9A, 'M', '赤'), - (0x2F9B, 'M', 'čµ°'), - (0x2F9C, 'M', 'č¶³'), - (0x2F9D, 'M', 'čŗ«'), - (0x2F9E, 'M', '車'), - (0x2F9F, 'M', 'č¾›'), - (0x2FA0, 'M', 'č¾°'), - (0x2FA1, 'M', 'č¾µ'), - (0x2FA2, 'M', '邑'), - (0x2FA3, 'M', '酉'), - (0x2FA4, 'M', '釆'), - (0x2FA5, 'M', '里'), - (0x2FA6, 'M', '金'), - (0x2FA7, 'M', '長'), - (0x2FA8, 'M', '門'), - (0x2FA9, 'M', '阜'), - (0x2FAA, 'M', '隶'), - (0x2FAB, 'M', '隹'), - (0x2FAC, 'M', '雨'), - (0x2FAD, 'M', '靑'), - (0x2FAE, 'M', '非'), - (0x2FAF, 'M', '面'), - (0x2FB0, 'M', '革'), - (0x2FB1, 'M', '韋'), - (0x2FB2, 'M', '韭'), - (0x2FB3, 'M', '音'), - (0x2FB4, 'M', '頁'), - (0x2FB5, 'M', '風'), - (0x2FB6, 'M', '飛'), - (0x2FB7, 'M', '食'), - (0x2FB8, 'M', '首'), - (0x2FB9, 'M', '香'), - (0x2FBA, 'M', '馬'), - (0x2FBB, 'M', 'éŖØ'), - (0x2FBC, 'M', '高'), - (0x2FBD, 'M', '髟'), - (0x2FBE, 'M', '鬄'), - (0x2FBF, 'M', '鬯'), - (0x2FC0, 'M', '鬲'), - (0x2FC1, 'M', '鬼'), - (0x2FC2, 'M', '魚'), - (0x2FC3, 'M', '鳄'), - (0x2FC4, 'M', 'é¹µ'), - (0x2FC5, 'M', '鹿'), - (0x2FC6, 'M', 'éŗ„'), - (0x2FC7, 'M', 'éŗ»'), - (0x2FC8, 'M', '黃'), - (0x2FC9, 'M', '黍'), - (0x2FCA, 'M', '黑'), - (0x2FCB, 'M', '黹'), - (0x2FCC, 'M', '黽'), - (0x2FCD, 'M', '鼎'), - (0x2FCE, 'M', '鼓'), - (0x2FCF, 'M', 'é¼ '), - (0x2FD0, 'M', 'é¼»'), - (0x2FD1, 'M', '齊'), - (0x2FD2, 'M', '齒'), - (0x2FD3, 'M', '龍'), - (0x2FD4, 'M', '龜'), - (0x2FD5, 'M', 'é¾ '), - (0x2FD6, 'X'), - (0x3000, '3', ' '), - (0x3001, 'V'), - (0x3002, 'M', '.'), - (0x3003, 'V'), - (0x3036, 'M', '怒'), - (0x3037, 'V'), - (0x3038, 'M', '十'), + (0x2F7E, "M", "耒"), + (0x2F7F, "M", "耳"), + (0x2F80, "M", "聿"), + (0x2F81, "M", "肉"), + (0x2F82, "M", "臣"), + (0x2F83, "M", "自"), + (0x2F84, "M", "至"), + (0x2F85, "M", "臼"), + (0x2F86, "M", "舌"), + (0x2F87, "M", "舛"), + (0x2F88, "M", "舟"), + (0x2F89, "M", "艮"), + (0x2F8A, "M", "色"), + (0x2F8B, "M", "艸"), + (0x2F8C, "M", "虍"), + (0x2F8D, "M", "虫"), + (0x2F8E, "M", "蔀"), + (0x2F8F, "M", "蔌"), + (0x2F90, "M", "蔣"), + (0x2F91, "M", "脾"), + (0x2F92, "M", "見"), + (0x2F93, "M", "角"), + (0x2F94, "M", "言"), + (0x2F95, "M", "č°·"), + (0x2F96, "M", "豆"), + (0x2F97, "M", "豕"), + (0x2F98, "M", "č±ø"), + (0x2F99, "M", "č²"), + (0x2F9A, "M", "赤"), + (0x2F9B, "M", "čµ°"), + (0x2F9C, "M", "č¶³"), + (0x2F9D, "M", "čŗ«"), + (0x2F9E, "M", "車"), + (0x2F9F, "M", "č¾›"), + (0x2FA0, "M", "č¾°"), + (0x2FA1, "M", "č¾µ"), + (0x2FA2, "M", "邑"), + (0x2FA3, "M", "酉"), + (0x2FA4, "M", "釆"), + (0x2FA5, "M", "里"), + (0x2FA6, "M", "金"), + (0x2FA7, "M", "長"), + (0x2FA8, "M", "門"), + (0x2FA9, "M", "阜"), + (0x2FAA, "M", "隶"), + (0x2FAB, "M", "隹"), + (0x2FAC, "M", "雨"), + (0x2FAD, "M", "靑"), + (0x2FAE, "M", "非"), + (0x2FAF, "M", "面"), + (0x2FB0, "M", "革"), + (0x2FB1, "M", "韋"), + (0x2FB2, "M", "韭"), + (0x2FB3, "M", "音"), + (0x2FB4, "M", "頁"), + (0x2FB5, "M", "風"), + (0x2FB6, "M", "飛"), + (0x2FB7, "M", "食"), + (0x2FB8, "M", "首"), + (0x2FB9, "M", "香"), + (0x2FBA, "M", "馬"), + (0x2FBB, "M", "éŖØ"), + (0x2FBC, "M", "高"), + (0x2FBD, "M", "髟"), + (0x2FBE, "M", "鬄"), + (0x2FBF, "M", "鬯"), + (0x2FC0, "M", "鬲"), + (0x2FC1, "M", "鬼"), + (0x2FC2, "M", "魚"), + (0x2FC3, "M", "鳄"), + (0x2FC4, "M", "é¹µ"), + (0x2FC5, "M", "鹿"), + (0x2FC6, "M", "éŗ„"), + (0x2FC7, "M", "éŗ»"), + (0x2FC8, "M", "黃"), + (0x2FC9, "M", "黍"), + (0x2FCA, "M", "黑"), + (0x2FCB, "M", "黹"), + (0x2FCC, "M", "黽"), + (0x2FCD, "M", "鼎"), + (0x2FCE, "M", "鼓"), + (0x2FCF, "M", "é¼ "), + (0x2FD0, "M", "é¼»"), + (0x2FD1, "M", "齊"), + (0x2FD2, "M", "齒"), + (0x2FD3, "M", "龍"), + (0x2FD4, "M", "龜"), + (0x2FD5, "M", "é¾ "), + (0x2FD6, "X"), + (0x3000, "3", " "), + (0x3001, "V"), + (0x3002, "M", "."), + (0x3003, "V"), + (0x3036, "M", "怒"), + (0x3037, "V"), + (0x3038, "M", "十"), + (0x3039, "M", "卄"), + (0x303A, "M", "卅"), + (0x303B, "V"), + (0x3040, "X"), ] + def _seg_29() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x3039, 'M', '卄'), - (0x303A, 'M', '卅'), - (0x303B, 'V'), - (0x3040, 'X'), - (0x3041, 'V'), - (0x3097, 'X'), - (0x3099, 'V'), - (0x309B, '3', ' 悙'), - (0x309C, '3', ' 悚'), - (0x309D, 'V'), - (0x309F, 'M', '悈悊'), - (0x30A0, 'V'), - (0x30FF, 'M', 'ć‚³ćƒˆ'), - (0x3100, 'X'), - (0x3105, 'V'), - (0x3130, 'X'), - (0x3131, 'M', 'į„€'), - (0x3132, 'M', 'ᄁ'), - (0x3133, 'M', 'ᆪ'), - (0x3134, 'M', 'į„‚'), - (0x3135, 'M', 'ᆬ'), - (0x3136, 'M', 'ᆭ'), - (0x3137, 'M', 'į„ƒ'), - (0x3138, 'M', 'į„„'), - (0x3139, 'M', 'į„…'), - (0x313A, 'M', 'ᆰ'), - (0x313B, 'M', 'ᆱ'), - (0x313C, 'M', 'ᆲ'), - (0x313D, 'M', 'ᆳ'), - (0x313E, 'M', 'ᆓ'), - (0x313F, 'M', 'ᆵ'), - (0x3140, 'M', 'į„š'), - (0x3141, 'M', 'ᄆ'), - (0x3142, 'M', 'ᄇ'), - (0x3143, 'M', 'į„ˆ'), - (0x3144, 'M', 'į„”'), - (0x3145, 'M', 'ᄉ'), - (0x3146, 'M', 'į„Š'), - (0x3147, 'M', 'į„‹'), - (0x3148, 'M', 'į„Œ'), - (0x3149, 'M', 'į„'), - (0x314A, 'M', 'į„Ž'), - (0x314B, 'M', 'į„'), - (0x314C, 'M', 'ᄐ'), - (0x314D, 'M', 'į„‘'), - (0x314E, 'M', 'į„’'), - (0x314F, 'M', 'į…”'), - (0x3150, 'M', 'į…¢'), - (0x3151, 'M', 'į…£'), - (0x3152, 'M', 'į…¤'), - (0x3153, 'M', 'į…„'), - (0x3154, 'M', 'į…¦'), - (0x3155, 'M', 'į…§'), - (0x3156, 'M', 'į…Ø'), - (0x3157, 'M', 'į…©'), - (0x3158, 'M', 'į…Ŗ'), - (0x3159, 'M', 'į…«'), - (0x315A, 'M', 'į…¬'), - (0x315B, 'M', 'į…­'), - (0x315C, 'M', 'į…®'), - (0x315D, 'M', 'į…Æ'), - (0x315E, 'M', 'į…°'), - (0x315F, 'M', 'į…±'), - (0x3160, 'M', 'į…²'), - (0x3161, 'M', 'į…³'), - (0x3162, 'M', 'į…“'), - (0x3163, 'M', 'į…µ'), - (0x3164, 'X'), - (0x3165, 'M', 'į„”'), - (0x3166, 'M', 'į„•'), - (0x3167, 'M', 'ᇇ'), - (0x3168, 'M', 'į‡ˆ'), - (0x3169, 'M', 'į‡Œ'), - (0x316A, 'M', 'į‡Ž'), - (0x316B, 'M', 'ᇓ'), - (0x316C, 'M', 'ᇗ'), - (0x316D, 'M', 'ᇙ'), - (0x316E, 'M', 'į„œ'), - (0x316F, 'M', 'į‡'), - (0x3170, 'M', 'į‡Ÿ'), - (0x3171, 'M', 'į„'), - (0x3172, 'M', 'į„ž'), - (0x3173, 'M', 'į„ '), - (0x3174, 'M', 'į„¢'), - (0x3175, 'M', 'į„£'), - (0x3176, 'M', 'į„§'), - (0x3177, 'M', 'į„©'), - (0x3178, 'M', 'į„«'), - (0x3179, 'M', 'ᄬ'), - (0x317A, 'M', 'į„­'), - (0x317B, 'M', 'į„®'), - (0x317C, 'M', 'ᄯ'), - (0x317D, 'M', 'ᄲ'), - (0x317E, 'M', 'į„¶'), - (0x317F, 'M', 'į…€'), - (0x3180, 'M', 'į…‡'), - (0x3181, 'M', 'į…Œ'), - (0x3182, 'M', 'ᇱ'), - (0x3183, 'M', 'ᇲ'), - (0x3184, 'M', 'į…—'), + (0x3041, "V"), + (0x3097, "X"), + (0x3099, "V"), + (0x309B, "3", " 悙"), + (0x309C, "3", " 悚"), + (0x309D, "V"), + (0x309F, "M", "悈悊"), + (0x30A0, "V"), + (0x30FF, "M", "ć‚³ćƒˆ"), + (0x3100, "X"), + (0x3105, "V"), + (0x3130, "X"), + (0x3131, "M", "į„€"), + (0x3132, "M", "ᄁ"), + (0x3133, "M", "ᆪ"), + (0x3134, "M", "į„‚"), + (0x3135, "M", "ᆬ"), + (0x3136, "M", "ᆭ"), + (0x3137, "M", "į„ƒ"), + (0x3138, "M", "į„„"), + (0x3139, "M", "į„…"), + (0x313A, "M", "ᆰ"), + (0x313B, "M", "ᆱ"), + (0x313C, "M", "ᆲ"), + (0x313D, "M", "ᆳ"), + (0x313E, "M", "ᆓ"), + (0x313F, "M", "ᆵ"), + (0x3140, "M", "į„š"), + (0x3141, "M", "ᄆ"), + (0x3142, "M", "ᄇ"), + (0x3143, "M", "į„ˆ"), + (0x3144, "M", "į„”"), + (0x3145, "M", "ᄉ"), + (0x3146, "M", "į„Š"), + (0x3147, "M", "į„‹"), + (0x3148, "M", "į„Œ"), + (0x3149, "M", "į„"), + (0x314A, "M", "į„Ž"), + (0x314B, "M", "į„"), + (0x314C, "M", "ᄐ"), + (0x314D, "M", "į„‘"), + (0x314E, "M", "į„’"), + (0x314F, "M", "į…”"), + (0x3150, "M", "į…¢"), + (0x3151, "M", "į…£"), + (0x3152, "M", "į…¤"), + (0x3153, "M", "į…„"), + (0x3154, "M", "į…¦"), + (0x3155, "M", "į…§"), + (0x3156, "M", "į…Ø"), + (0x3157, "M", "į…©"), + (0x3158, "M", "į…Ŗ"), + (0x3159, "M", "į…«"), + (0x315A, "M", "į…¬"), + (0x315B, "M", "į…­"), + (0x315C, "M", "į…®"), + (0x315D, "M", "į…Æ"), + (0x315E, "M", "į…°"), + (0x315F, "M", "į…±"), + (0x3160, "M", "į…²"), + (0x3161, "M", "į…³"), + (0x3162, "M", "į…“"), + (0x3163, "M", "į…µ"), + (0x3164, "X"), + (0x3165, "M", "į„”"), + (0x3166, "M", "į„•"), + (0x3167, "M", "ᇇ"), + (0x3168, "M", "į‡ˆ"), + (0x3169, "M", "į‡Œ"), + (0x316A, "M", "į‡Ž"), + (0x316B, "M", "ᇓ"), + (0x316C, "M", "ᇗ"), + (0x316D, "M", "ᇙ"), + (0x316E, "M", "į„œ"), + (0x316F, "M", "į‡"), + (0x3170, "M", "į‡Ÿ"), + (0x3171, "M", "į„"), + (0x3172, "M", "į„ž"), + (0x3173, "M", "į„ "), + (0x3174, "M", "į„¢"), + (0x3175, "M", "į„£"), + (0x3176, "M", "į„§"), + (0x3177, "M", "į„©"), + (0x3178, "M", "į„«"), + (0x3179, "M", "ᄬ"), + (0x317A, "M", "į„­"), + (0x317B, "M", "į„®"), + (0x317C, "M", "ᄯ"), + (0x317D, "M", "ᄲ"), + (0x317E, "M", "į„¶"), + (0x317F, "M", "į…€"), + (0x3180, "M", "į…‡"), + (0x3181, "M", "į…Œ"), + (0x3182, "M", "ᇱ"), + (0x3183, "M", "ᇲ"), + (0x3184, "M", "į…—"), + (0x3185, "M", "į…˜"), + (0x3186, "M", "į…™"), + (0x3187, "M", "ᆄ"), + (0x3188, "M", "ᆅ"), ] + def _seg_30() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x3185, 'M', 'į…˜'), - (0x3186, 'M', 'į…™'), - (0x3187, 'M', 'ᆄ'), - (0x3188, 'M', 'ᆅ'), - (0x3189, 'M', 'į†ˆ'), - (0x318A, 'M', 'ᆑ'), - (0x318B, 'M', 'ᆒ'), - (0x318C, 'M', 'ᆔ'), - (0x318D, 'M', 'į†ž'), - (0x318E, 'M', 'ᆔ'), - (0x318F, 'X'), - (0x3190, 'V'), - (0x3192, 'M', 'äø€'), - (0x3193, 'M', '二'), - (0x3194, 'M', 'äø‰'), - (0x3195, 'M', '四'), - (0x3196, 'M', '上'), - (0x3197, 'M', 'äø­'), - (0x3198, 'M', 'äø‹'), - (0x3199, 'M', '甲'), - (0x319A, 'M', '乙'), - (0x319B, 'M', 'äø™'), - (0x319C, 'M', '丁'), - (0x319D, 'M', '天'), - (0x319E, 'M', '地'), - (0x319F, 'M', 'äŗŗ'), - (0x31A0, 'V'), - (0x31E4, 'X'), - (0x31F0, 'V'), - (0x3200, '3', '(į„€)'), - (0x3201, '3', '(į„‚)'), - (0x3202, '3', '(į„ƒ)'), - (0x3203, '3', '(į„…)'), - (0x3204, '3', '(ᄆ)'), - (0x3205, '3', '(ᄇ)'), - (0x3206, '3', '(ᄉ)'), - (0x3207, '3', '(į„‹)'), - (0x3208, '3', '(į„Œ)'), - (0x3209, '3', '(į„Ž)'), - (0x320A, '3', '(į„)'), - (0x320B, '3', '(ᄐ)'), - (0x320C, '3', '(į„‘)'), - (0x320D, '3', '(į„’)'), - (0x320E, '3', '(ź°€)'), - (0x320F, '3', '(ė‚˜)'), - (0x3210, '3', '(다)'), - (0x3211, '3', '(ė¼)'), - (0x3212, '3', '(마)'), - (0x3213, '3', '(ė°”)'), - (0x3214, '3', '(사)'), - (0x3215, '3', '(ģ•„)'), - (0x3216, '3', '(ģž)'), - (0x3217, '3', '(ģ°Ø)'), - (0x3218, '3', '(칓)'), - (0x3219, '3', '(ķƒ€)'), - (0x321A, '3', '(파)'), - (0x321B, '3', '(ķ•˜)'), - (0x321C, '3', '(주)'), - (0x321D, '3', '(ģ˜¤ģ „)'), - (0x321E, '3', '(ģ˜¤ķ›„)'), - (0x321F, 'X'), - (0x3220, '3', '(äø€)'), - (0x3221, '3', '(二)'), - (0x3222, '3', '(äø‰)'), - (0x3223, '3', '(四)'), - (0x3224, '3', '(äŗ”)'), - (0x3225, '3', '(六)'), - (0x3226, '3', '(七)'), - (0x3227, '3', '(八)'), - (0x3228, '3', '(九)'), - (0x3229, '3', '(十)'), - (0x322A, '3', '(月)'), - (0x322B, '3', '(火)'), - (0x322C, '3', '(ę°“)'), - (0x322D, '3', '(木)'), - (0x322E, '3', '(金)'), - (0x322F, '3', '(土)'), - (0x3230, '3', '(ę—„)'), - (0x3231, '3', '(ę Ŗ)'), - (0x3232, '3', '(꜉)'), - (0x3233, '3', '(社)'), - (0x3234, '3', '(名)'), - (0x3235, '3', '(特)'), - (0x3236, '3', '(č²”)'), - (0x3237, '3', '(ē„)'), - (0x3238, '3', '(劓)'), - (0x3239, '3', '(代)'), - (0x323A, '3', '(呼)'), - (0x323B, '3', '(å­¦)'), - (0x323C, '3', '(監)'), - (0x323D, '3', '(企)'), - (0x323E, '3', '(資)'), - (0x323F, '3', '(協)'), - (0x3240, '3', '(ē„­)'), - (0x3241, '3', '(休)'), - (0x3242, '3', '(自)'), - (0x3243, '3', '(至)'), - (0x3244, 'M', '問'), - (0x3245, 'M', 'å¹¼'), - (0x3246, 'M', 'ꖇ'), + (0x3189, "M", "į†ˆ"), + (0x318A, "M", "ᆑ"), + (0x318B, "M", "ᆒ"), + (0x318C, "M", "ᆔ"), + (0x318D, "M", "į†ž"), + (0x318E, "M", "ᆔ"), + (0x318F, "X"), + (0x3190, "V"), + (0x3192, "M", "äø€"), + (0x3193, "M", "二"), + (0x3194, "M", "äø‰"), + (0x3195, "M", "四"), + (0x3196, "M", "上"), + (0x3197, "M", "äø­"), + (0x3198, "M", "äø‹"), + (0x3199, "M", "甲"), + (0x319A, "M", "乙"), + (0x319B, "M", "äø™"), + (0x319C, "M", "丁"), + (0x319D, "M", "天"), + (0x319E, "M", "地"), + (0x319F, "M", "äŗŗ"), + (0x31A0, "V"), + (0x31E4, "X"), + (0x31F0, "V"), + (0x3200, "3", "(į„€)"), + (0x3201, "3", "(į„‚)"), + (0x3202, "3", "(į„ƒ)"), + (0x3203, "3", "(į„…)"), + (0x3204, "3", "(ᄆ)"), + (0x3205, "3", "(ᄇ)"), + (0x3206, "3", "(ᄉ)"), + (0x3207, "3", "(į„‹)"), + (0x3208, "3", "(į„Œ)"), + (0x3209, "3", "(į„Ž)"), + (0x320A, "3", "(į„)"), + (0x320B, "3", "(ᄐ)"), + (0x320C, "3", "(į„‘)"), + (0x320D, "3", "(į„’)"), + (0x320E, "3", "(ź°€)"), + (0x320F, "3", "(ė‚˜)"), + (0x3210, "3", "(다)"), + (0x3211, "3", "(ė¼)"), + (0x3212, "3", "(마)"), + (0x3213, "3", "(ė°”)"), + (0x3214, "3", "(사)"), + (0x3215, "3", "(ģ•„)"), + (0x3216, "3", "(ģž)"), + (0x3217, "3", "(ģ°Ø)"), + (0x3218, "3", "(칓)"), + (0x3219, "3", "(ķƒ€)"), + (0x321A, "3", "(파)"), + (0x321B, "3", "(ķ•˜)"), + (0x321C, "3", "(주)"), + (0x321D, "3", "(ģ˜¤ģ „)"), + (0x321E, "3", "(ģ˜¤ķ›„)"), + (0x321F, "X"), + (0x3220, "3", "(äø€)"), + (0x3221, "3", "(二)"), + (0x3222, "3", "(äø‰)"), + (0x3223, "3", "(四)"), + (0x3224, "3", "(äŗ”)"), + (0x3225, "3", "(六)"), + (0x3226, "3", "(七)"), + (0x3227, "3", "(八)"), + (0x3228, "3", "(九)"), + (0x3229, "3", "(十)"), + (0x322A, "3", "(月)"), + (0x322B, "3", "(火)"), + (0x322C, "3", "(ę°“)"), + (0x322D, "3", "(木)"), + (0x322E, "3", "(金)"), + (0x322F, "3", "(土)"), + (0x3230, "3", "(ę—„)"), + (0x3231, "3", "(ę Ŗ)"), + (0x3232, "3", "(꜉)"), + (0x3233, "3", "(社)"), + (0x3234, "3", "(名)"), + (0x3235, "3", "(特)"), + (0x3236, "3", "(č²”)"), + (0x3237, "3", "(ē„)"), + (0x3238, "3", "(劓)"), + (0x3239, "3", "(代)"), + (0x323A, "3", "(呼)"), + (0x323B, "3", "(å­¦)"), + (0x323C, "3", "(監)"), + (0x323D, "3", "(企)"), + (0x323E, "3", "(資)"), + (0x323F, "3", "(協)"), + (0x3240, "3", "(ē„­)"), + (0x3241, "3", "(休)"), + (0x3242, "3", "(自)"), + (0x3243, "3", "(至)"), + (0x3244, "M", "問"), + (0x3245, "M", "å¹¼"), + (0x3246, "M", "ꖇ"), + (0x3247, "M", "ē®"), + (0x3248, "V"), + (0x3250, "M", "pte"), + (0x3251, "M", "21"), ] + def _seg_31() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x3247, 'M', 'ē®'), - (0x3248, 'V'), - (0x3250, 'M', 'pte'), - (0x3251, 'M', '21'), - (0x3252, 'M', '22'), - (0x3253, 'M', '23'), - (0x3254, 'M', '24'), - (0x3255, 'M', '25'), - (0x3256, 'M', '26'), - (0x3257, 'M', '27'), - (0x3258, 'M', '28'), - (0x3259, 'M', '29'), - (0x325A, 'M', '30'), - (0x325B, 'M', '31'), - (0x325C, 'M', '32'), - (0x325D, 'M', '33'), - (0x325E, 'M', '34'), - (0x325F, 'M', '35'), - (0x3260, 'M', 'į„€'), - (0x3261, 'M', 'į„‚'), - (0x3262, 'M', 'į„ƒ'), - (0x3263, 'M', 'į„…'), - (0x3264, 'M', 'ᄆ'), - (0x3265, 'M', 'ᄇ'), - (0x3266, 'M', 'ᄉ'), - (0x3267, 'M', 'į„‹'), - (0x3268, 'M', 'į„Œ'), - (0x3269, 'M', 'į„Ž'), - (0x326A, 'M', 'į„'), - (0x326B, 'M', 'ᄐ'), - (0x326C, 'M', 'į„‘'), - (0x326D, 'M', 'į„’'), - (0x326E, 'M', 'ź°€'), - (0x326F, 'M', 'ė‚˜'), - (0x3270, 'M', '다'), - (0x3271, 'M', 'ė¼'), - (0x3272, 'M', '마'), - (0x3273, 'M', 'ė°”'), - (0x3274, 'M', '사'), - (0x3275, 'M', 'ģ•„'), - (0x3276, 'M', 'ģž'), - (0x3277, 'M', 'ģ°Ø'), - (0x3278, 'M', '칓'), - (0x3279, 'M', 'ķƒ€'), - (0x327A, 'M', '파'), - (0x327B, 'M', 'ķ•˜'), - (0x327C, 'M', 'ģ°øź³ '), - (0x327D, 'M', 'ģ£¼ģ˜'), - (0x327E, 'M', '우'), - (0x327F, 'V'), - (0x3280, 'M', 'äø€'), - (0x3281, 'M', '二'), - (0x3282, 'M', 'äø‰'), - (0x3283, 'M', '四'), - (0x3284, 'M', 'äŗ”'), - (0x3285, 'M', '六'), - (0x3286, 'M', '七'), - (0x3287, 'M', '八'), - (0x3288, 'M', '九'), - (0x3289, 'M', '十'), - (0x328A, 'M', '月'), - (0x328B, 'M', '火'), - (0x328C, 'M', 'ę°“'), - (0x328D, 'M', '木'), - (0x328E, 'M', '金'), - (0x328F, 'M', '土'), - (0x3290, 'M', 'ę—„'), - (0x3291, 'M', 'ę Ŗ'), - (0x3292, 'M', '꜉'), - (0x3293, 'M', '社'), - (0x3294, 'M', '名'), - (0x3295, 'M', '特'), - (0x3296, 'M', 'č²”'), - (0x3297, 'M', 'ē„'), - (0x3298, 'M', '劓'), - (0x3299, 'M', '秘'), - (0x329A, 'M', 'ē”·'), - (0x329B, 'M', '儳'), - (0x329C, 'M', '適'), - (0x329D, 'M', '優'), - (0x329E, 'M', '印'), - (0x329F, 'M', '注'), - (0x32A0, 'M', '項'), - (0x32A1, 'M', '休'), - (0x32A2, 'M', '写'), - (0x32A3, 'M', 'ę­£'), - (0x32A4, 'M', '上'), - (0x32A5, 'M', 'äø­'), - (0x32A6, 'M', 'äø‹'), - (0x32A7, 'M', 'å·¦'), - (0x32A8, 'M', '右'), - (0x32A9, 'M', '医'), - (0x32AA, 'M', '宗'), - (0x32AB, 'M', 'å­¦'), - (0x32AC, 'M', '監'), - (0x32AD, 'M', '企'), - (0x32AE, 'M', '資'), - (0x32AF, 'M', '協'), - (0x32B0, 'M', '夜'), - (0x32B1, 'M', '36'), + (0x3252, "M", "22"), + (0x3253, "M", "23"), + (0x3254, "M", "24"), + (0x3255, "M", "25"), + (0x3256, "M", "26"), + (0x3257, "M", "27"), + (0x3258, "M", "28"), + (0x3259, "M", "29"), + (0x325A, "M", "30"), + (0x325B, "M", "31"), + (0x325C, "M", "32"), + (0x325D, "M", "33"), + (0x325E, "M", "34"), + (0x325F, "M", "35"), + (0x3260, "M", "į„€"), + (0x3261, "M", "į„‚"), + (0x3262, "M", "į„ƒ"), + (0x3263, "M", "į„…"), + (0x3264, "M", "ᄆ"), + (0x3265, "M", "ᄇ"), + (0x3266, "M", "ᄉ"), + (0x3267, "M", "į„‹"), + (0x3268, "M", "į„Œ"), + (0x3269, "M", "į„Ž"), + (0x326A, "M", "į„"), + (0x326B, "M", "ᄐ"), + (0x326C, "M", "į„‘"), + (0x326D, "M", "į„’"), + (0x326E, "M", "ź°€"), + (0x326F, "M", "ė‚˜"), + (0x3270, "M", "다"), + (0x3271, "M", "ė¼"), + (0x3272, "M", "마"), + (0x3273, "M", "ė°”"), + (0x3274, "M", "사"), + (0x3275, "M", "ģ•„"), + (0x3276, "M", "ģž"), + (0x3277, "M", "ģ°Ø"), + (0x3278, "M", "칓"), + (0x3279, "M", "ķƒ€"), + (0x327A, "M", "파"), + (0x327B, "M", "ķ•˜"), + (0x327C, "M", "ģ°øź³ "), + (0x327D, "M", "ģ£¼ģ˜"), + (0x327E, "M", "우"), + (0x327F, "V"), + (0x3280, "M", "äø€"), + (0x3281, "M", "二"), + (0x3282, "M", "äø‰"), + (0x3283, "M", "四"), + (0x3284, "M", "äŗ”"), + (0x3285, "M", "六"), + (0x3286, "M", "七"), + (0x3287, "M", "八"), + (0x3288, "M", "九"), + (0x3289, "M", "十"), + (0x328A, "M", "月"), + (0x328B, "M", "火"), + (0x328C, "M", "ę°“"), + (0x328D, "M", "木"), + (0x328E, "M", "金"), + (0x328F, "M", "土"), + (0x3290, "M", "ę—„"), + (0x3291, "M", "ę Ŗ"), + (0x3292, "M", "꜉"), + (0x3293, "M", "社"), + (0x3294, "M", "名"), + (0x3295, "M", "特"), + (0x3296, "M", "č²”"), + (0x3297, "M", "ē„"), + (0x3298, "M", "劓"), + (0x3299, "M", "秘"), + (0x329A, "M", "ē”·"), + (0x329B, "M", "儳"), + (0x329C, "M", "適"), + (0x329D, "M", "優"), + (0x329E, "M", "印"), + (0x329F, "M", "注"), + (0x32A0, "M", "項"), + (0x32A1, "M", "休"), + (0x32A2, "M", "写"), + (0x32A3, "M", "ę­£"), + (0x32A4, "M", "上"), + (0x32A5, "M", "äø­"), + (0x32A6, "M", "äø‹"), + (0x32A7, "M", "å·¦"), + (0x32A8, "M", "右"), + (0x32A9, "M", "医"), + (0x32AA, "M", "宗"), + (0x32AB, "M", "å­¦"), + (0x32AC, "M", "監"), + (0x32AD, "M", "企"), + (0x32AE, "M", "資"), + (0x32AF, "M", "協"), + (0x32B0, "M", "夜"), + (0x32B1, "M", "36"), + (0x32B2, "M", "37"), + (0x32B3, "M", "38"), + (0x32B4, "M", "39"), + (0x32B5, "M", "40"), ] + def _seg_32() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x32B2, 'M', '37'), - (0x32B3, 'M', '38'), - (0x32B4, 'M', '39'), - (0x32B5, 'M', '40'), - (0x32B6, 'M', '41'), - (0x32B7, 'M', '42'), - (0x32B8, 'M', '43'), - (0x32B9, 'M', '44'), - (0x32BA, 'M', '45'), - (0x32BB, 'M', '46'), - (0x32BC, 'M', '47'), - (0x32BD, 'M', '48'), - (0x32BE, 'M', '49'), - (0x32BF, 'M', '50'), - (0x32C0, 'M', '1月'), - (0x32C1, 'M', '2月'), - (0x32C2, 'M', '3月'), - (0x32C3, 'M', '4月'), - (0x32C4, 'M', '5月'), - (0x32C5, 'M', '6月'), - (0x32C6, 'M', '7月'), - (0x32C7, 'M', '8月'), - (0x32C8, 'M', '9月'), - (0x32C9, 'M', '10月'), - (0x32CA, 'M', '11月'), - (0x32CB, 'M', '12月'), - (0x32CC, 'M', 'hg'), - (0x32CD, 'M', 'erg'), - (0x32CE, 'M', 'ev'), - (0x32CF, 'M', 'ltd'), - (0x32D0, 'M', 'ć‚¢'), - (0x32D1, 'M', '悤'), - (0x32D2, 'M', '悦'), - (0x32D3, 'M', 'エ'), - (0x32D4, 'M', 'オ'), - (0x32D5, 'M', 'ć‚«'), - (0x32D6, 'M', '悭'), - (0x32D7, 'M', 'ク'), - (0x32D8, 'M', '悱'), - (0x32D9, 'M', 'コ'), - (0x32DA, 'M', '悵'), - (0x32DB, 'M', 'ć‚·'), - (0x32DC, 'M', 'ス'), - (0x32DD, 'M', 'ć‚»'), - (0x32DE, 'M', 'ソ'), - (0x32DF, 'M', 'タ'), - (0x32E0, 'M', '惁'), - (0x32E1, 'M', '惄'), - (0x32E2, 'M', '惆'), - (0x32E3, 'M', '惈'), - (0x32E4, 'M', 'ナ'), - (0x32E5, 'M', '惋'), - (0x32E6, 'M', 'ヌ'), - (0x32E7, 'M', '惍'), - (0x32E8, 'M', '惎'), - (0x32E9, 'M', '惏'), - (0x32EA, 'M', '惒'), - (0x32EB, 'M', '惕'), - (0x32EC, 'M', '惘'), - (0x32ED, 'M', '惛'), - (0x32EE, 'M', '惞'), - (0x32EF, 'M', 'ミ'), - (0x32F0, 'M', '惠'), - (0x32F1, 'M', '惔'), - (0x32F2, 'M', 'モ'), - (0x32F3, 'M', '惤'), - (0x32F4, 'M', '惦'), - (0x32F5, 'M', 'ヨ'), - (0x32F6, 'M', '惩'), - (0x32F7, 'M', 'リ'), - (0x32F8, 'M', '惫'), - (0x32F9, 'M', '惬'), - (0x32FA, 'M', '惭'), - (0x32FB, 'M', 'ワ'), - (0x32FC, 'M', '惰'), - (0x32FD, 'M', '惱'), - (0x32FE, 'M', 'ヲ'), - (0x32FF, 'M', '令和'), - (0x3300, 'M', 'ć‚¢ćƒ‘ćƒ¼ćƒˆ'), - (0x3301, 'M', 'ć‚¢ćƒ«ćƒ•ć‚”'), - (0x3302, 'M', 'ć‚¢ćƒ³ćƒšć‚¢'), - (0x3303, 'M', 'ć‚¢ćƒ¼ćƒ«'), - (0x3304, 'M', 'ć‚¤ćƒ‹ćƒ³ć‚°'), - (0x3305, 'M', 'ć‚¤ćƒ³ćƒ'), - (0x3306, 'M', 'ć‚¦ć‚©ćƒ³'), - (0x3307, 'M', 'ć‚Øć‚¹ć‚Æćƒ¼ćƒ‰'), - (0x3308, 'M', 'ć‚Øćƒ¼ć‚«ćƒ¼'), - (0x3309, 'M', 'ć‚Ŗćƒ³ć‚¹'), - (0x330A, 'M', 'ć‚Ŗćƒ¼ćƒ '), - (0x330B, 'M', 'ć‚«ć‚¤ćƒŖ'), - (0x330C, 'M', 'ć‚«ćƒ©ćƒƒćƒˆ'), - (0x330D, 'M', 'ć‚«ćƒ­ćƒŖćƒ¼'), - (0x330E, 'M', 'ć‚¬ćƒ­ćƒ³'), - (0x330F, 'M', 'ć‚¬ćƒ³ćƒž'), - (0x3310, 'M', '悮悬'), - (0x3311, 'M', 'ć‚®ćƒ‹ćƒ¼'), - (0x3312, 'M', 'ć‚­ćƒ„ćƒŖćƒ¼'), - (0x3313, 'M', 'ć‚®ćƒ«ćƒ€ćƒ¼'), - (0x3314, 'M', '悭惭'), - (0x3315, 'M', 'ć‚­ćƒ­ć‚°ćƒ©ćƒ '), + (0x32B6, "M", "41"), + (0x32B7, "M", "42"), + (0x32B8, "M", "43"), + (0x32B9, "M", "44"), + (0x32BA, "M", "45"), + (0x32BB, "M", "46"), + (0x32BC, "M", "47"), + (0x32BD, "M", "48"), + (0x32BE, "M", "49"), + (0x32BF, "M", "50"), + (0x32C0, "M", "1月"), + (0x32C1, "M", "2月"), + (0x32C2, "M", "3月"), + (0x32C3, "M", "4月"), + (0x32C4, "M", "5月"), + (0x32C5, "M", "6月"), + (0x32C6, "M", "7月"), + (0x32C7, "M", "8月"), + (0x32C8, "M", "9月"), + (0x32C9, "M", "10月"), + (0x32CA, "M", "11月"), + (0x32CB, "M", "12月"), + (0x32CC, "M", "hg"), + (0x32CD, "M", "erg"), + (0x32CE, "M", "ev"), + (0x32CF, "M", "ltd"), + (0x32D0, "M", "ć‚¢"), + (0x32D1, "M", "悤"), + (0x32D2, "M", "悦"), + (0x32D3, "M", "エ"), + (0x32D4, "M", "オ"), + (0x32D5, "M", "ć‚«"), + (0x32D6, "M", "悭"), + (0x32D7, "M", "ク"), + (0x32D8, "M", "悱"), + (0x32D9, "M", "コ"), + (0x32DA, "M", "悵"), + (0x32DB, "M", "ć‚·"), + (0x32DC, "M", "ス"), + (0x32DD, "M", "ć‚»"), + (0x32DE, "M", "ソ"), + (0x32DF, "M", "タ"), + (0x32E0, "M", "惁"), + (0x32E1, "M", "惄"), + (0x32E2, "M", "惆"), + (0x32E3, "M", "惈"), + (0x32E4, "M", "ナ"), + (0x32E5, "M", "惋"), + (0x32E6, "M", "ヌ"), + (0x32E7, "M", "惍"), + (0x32E8, "M", "惎"), + (0x32E9, "M", "惏"), + (0x32EA, "M", "惒"), + (0x32EB, "M", "惕"), + (0x32EC, "M", "惘"), + (0x32ED, "M", "惛"), + (0x32EE, "M", "惞"), + (0x32EF, "M", "ミ"), + (0x32F0, "M", "惠"), + (0x32F1, "M", "惔"), + (0x32F2, "M", "モ"), + (0x32F3, "M", "惤"), + (0x32F4, "M", "惦"), + (0x32F5, "M", "ヨ"), + (0x32F6, "M", "惩"), + (0x32F7, "M", "リ"), + (0x32F8, "M", "惫"), + (0x32F9, "M", "惬"), + (0x32FA, "M", "惭"), + (0x32FB, "M", "ワ"), + (0x32FC, "M", "惰"), + (0x32FD, "M", "惱"), + (0x32FE, "M", "ヲ"), + (0x32FF, "M", "令和"), + (0x3300, "M", "ć‚¢ćƒ‘ćƒ¼ćƒˆ"), + (0x3301, "M", "ć‚¢ćƒ«ćƒ•ć‚”"), + (0x3302, "M", "ć‚¢ćƒ³ćƒšć‚¢"), + (0x3303, "M", "ć‚¢ćƒ¼ćƒ«"), + (0x3304, "M", "ć‚¤ćƒ‹ćƒ³ć‚°"), + (0x3305, "M", "ć‚¤ćƒ³ćƒ"), + (0x3306, "M", "ć‚¦ć‚©ćƒ³"), + (0x3307, "M", "ć‚Øć‚¹ć‚Æćƒ¼ćƒ‰"), + (0x3308, "M", "ć‚Øćƒ¼ć‚«ćƒ¼"), + (0x3309, "M", "ć‚Ŗćƒ³ć‚¹"), + (0x330A, "M", "ć‚Ŗćƒ¼ćƒ "), + (0x330B, "M", "ć‚«ć‚¤ćƒŖ"), + (0x330C, "M", "ć‚«ćƒ©ćƒƒćƒˆ"), + (0x330D, "M", "ć‚«ćƒ­ćƒŖćƒ¼"), + (0x330E, "M", "ć‚¬ćƒ­ćƒ³"), + (0x330F, "M", "ć‚¬ćƒ³ćƒž"), + (0x3310, "M", "悮悬"), + (0x3311, "M", "ć‚®ćƒ‹ćƒ¼"), + (0x3312, "M", "ć‚­ćƒ„ćƒŖćƒ¼"), + (0x3313, "M", "ć‚®ćƒ«ćƒ€ćƒ¼"), + (0x3314, "M", "悭惭"), + (0x3315, "M", "ć‚­ćƒ­ć‚°ćƒ©ćƒ "), + (0x3316, "M", "ć‚­ćƒ­ćƒ”ćƒ¼ćƒˆćƒ«"), + (0x3317, "M", "ć‚­ćƒ­ćƒÆćƒƒćƒˆ"), + (0x3318, "M", "ć‚°ćƒ©ćƒ "), + (0x3319, "M", "ć‚°ćƒ©ćƒ ćƒˆćƒ³"), ] + def _seg_33() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x3316, 'M', 'ć‚­ćƒ­ćƒ”ćƒ¼ćƒˆćƒ«'), - (0x3317, 'M', 'ć‚­ćƒ­ćƒÆćƒƒćƒˆ'), - (0x3318, 'M', 'ć‚°ćƒ©ćƒ '), - (0x3319, 'M', 'ć‚°ćƒ©ćƒ ćƒˆćƒ³'), - (0x331A, 'M', 'ć‚Æćƒ«ć‚¼ć‚¤ćƒ­'), - (0x331B, 'M', 'ć‚Æćƒ­ćƒ¼ćƒ'), - (0x331C, 'M', 'ć‚±ćƒ¼ć‚¹'), - (0x331D, 'M', 'ć‚³ćƒ«ćƒŠ'), - (0x331E, 'M', 'ć‚³ćƒ¼ćƒ'), - (0x331F, 'M', 'ć‚µć‚¤ć‚Æćƒ«'), - (0x3320, 'M', 'ć‚µćƒ³ćƒćƒ¼ćƒ '), - (0x3321, 'M', 'ć‚·ćƒŖćƒ³ć‚°'), - (0x3322, 'M', 'ć‚»ćƒ³ćƒ'), - (0x3323, 'M', 'ć‚»ćƒ³ćƒˆ'), - (0x3324, 'M', 'ćƒ€ćƒ¼ć‚¹'), - (0x3325, 'M', 'ćƒ‡ć‚·'), - (0x3326, 'M', 'ćƒ‰ćƒ«'), - (0x3327, 'M', 'トン'), - (0x3328, 'M', '惊惎'), - (0x3329, 'M', '惎惃惈'), - (0x332A, 'M', '惏悤惄'), - (0x332B, 'M', 'ćƒ‘ćƒ¼ć‚»ćƒ³ćƒˆ'), - (0x332C, 'M', 'ćƒ‘ćƒ¼ćƒ„'), - (0x332D, 'M', 'バーレル'), - (0x332E, 'M', 'ćƒ”ć‚¢ć‚¹ćƒˆćƒ«'), - (0x332F, 'M', 'ćƒ”ć‚Æćƒ«'), - (0x3330, 'M', 'ćƒ”ć‚³'), - (0x3331, 'M', 'ćƒ“ćƒ«'), - (0x3332, 'M', 'ćƒ•ć‚”ćƒ©ćƒƒćƒ‰'), - (0x3333, 'M', 'ćƒ•ć‚£ćƒ¼ćƒˆ'), - (0x3334, 'M', 'ćƒ–ćƒƒć‚·ć‚§ćƒ«'), - (0x3335, 'M', 'ćƒ•ćƒ©ćƒ³'), - (0x3336, 'M', 'ćƒ˜ć‚Æć‚æćƒ¼ćƒ«'), - (0x3337, 'M', 'ćƒšć‚½'), - (0x3338, 'M', '惚惋惒'), - (0x3339, 'M', 'ćƒ˜ćƒ«ćƒ„'), - (0x333A, 'M', 'ćƒšćƒ³ć‚¹'), - (0x333B, 'M', 'ćƒšćƒ¼ć‚ø'), - (0x333C, 'M', 'ćƒ™ćƒ¼ć‚æ'), - (0x333D, 'M', 'ćƒć‚¤ćƒ³ćƒˆ'), - (0x333E, 'M', 'ボルト'), - (0x333F, 'M', 'ćƒ›ćƒ³'), - (0x3340, 'M', 'ćƒćƒ³ćƒ‰'), - (0x3341, 'M', 'ćƒ›ćƒ¼ćƒ«'), - (0x3342, 'M', 'ćƒ›ćƒ¼ćƒ³'), - (0x3343, 'M', 'ćƒžć‚¤ć‚Æćƒ­'), - (0x3344, 'M', 'ćƒžć‚¤ćƒ«'), - (0x3345, 'M', '惞惃惏'), - (0x3346, 'M', 'ćƒžćƒ«ć‚Æ'), - (0x3347, 'M', 'ćƒžćƒ³ć‚·ćƒ§ćƒ³'), - (0x3348, 'M', 'ćƒŸć‚Æćƒ­ćƒ³'), - (0x3349, 'M', 'ミリ'), - (0x334A, 'M', 'ミリバール'), - (0x334B, 'M', 'ćƒ”ć‚¬'), - (0x334C, 'M', 'ćƒ”ć‚¬ćƒˆćƒ³'), - (0x334D, 'M', 'ピートル'), - (0x334E, 'M', 'ćƒ¤ćƒ¼ćƒ‰'), - (0x334F, 'M', 'ヤール'), - (0x3350, 'M', 'ćƒ¦ć‚¢ćƒ³'), - (0x3351, 'M', 'リットル'), - (0x3352, 'M', 'リラ'), - (0x3353, 'M', 'ćƒ«ćƒ”ćƒ¼'), - (0x3354, 'M', 'ćƒ«ćƒ¼ćƒ–ćƒ«'), - (0x3355, 'M', '惬惠'), - (0x3356, 'M', 'ćƒ¬ćƒ³ćƒˆć‚²ćƒ³'), - (0x3357, 'M', 'ワット'), - (0x3358, 'M', '0点'), - (0x3359, 'M', '1点'), - (0x335A, 'M', '2点'), - (0x335B, 'M', '3点'), - (0x335C, 'M', '4点'), - (0x335D, 'M', '5点'), - (0x335E, 'M', '6点'), - (0x335F, 'M', '7点'), - (0x3360, 'M', '8点'), - (0x3361, 'M', '9点'), - (0x3362, 'M', '10点'), - (0x3363, 'M', '11点'), - (0x3364, 'M', '12点'), - (0x3365, 'M', '13点'), - (0x3366, 'M', '14点'), - (0x3367, 'M', '15点'), - (0x3368, 'M', '16点'), - (0x3369, 'M', '17点'), - (0x336A, 'M', '18点'), - (0x336B, 'M', '19点'), - (0x336C, 'M', '20点'), - (0x336D, 'M', '21点'), - (0x336E, 'M', '22点'), - (0x336F, 'M', '23点'), - (0x3370, 'M', '24点'), - (0x3371, 'M', 'hpa'), - (0x3372, 'M', 'da'), - (0x3373, 'M', 'au'), - (0x3374, 'M', 'bar'), - (0x3375, 'M', 'ov'), - (0x3376, 'M', 'pc'), - (0x3377, 'M', 'dm'), - (0x3378, 'M', 'dm2'), - (0x3379, 'M', 'dm3'), + (0x331A, "M", "ć‚Æćƒ«ć‚¼ć‚¤ćƒ­"), + (0x331B, "M", "ć‚Æćƒ­ćƒ¼ćƒ"), + (0x331C, "M", "ć‚±ćƒ¼ć‚¹"), + (0x331D, "M", "ć‚³ćƒ«ćƒŠ"), + (0x331E, "M", "ć‚³ćƒ¼ćƒ"), + (0x331F, "M", "ć‚µć‚¤ć‚Æćƒ«"), + (0x3320, "M", "ć‚µćƒ³ćƒćƒ¼ćƒ "), + (0x3321, "M", "ć‚·ćƒŖćƒ³ć‚°"), + (0x3322, "M", "ć‚»ćƒ³ćƒ"), + (0x3323, "M", "ć‚»ćƒ³ćƒˆ"), + (0x3324, "M", "ćƒ€ćƒ¼ć‚¹"), + (0x3325, "M", "ćƒ‡ć‚·"), + (0x3326, "M", "ćƒ‰ćƒ«"), + (0x3327, "M", "トン"), + (0x3328, "M", "惊惎"), + (0x3329, "M", "惎惃惈"), + (0x332A, "M", "惏悤惄"), + (0x332B, "M", "ćƒ‘ćƒ¼ć‚»ćƒ³ćƒˆ"), + (0x332C, "M", "ćƒ‘ćƒ¼ćƒ„"), + (0x332D, "M", "バーレル"), + (0x332E, "M", "ćƒ”ć‚¢ć‚¹ćƒˆćƒ«"), + (0x332F, "M", "ćƒ”ć‚Æćƒ«"), + (0x3330, "M", "ćƒ”ć‚³"), + (0x3331, "M", "ćƒ“ćƒ«"), + (0x3332, "M", "ćƒ•ć‚”ćƒ©ćƒƒćƒ‰"), + (0x3333, "M", "ćƒ•ć‚£ćƒ¼ćƒˆ"), + (0x3334, "M", "ćƒ–ćƒƒć‚·ć‚§ćƒ«"), + (0x3335, "M", "ćƒ•ćƒ©ćƒ³"), + (0x3336, "M", "ćƒ˜ć‚Æć‚æćƒ¼ćƒ«"), + (0x3337, "M", "ćƒšć‚½"), + (0x3338, "M", "惚惋惒"), + (0x3339, "M", "ćƒ˜ćƒ«ćƒ„"), + (0x333A, "M", "ćƒšćƒ³ć‚¹"), + (0x333B, "M", "ćƒšćƒ¼ć‚ø"), + (0x333C, "M", "ćƒ™ćƒ¼ć‚æ"), + (0x333D, "M", "ćƒć‚¤ćƒ³ćƒˆ"), + (0x333E, "M", "ボルト"), + (0x333F, "M", "ćƒ›ćƒ³"), + (0x3340, "M", "ćƒćƒ³ćƒ‰"), + (0x3341, "M", "ćƒ›ćƒ¼ćƒ«"), + (0x3342, "M", "ćƒ›ćƒ¼ćƒ³"), + (0x3343, "M", "ćƒžć‚¤ć‚Æćƒ­"), + (0x3344, "M", "ćƒžć‚¤ćƒ«"), + (0x3345, "M", "惞惃惏"), + (0x3346, "M", "ćƒžćƒ«ć‚Æ"), + (0x3347, "M", "ćƒžćƒ³ć‚·ćƒ§ćƒ³"), + (0x3348, "M", "ćƒŸć‚Æćƒ­ćƒ³"), + (0x3349, "M", "ミリ"), + (0x334A, "M", "ミリバール"), + (0x334B, "M", "ćƒ”ć‚¬"), + (0x334C, "M", "ćƒ”ć‚¬ćƒˆćƒ³"), + (0x334D, "M", "ピートル"), + (0x334E, "M", "ćƒ¤ćƒ¼ćƒ‰"), + (0x334F, "M", "ヤール"), + (0x3350, "M", "ćƒ¦ć‚¢ćƒ³"), + (0x3351, "M", "リットル"), + (0x3352, "M", "リラ"), + (0x3353, "M", "ćƒ«ćƒ”ćƒ¼"), + (0x3354, "M", "ćƒ«ćƒ¼ćƒ–ćƒ«"), + (0x3355, "M", "惬惠"), + (0x3356, "M", "ćƒ¬ćƒ³ćƒˆć‚²ćƒ³"), + (0x3357, "M", "ワット"), + (0x3358, "M", "0点"), + (0x3359, "M", "1点"), + (0x335A, "M", "2点"), + (0x335B, "M", "3点"), + (0x335C, "M", "4点"), + (0x335D, "M", "5点"), + (0x335E, "M", "6点"), + (0x335F, "M", "7点"), + (0x3360, "M", "8点"), + (0x3361, "M", "9点"), + (0x3362, "M", "10点"), + (0x3363, "M", "11点"), + (0x3364, "M", "12点"), + (0x3365, "M", "13点"), + (0x3366, "M", "14点"), + (0x3367, "M", "15点"), + (0x3368, "M", "16点"), + (0x3369, "M", "17点"), + (0x336A, "M", "18点"), + (0x336B, "M", "19点"), + (0x336C, "M", "20点"), + (0x336D, "M", "21点"), + (0x336E, "M", "22点"), + (0x336F, "M", "23点"), + (0x3370, "M", "24点"), + (0x3371, "M", "hpa"), + (0x3372, "M", "da"), + (0x3373, "M", "au"), + (0x3374, "M", "bar"), + (0x3375, "M", "ov"), + (0x3376, "M", "pc"), + (0x3377, "M", "dm"), + (0x3378, "M", "dm2"), + (0x3379, "M", "dm3"), + (0x337A, "M", "iu"), + (0x337B, "M", "平成"), + (0x337C, "M", "ę˜­å’Œ"), + (0x337D, "M", "大正"), ] + def _seg_34() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x337A, 'M', 'iu'), - (0x337B, 'M', '平成'), - (0x337C, 'M', 'ę˜­å’Œ'), - (0x337D, 'M', '大正'), - (0x337E, 'M', 'ę˜Žę²»'), - (0x337F, 'M', 'ę Ŗå¼ä¼šē¤¾'), - (0x3380, 'M', 'pa'), - (0x3381, 'M', 'na'), - (0x3382, 'M', 'μa'), - (0x3383, 'M', 'ma'), - (0x3384, 'M', 'ka'), - (0x3385, 'M', 'kb'), - (0x3386, 'M', 'mb'), - (0x3387, 'M', 'gb'), - (0x3388, 'M', 'cal'), - (0x3389, 'M', 'kcal'), - (0x338A, 'M', 'pf'), - (0x338B, 'M', 'nf'), - (0x338C, 'M', 'μf'), - (0x338D, 'M', 'μg'), - (0x338E, 'M', 'mg'), - (0x338F, 'M', 'kg'), - (0x3390, 'M', 'hz'), - (0x3391, 'M', 'khz'), - (0x3392, 'M', 'mhz'), - (0x3393, 'M', 'ghz'), - (0x3394, 'M', 'thz'), - (0x3395, 'M', 'μl'), - (0x3396, 'M', 'ml'), - (0x3397, 'M', 'dl'), - (0x3398, 'M', 'kl'), - (0x3399, 'M', 'fm'), - (0x339A, 'M', 'nm'), - (0x339B, 'M', 'μm'), - (0x339C, 'M', 'mm'), - (0x339D, 'M', 'cm'), - (0x339E, 'M', 'km'), - (0x339F, 'M', 'mm2'), - (0x33A0, 'M', 'cm2'), - (0x33A1, 'M', 'm2'), - (0x33A2, 'M', 'km2'), - (0x33A3, 'M', 'mm3'), - (0x33A4, 'M', 'cm3'), - (0x33A5, 'M', 'm3'), - (0x33A6, 'M', 'km3'), - (0x33A7, 'M', 'māˆ•s'), - (0x33A8, 'M', 'māˆ•s2'), - (0x33A9, 'M', 'pa'), - (0x33AA, 'M', 'kpa'), - (0x33AB, 'M', 'mpa'), - (0x33AC, 'M', 'gpa'), - (0x33AD, 'M', 'rad'), - (0x33AE, 'M', 'radāˆ•s'), - (0x33AF, 'M', 'radāˆ•s2'), - (0x33B0, 'M', 'ps'), - (0x33B1, 'M', 'ns'), - (0x33B2, 'M', 'μs'), - (0x33B3, 'M', 'ms'), - (0x33B4, 'M', 'pv'), - (0x33B5, 'M', 'nv'), - (0x33B6, 'M', 'μv'), - (0x33B7, 'M', 'mv'), - (0x33B8, 'M', 'kv'), - (0x33B9, 'M', 'mv'), - (0x33BA, 'M', 'pw'), - (0x33BB, 'M', 'nw'), - (0x33BC, 'M', 'μw'), - (0x33BD, 'M', 'mw'), - (0x33BE, 'M', 'kw'), - (0x33BF, 'M', 'mw'), - (0x33C0, 'M', 'kω'), - (0x33C1, 'M', 'mω'), - (0x33C2, 'X'), - (0x33C3, 'M', 'bq'), - (0x33C4, 'M', 'cc'), - (0x33C5, 'M', 'cd'), - (0x33C6, 'M', 'cāˆ•kg'), - (0x33C7, 'X'), - (0x33C8, 'M', 'db'), - (0x33C9, 'M', 'gy'), - (0x33CA, 'M', 'ha'), - (0x33CB, 'M', 'hp'), - (0x33CC, 'M', 'in'), - (0x33CD, 'M', 'kk'), - (0x33CE, 'M', 'km'), - (0x33CF, 'M', 'kt'), - (0x33D0, 'M', 'lm'), - (0x33D1, 'M', 'ln'), - (0x33D2, 'M', 'log'), - (0x33D3, 'M', 'lx'), - (0x33D4, 'M', 'mb'), - (0x33D5, 'M', 'mil'), - (0x33D6, 'M', 'mol'), - (0x33D7, 'M', 'ph'), - (0x33D8, 'X'), - (0x33D9, 'M', 'ppm'), - (0x33DA, 'M', 'pr'), - (0x33DB, 'M', 'sr'), - (0x33DC, 'M', 'sv'), - (0x33DD, 'M', 'wb'), + (0x337E, "M", "ę˜Žę²»"), + (0x337F, "M", "ę Ŗå¼ä¼šē¤¾"), + (0x3380, "M", "pa"), + (0x3381, "M", "na"), + (0x3382, "M", "μa"), + (0x3383, "M", "ma"), + (0x3384, "M", "ka"), + (0x3385, "M", "kb"), + (0x3386, "M", "mb"), + (0x3387, "M", "gb"), + (0x3388, "M", "cal"), + (0x3389, "M", "kcal"), + (0x338A, "M", "pf"), + (0x338B, "M", "nf"), + (0x338C, "M", "μf"), + (0x338D, "M", "μg"), + (0x338E, "M", "mg"), + (0x338F, "M", "kg"), + (0x3390, "M", "hz"), + (0x3391, "M", "khz"), + (0x3392, "M", "mhz"), + (0x3393, "M", "ghz"), + (0x3394, "M", "thz"), + (0x3395, "M", "μl"), + (0x3396, "M", "ml"), + (0x3397, "M", "dl"), + (0x3398, "M", "kl"), + (0x3399, "M", "fm"), + (0x339A, "M", "nm"), + (0x339B, "M", "μm"), + (0x339C, "M", "mm"), + (0x339D, "M", "cm"), + (0x339E, "M", "km"), + (0x339F, "M", "mm2"), + (0x33A0, "M", "cm2"), + (0x33A1, "M", "m2"), + (0x33A2, "M", "km2"), + (0x33A3, "M", "mm3"), + (0x33A4, "M", "cm3"), + (0x33A5, "M", "m3"), + (0x33A6, "M", "km3"), + (0x33A7, "M", "māˆ•s"), + (0x33A8, "M", "māˆ•s2"), + (0x33A9, "M", "pa"), + (0x33AA, "M", "kpa"), + (0x33AB, "M", "mpa"), + (0x33AC, "M", "gpa"), + (0x33AD, "M", "rad"), + (0x33AE, "M", "radāˆ•s"), + (0x33AF, "M", "radāˆ•s2"), + (0x33B0, "M", "ps"), + (0x33B1, "M", "ns"), + (0x33B2, "M", "μs"), + (0x33B3, "M", "ms"), + (0x33B4, "M", "pv"), + (0x33B5, "M", "nv"), + (0x33B6, "M", "μv"), + (0x33B7, "M", "mv"), + (0x33B8, "M", "kv"), + (0x33B9, "M", "mv"), + (0x33BA, "M", "pw"), + (0x33BB, "M", "nw"), + (0x33BC, "M", "μw"), + (0x33BD, "M", "mw"), + (0x33BE, "M", "kw"), + (0x33BF, "M", "mw"), + (0x33C0, "M", "kω"), + (0x33C1, "M", "mω"), + (0x33C2, "X"), + (0x33C3, "M", "bq"), + (0x33C4, "M", "cc"), + (0x33C5, "M", "cd"), + (0x33C6, "M", "cāˆ•kg"), + (0x33C7, "X"), + (0x33C8, "M", "db"), + (0x33C9, "M", "gy"), + (0x33CA, "M", "ha"), + (0x33CB, "M", "hp"), + (0x33CC, "M", "in"), + (0x33CD, "M", "kk"), + (0x33CE, "M", "km"), + (0x33CF, "M", "kt"), + (0x33D0, "M", "lm"), + (0x33D1, "M", "ln"), + (0x33D2, "M", "log"), + (0x33D3, "M", "lx"), + (0x33D4, "M", "mb"), + (0x33D5, "M", "mil"), + (0x33D6, "M", "mol"), + (0x33D7, "M", "ph"), + (0x33D8, "X"), + (0x33D9, "M", "ppm"), + (0x33DA, "M", "pr"), + (0x33DB, "M", "sr"), + (0x33DC, "M", "sv"), + (0x33DD, "M", "wb"), + (0x33DE, "M", "vāˆ•m"), + (0x33DF, "M", "aāˆ•m"), + (0x33E0, "M", "1ę—„"), + (0x33E1, "M", "2ę—„"), ] + def _seg_35() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x33DE, 'M', 'vāˆ•m'), - (0x33DF, 'M', 'aāˆ•m'), - (0x33E0, 'M', '1ę—„'), - (0x33E1, 'M', '2ę—„'), - (0x33E2, 'M', '3ę—„'), - (0x33E3, 'M', '4ę—„'), - (0x33E4, 'M', '5ę—„'), - (0x33E5, 'M', '6ę—„'), - (0x33E6, 'M', '7ę—„'), - (0x33E7, 'M', '8ę—„'), - (0x33E8, 'M', '9ę—„'), - (0x33E9, 'M', '10ę—„'), - (0x33EA, 'M', '11ę—„'), - (0x33EB, 'M', '12ę—„'), - (0x33EC, 'M', '13ę—„'), - (0x33ED, 'M', '14ę—„'), - (0x33EE, 'M', '15ę—„'), - (0x33EF, 'M', '16ę—„'), - (0x33F0, 'M', '17ę—„'), - (0x33F1, 'M', '18ę—„'), - (0x33F2, 'M', '19ę—„'), - (0x33F3, 'M', '20ę—„'), - (0x33F4, 'M', '21ę—„'), - (0x33F5, 'M', '22ę—„'), - (0x33F6, 'M', '23ę—„'), - (0x33F7, 'M', '24ę—„'), - (0x33F8, 'M', '25ę—„'), - (0x33F9, 'M', '26ę—„'), - (0x33FA, 'M', '27ę—„'), - (0x33FB, 'M', '28ę—„'), - (0x33FC, 'M', '29ę—„'), - (0x33FD, 'M', '30ę—„'), - (0x33FE, 'M', '31ę—„'), - (0x33FF, 'M', 'gal'), - (0x3400, 'V'), - (0xA48D, 'X'), - (0xA490, 'V'), - (0xA4C7, 'X'), - (0xA4D0, 'V'), - (0xA62C, 'X'), - (0xA640, 'M', 'ꙁ'), - (0xA641, 'V'), - (0xA642, 'M', 'ź™ƒ'), - (0xA643, 'V'), - (0xA644, 'M', 'ź™…'), - (0xA645, 'V'), - (0xA646, 'M', 'ꙇ'), - (0xA647, 'V'), - (0xA648, 'M', 'ꙉ'), - (0xA649, 'V'), - (0xA64A, 'M', 'ꙋ'), - (0xA64B, 'V'), - (0xA64C, 'M', 'ź™'), - (0xA64D, 'V'), - (0xA64E, 'M', 'ź™'), - (0xA64F, 'V'), - (0xA650, 'M', 'ꙑ'), - (0xA651, 'V'), - (0xA652, 'M', 'ꙓ'), - (0xA653, 'V'), - (0xA654, 'M', 'ꙕ'), - (0xA655, 'V'), - (0xA656, 'M', 'ź™—'), - (0xA657, 'V'), - (0xA658, 'M', 'ź™™'), - (0xA659, 'V'), - (0xA65A, 'M', 'ź™›'), - (0xA65B, 'V'), - (0xA65C, 'M', 'ź™'), - (0xA65D, 'V'), - (0xA65E, 'M', 'ź™Ÿ'), - (0xA65F, 'V'), - (0xA660, 'M', 'ź™”'), - (0xA661, 'V'), - (0xA662, 'M', 'ꙣ'), - (0xA663, 'V'), - (0xA664, 'M', 'Ꙅ'), - (0xA665, 'V'), - (0xA666, 'M', 'ź™§'), - (0xA667, 'V'), - (0xA668, 'M', 'ꙩ'), - (0xA669, 'V'), - (0xA66A, 'M', 'ꙫ'), - (0xA66B, 'V'), - (0xA66C, 'M', 'ź™­'), - (0xA66D, 'V'), - (0xA680, 'M', 'ꚁ'), - (0xA681, 'V'), - (0xA682, 'M', 'ꚃ'), - (0xA683, 'V'), - (0xA684, 'M', 'źš…'), - (0xA685, 'V'), - (0xA686, 'M', 'źš‡'), - (0xA687, 'V'), - (0xA688, 'M', 'źš‰'), - (0xA689, 'V'), - (0xA68A, 'M', 'źš‹'), - (0xA68B, 'V'), - (0xA68C, 'M', 'źš'), - (0xA68D, 'V'), + (0x33E2, "M", "3ę—„"), + (0x33E3, "M", "4ę—„"), + (0x33E4, "M", "5ę—„"), + (0x33E5, "M", "6ę—„"), + (0x33E6, "M", "7ę—„"), + (0x33E7, "M", "8ę—„"), + (0x33E8, "M", "9ę—„"), + (0x33E9, "M", "10ę—„"), + (0x33EA, "M", "11ę—„"), + (0x33EB, "M", "12ę—„"), + (0x33EC, "M", "13ę—„"), + (0x33ED, "M", "14ę—„"), + (0x33EE, "M", "15ę—„"), + (0x33EF, "M", "16ę—„"), + (0x33F0, "M", "17ę—„"), + (0x33F1, "M", "18ę—„"), + (0x33F2, "M", "19ę—„"), + (0x33F3, "M", "20ę—„"), + (0x33F4, "M", "21ę—„"), + (0x33F5, "M", "22ę—„"), + (0x33F6, "M", "23ę—„"), + (0x33F7, "M", "24ę—„"), + (0x33F8, "M", "25ę—„"), + (0x33F9, "M", "26ę—„"), + (0x33FA, "M", "27ę—„"), + (0x33FB, "M", "28ę—„"), + (0x33FC, "M", "29ę—„"), + (0x33FD, "M", "30ę—„"), + (0x33FE, "M", "31ę—„"), + (0x33FF, "M", "gal"), + (0x3400, "V"), + (0xA48D, "X"), + (0xA490, "V"), + (0xA4C7, "X"), + (0xA4D0, "V"), + (0xA62C, "X"), + (0xA640, "M", "ꙁ"), + (0xA641, "V"), + (0xA642, "M", "ź™ƒ"), + (0xA643, "V"), + (0xA644, "M", "ź™…"), + (0xA645, "V"), + (0xA646, "M", "ꙇ"), + (0xA647, "V"), + (0xA648, "M", "ꙉ"), + (0xA649, "V"), + (0xA64A, "M", "ꙋ"), + (0xA64B, "V"), + (0xA64C, "M", "ź™"), + (0xA64D, "V"), + (0xA64E, "M", "ź™"), + (0xA64F, "V"), + (0xA650, "M", "ꙑ"), + (0xA651, "V"), + (0xA652, "M", "ꙓ"), + (0xA653, "V"), + (0xA654, "M", "ꙕ"), + (0xA655, "V"), + (0xA656, "M", "ź™—"), + (0xA657, "V"), + (0xA658, "M", "ź™™"), + (0xA659, "V"), + (0xA65A, "M", "ź™›"), + (0xA65B, "V"), + (0xA65C, "M", "ź™"), + (0xA65D, "V"), + (0xA65E, "M", "ź™Ÿ"), + (0xA65F, "V"), + (0xA660, "M", "ź™”"), + (0xA661, "V"), + (0xA662, "M", "ꙣ"), + (0xA663, "V"), + (0xA664, "M", "Ꙅ"), + (0xA665, "V"), + (0xA666, "M", "ź™§"), + (0xA667, "V"), + (0xA668, "M", "ꙩ"), + (0xA669, "V"), + (0xA66A, "M", "ꙫ"), + (0xA66B, "V"), + (0xA66C, "M", "ź™­"), + (0xA66D, "V"), + (0xA680, "M", "ꚁ"), + (0xA681, "V"), + (0xA682, "M", "ꚃ"), + (0xA683, "V"), + (0xA684, "M", "źš…"), + (0xA685, "V"), + (0xA686, "M", "źš‡"), + (0xA687, "V"), + (0xA688, "M", "źš‰"), + (0xA689, "V"), + (0xA68A, "M", "źš‹"), + (0xA68B, "V"), + (0xA68C, "M", "źš"), + (0xA68D, "V"), + (0xA68E, "M", "źš"), + (0xA68F, "V"), + (0xA690, "M", "źš‘"), + (0xA691, "V"), ] + def _seg_36() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xA68E, 'M', 'źš'), - (0xA68F, 'V'), - (0xA690, 'M', 'źš‘'), - (0xA691, 'V'), - (0xA692, 'M', 'źš“'), - (0xA693, 'V'), - (0xA694, 'M', 'źš•'), - (0xA695, 'V'), - (0xA696, 'M', 'źš—'), - (0xA697, 'V'), - (0xA698, 'M', 'źš™'), - (0xA699, 'V'), - (0xA69A, 'M', 'źš›'), - (0xA69B, 'V'), - (0xA69C, 'M', 'ъ'), - (0xA69D, 'M', 'ь'), - (0xA69E, 'V'), - (0xA6F8, 'X'), - (0xA700, 'V'), - (0xA722, 'M', 'ꜣ'), - (0xA723, 'V'), - (0xA724, 'M', '꜄'), - (0xA725, 'V'), - (0xA726, 'M', 'ꜧ'), - (0xA727, 'V'), - (0xA728, 'M', 'ꜩ'), - (0xA729, 'V'), - (0xA72A, 'M', 'ꜫ'), - (0xA72B, 'V'), - (0xA72C, 'M', 'ꜭ'), - (0xA72D, 'V'), - (0xA72E, 'M', 'ꜯ'), - (0xA72F, 'V'), - (0xA732, 'M', 'ꜳ'), - (0xA733, 'V'), - (0xA734, 'M', 'ꜵ'), - (0xA735, 'V'), - (0xA736, 'M', 'ꜷ'), - (0xA737, 'V'), - (0xA738, 'M', 'ꜹ'), - (0xA739, 'V'), - (0xA73A, 'M', 'ꜻ'), - (0xA73B, 'V'), - (0xA73C, 'M', 'ꜽ'), - (0xA73D, 'V'), - (0xA73E, 'M', 'ꜿ'), - (0xA73F, 'V'), - (0xA740, 'M', 'ź'), - (0xA741, 'V'), - (0xA742, 'M', 'źƒ'), - (0xA743, 'V'), - (0xA744, 'M', 'ź…'), - (0xA745, 'V'), - (0xA746, 'M', 'ź‡'), - (0xA747, 'V'), - (0xA748, 'M', 'ź‰'), - (0xA749, 'V'), - (0xA74A, 'M', 'ź‹'), - (0xA74B, 'V'), - (0xA74C, 'M', 'ź'), - (0xA74D, 'V'), - (0xA74E, 'M', 'ź'), - (0xA74F, 'V'), - (0xA750, 'M', 'ź‘'), - (0xA751, 'V'), - (0xA752, 'M', 'ź“'), - (0xA753, 'V'), - (0xA754, 'M', 'ź•'), - (0xA755, 'V'), - (0xA756, 'M', 'ź—'), - (0xA757, 'V'), - (0xA758, 'M', 'ź™'), - (0xA759, 'V'), - (0xA75A, 'M', 'ź›'), - (0xA75B, 'V'), - (0xA75C, 'M', 'ź'), - (0xA75D, 'V'), - (0xA75E, 'M', 'źŸ'), - (0xA75F, 'V'), - (0xA760, 'M', 'ź”'), - (0xA761, 'V'), - (0xA762, 'M', 'ź£'), - (0xA763, 'V'), - (0xA764, 'M', 'ź„'), - (0xA765, 'V'), - (0xA766, 'M', 'ź§'), - (0xA767, 'V'), - (0xA768, 'M', 'ź©'), - (0xA769, 'V'), - (0xA76A, 'M', 'ź«'), - (0xA76B, 'V'), - (0xA76C, 'M', 'ź­'), - (0xA76D, 'V'), - (0xA76E, 'M', 'źÆ'), - (0xA76F, 'V'), - (0xA770, 'M', 'źÆ'), - (0xA771, 'V'), - (0xA779, 'M', 'źŗ'), - (0xA77A, 'V'), - (0xA77B, 'M', 'ź¼'), + (0xA692, "M", "źš“"), + (0xA693, "V"), + (0xA694, "M", "źš•"), + (0xA695, "V"), + (0xA696, "M", "źš—"), + (0xA697, "V"), + (0xA698, "M", "źš™"), + (0xA699, "V"), + (0xA69A, "M", "źš›"), + (0xA69B, "V"), + (0xA69C, "M", "ъ"), + (0xA69D, "M", "ь"), + (0xA69E, "V"), + (0xA6F8, "X"), + (0xA700, "V"), + (0xA722, "M", "ꜣ"), + (0xA723, "V"), + (0xA724, "M", "꜄"), + (0xA725, "V"), + (0xA726, "M", "ꜧ"), + (0xA727, "V"), + (0xA728, "M", "ꜩ"), + (0xA729, "V"), + (0xA72A, "M", "ꜫ"), + (0xA72B, "V"), + (0xA72C, "M", "ꜭ"), + (0xA72D, "V"), + (0xA72E, "M", "ꜯ"), + (0xA72F, "V"), + (0xA732, "M", "ꜳ"), + (0xA733, "V"), + (0xA734, "M", "ꜵ"), + (0xA735, "V"), + (0xA736, "M", "ꜷ"), + (0xA737, "V"), + (0xA738, "M", "ꜹ"), + (0xA739, "V"), + (0xA73A, "M", "ꜻ"), + (0xA73B, "V"), + (0xA73C, "M", "ꜽ"), + (0xA73D, "V"), + (0xA73E, "M", "ꜿ"), + (0xA73F, "V"), + (0xA740, "M", "ź"), + (0xA741, "V"), + (0xA742, "M", "źƒ"), + (0xA743, "V"), + (0xA744, "M", "ź…"), + (0xA745, "V"), + (0xA746, "M", "ź‡"), + (0xA747, "V"), + (0xA748, "M", "ź‰"), + (0xA749, "V"), + (0xA74A, "M", "ź‹"), + (0xA74B, "V"), + (0xA74C, "M", "ź"), + (0xA74D, "V"), + (0xA74E, "M", "ź"), + (0xA74F, "V"), + (0xA750, "M", "ź‘"), + (0xA751, "V"), + (0xA752, "M", "ź“"), + (0xA753, "V"), + (0xA754, "M", "ź•"), + (0xA755, "V"), + (0xA756, "M", "ź—"), + (0xA757, "V"), + (0xA758, "M", "ź™"), + (0xA759, "V"), + (0xA75A, "M", "ź›"), + (0xA75B, "V"), + (0xA75C, "M", "ź"), + (0xA75D, "V"), + (0xA75E, "M", "źŸ"), + (0xA75F, "V"), + (0xA760, "M", "ź”"), + (0xA761, "V"), + (0xA762, "M", "ź£"), + (0xA763, "V"), + (0xA764, "M", "ź„"), + (0xA765, "V"), + (0xA766, "M", "ź§"), + (0xA767, "V"), + (0xA768, "M", "ź©"), + (0xA769, "V"), + (0xA76A, "M", "ź«"), + (0xA76B, "V"), + (0xA76C, "M", "ź­"), + (0xA76D, "V"), + (0xA76E, "M", "źÆ"), + (0xA76F, "V"), + (0xA770, "M", "źÆ"), + (0xA771, "V"), + (0xA779, "M", "źŗ"), + (0xA77A, "V"), + (0xA77B, "M", "ź¼"), + (0xA77C, "V"), + (0xA77D, "M", "įµ¹"), + (0xA77E, "M", "źæ"), + (0xA77F, "V"), ] + def _seg_37() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xA77C, 'V'), - (0xA77D, 'M', 'įµ¹'), - (0xA77E, 'M', 'źæ'), - (0xA77F, 'V'), - (0xA780, 'M', 'źž'), - (0xA781, 'V'), - (0xA782, 'M', 'źžƒ'), - (0xA783, 'V'), - (0xA784, 'M', 'źž…'), - (0xA785, 'V'), - (0xA786, 'M', 'źž‡'), - (0xA787, 'V'), - (0xA78B, 'M', 'źžŒ'), - (0xA78C, 'V'), - (0xA78D, 'M', 'É„'), - (0xA78E, 'V'), - (0xA790, 'M', 'źž‘'), - (0xA791, 'V'), - (0xA792, 'M', 'źž“'), - (0xA793, 'V'), - (0xA796, 'M', 'źž—'), - (0xA797, 'V'), - (0xA798, 'M', 'źž™'), - (0xA799, 'V'), - (0xA79A, 'M', 'źž›'), - (0xA79B, 'V'), - (0xA79C, 'M', 'źž'), - (0xA79D, 'V'), - (0xA79E, 'M', 'źžŸ'), - (0xA79F, 'V'), - (0xA7A0, 'M', 'źž”'), - (0xA7A1, 'V'), - (0xA7A2, 'M', 'źž£'), - (0xA7A3, 'V'), - (0xA7A4, 'M', 'źž„'), - (0xA7A5, 'V'), - (0xA7A6, 'M', 'źž§'), - (0xA7A7, 'V'), - (0xA7A8, 'M', 'źž©'), - (0xA7A9, 'V'), - (0xA7AA, 'M', 'ɦ'), - (0xA7AB, 'M', 'ɜ'), - (0xA7AC, 'M', 'É”'), - (0xA7AD, 'M', 'ɬ'), - (0xA7AE, 'M', 'ÉŖ'), - (0xA7AF, 'V'), - (0xA7B0, 'M', 'Źž'), - (0xA7B1, 'M', 'ʇ'), - (0xA7B2, 'M', 'Ź'), - (0xA7B3, 'M', 'ź­“'), - (0xA7B4, 'M', 'źžµ'), - (0xA7B5, 'V'), - (0xA7B6, 'M', 'źž·'), - (0xA7B7, 'V'), - (0xA7B8, 'M', 'źž¹'), - (0xA7B9, 'V'), - (0xA7BA, 'M', 'źž»'), - (0xA7BB, 'V'), - (0xA7BC, 'M', 'źž½'), - (0xA7BD, 'V'), - (0xA7BE, 'M', 'źžæ'), - (0xA7BF, 'V'), - (0xA7C0, 'M', 'ꟁ'), - (0xA7C1, 'V'), - (0xA7C2, 'M', 'ꟃ'), - (0xA7C3, 'V'), - (0xA7C4, 'M', 'źž”'), - (0xA7C5, 'M', 'Ź‚'), - (0xA7C6, 'M', 'į¶Ž'), - (0xA7C7, 'M', 'ꟈ'), - (0xA7C8, 'V'), - (0xA7C9, 'M', 'ꟊ'), - (0xA7CA, 'V'), - (0xA7CB, 'X'), - (0xA7D0, 'M', 'źŸ‘'), - (0xA7D1, 'V'), - (0xA7D2, 'X'), - (0xA7D3, 'V'), - (0xA7D4, 'X'), - (0xA7D5, 'V'), - (0xA7D6, 'M', 'źŸ—'), - (0xA7D7, 'V'), - (0xA7D8, 'M', 'źŸ™'), - (0xA7D9, 'V'), - (0xA7DA, 'X'), - (0xA7F2, 'M', 'c'), - (0xA7F3, 'M', 'f'), - (0xA7F4, 'M', 'q'), - (0xA7F5, 'M', 'ꟶ'), - (0xA7F6, 'V'), - (0xA7F8, 'M', 'ħ'), - (0xA7F9, 'M', 'œ'), - (0xA7FA, 'V'), - (0xA82D, 'X'), - (0xA830, 'V'), - (0xA83A, 'X'), - (0xA840, 'V'), - (0xA878, 'X'), - (0xA880, 'V'), - (0xA8C6, 'X'), + (0xA780, "M", "źž"), + (0xA781, "V"), + (0xA782, "M", "źžƒ"), + (0xA783, "V"), + (0xA784, "M", "źž…"), + (0xA785, "V"), + (0xA786, "M", "źž‡"), + (0xA787, "V"), + (0xA78B, "M", "źžŒ"), + (0xA78C, "V"), + (0xA78D, "M", "É„"), + (0xA78E, "V"), + (0xA790, "M", "źž‘"), + (0xA791, "V"), + (0xA792, "M", "źž“"), + (0xA793, "V"), + (0xA796, "M", "źž—"), + (0xA797, "V"), + (0xA798, "M", "źž™"), + (0xA799, "V"), + (0xA79A, "M", "źž›"), + (0xA79B, "V"), + (0xA79C, "M", "źž"), + (0xA79D, "V"), + (0xA79E, "M", "źžŸ"), + (0xA79F, "V"), + (0xA7A0, "M", "źž”"), + (0xA7A1, "V"), + (0xA7A2, "M", "źž£"), + (0xA7A3, "V"), + (0xA7A4, "M", "źž„"), + (0xA7A5, "V"), + (0xA7A6, "M", "źž§"), + (0xA7A7, "V"), + (0xA7A8, "M", "źž©"), + (0xA7A9, "V"), + (0xA7AA, "M", "ɦ"), + (0xA7AB, "M", "ɜ"), + (0xA7AC, "M", "É”"), + (0xA7AD, "M", "ɬ"), + (0xA7AE, "M", "ÉŖ"), + (0xA7AF, "V"), + (0xA7B0, "M", "Źž"), + (0xA7B1, "M", "ʇ"), + (0xA7B2, "M", "Ź"), + (0xA7B3, "M", "ź­“"), + (0xA7B4, "M", "źžµ"), + (0xA7B5, "V"), + (0xA7B6, "M", "źž·"), + (0xA7B7, "V"), + (0xA7B8, "M", "źž¹"), + (0xA7B9, "V"), + (0xA7BA, "M", "źž»"), + (0xA7BB, "V"), + (0xA7BC, "M", "źž½"), + (0xA7BD, "V"), + (0xA7BE, "M", "źžæ"), + (0xA7BF, "V"), + (0xA7C0, "M", "ꟁ"), + (0xA7C1, "V"), + (0xA7C2, "M", "ꟃ"), + (0xA7C3, "V"), + (0xA7C4, "M", "źž”"), + (0xA7C5, "M", "Ź‚"), + (0xA7C6, "M", "į¶Ž"), + (0xA7C7, "M", "ꟈ"), + (0xA7C8, "V"), + (0xA7C9, "M", "ꟊ"), + (0xA7CA, "V"), + (0xA7CB, "X"), + (0xA7D0, "M", "źŸ‘"), + (0xA7D1, "V"), + (0xA7D2, "X"), + (0xA7D3, "V"), + (0xA7D4, "X"), + (0xA7D5, "V"), + (0xA7D6, "M", "źŸ—"), + (0xA7D7, "V"), + (0xA7D8, "M", "źŸ™"), + (0xA7D9, "V"), + (0xA7DA, "X"), + (0xA7F2, "M", "c"), + (0xA7F3, "M", "f"), + (0xA7F4, "M", "q"), + (0xA7F5, "M", "ꟶ"), + (0xA7F6, "V"), + (0xA7F8, "M", "ħ"), + (0xA7F9, "M", "œ"), + (0xA7FA, "V"), + (0xA82D, "X"), + (0xA830, "V"), + (0xA83A, "X"), + (0xA840, "V"), + (0xA878, "X"), + (0xA880, "V"), + (0xA8C6, "X"), + (0xA8CE, "V"), + (0xA8DA, "X"), + (0xA8E0, "V"), + (0xA954, "X"), ] + def _seg_38() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xA8CE, 'V'), - (0xA8DA, 'X'), - (0xA8E0, 'V'), - (0xA954, 'X'), - (0xA95F, 'V'), - (0xA97D, 'X'), - (0xA980, 'V'), - (0xA9CE, 'X'), - (0xA9CF, 'V'), - (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', 'ꜧ'), - (0xAB5D, 'M', 'ꬷ'), - (0xAB5E, 'M', 'É«'), - (0xAB5F, 'M', 'ź­’'), - (0xAB60, 'V'), - (0xAB69, 'M', 'Ź'), - (0xAB6A, 'V'), - (0xAB6C, 'X'), - (0xAB70, 'M', 'įŽ '), - (0xAB71, 'M', 'įŽ”'), - (0xAB72, 'M', 'įŽ¢'), - (0xAB73, 'M', 'įŽ£'), - (0xAB74, 'M', 'įŽ¤'), - (0xAB75, 'M', 'įŽ„'), - (0xAB76, 'M', 'įŽ¦'), - (0xAB77, 'M', 'įŽ§'), - (0xAB78, 'M', 'įŽØ'), - (0xAB79, 'M', 'įŽ©'), - (0xAB7A, 'M', 'įŽŖ'), - (0xAB7B, 'M', 'įŽ«'), - (0xAB7C, 'M', 'įŽ¬'), - (0xAB7D, 'M', 'įŽ­'), - (0xAB7E, 'M', 'įŽ®'), - (0xAB7F, 'M', 'įŽÆ'), - (0xAB80, 'M', 'įŽ°'), - (0xAB81, 'M', 'įŽ±'), - (0xAB82, 'M', 'įŽ²'), - (0xAB83, 'M', 'įŽ³'), - (0xAB84, 'M', 'įŽ“'), - (0xAB85, 'M', 'įŽµ'), - (0xAB86, 'M', 'įŽ¶'), - (0xAB87, 'M', 'įŽ·'), - (0xAB88, 'M', 'įŽø'), - (0xAB89, 'M', 'įŽ¹'), - (0xAB8A, 'M', 'įŽŗ'), - (0xAB8B, 'M', 'įŽ»'), - (0xAB8C, 'M', 'įŽ¼'), - (0xAB8D, 'M', 'įŽ½'), - (0xAB8E, 'M', 'įŽ¾'), - (0xAB8F, 'M', 'įŽæ'), - (0xAB90, 'M', 'į€'), - (0xAB91, 'M', 'į'), - (0xAB92, 'M', 'į‚'), - (0xAB93, 'M', 'įƒ'), - (0xAB94, 'M', 'į„'), - (0xAB95, 'M', 'į…'), - (0xAB96, 'M', 'į†'), - (0xAB97, 'M', 'į‡'), - (0xAB98, 'M', 'įˆ'), - (0xAB99, 'M', 'į‰'), - (0xAB9A, 'M', 'įŠ'), - (0xAB9B, 'M', 'į‹'), - (0xAB9C, 'M', 'įŒ'), - (0xAB9D, 'M', 'į'), - (0xAB9E, 'M', 'įŽ'), - (0xAB9F, 'M', 'į'), - (0xABA0, 'M', 'į'), - (0xABA1, 'M', 'į‘'), - (0xABA2, 'M', 'į’'), - (0xABA3, 'M', 'į“'), - (0xABA4, 'M', 'į”'), - (0xABA5, 'M', 'į•'), - (0xABA6, 'M', 'į–'), - (0xABA7, 'M', 'į—'), - (0xABA8, 'M', 'į˜'), - (0xABA9, 'M', 'į™'), - (0xABAA, 'M', 'įš'), + (0xA95F, "V"), + (0xA97D, "X"), + (0xA980, "V"), + (0xA9CE, "X"), + (0xA9CF, "V"), + (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", "ꜧ"), + (0xAB5D, "M", "ꬷ"), + (0xAB5E, "M", "É«"), + (0xAB5F, "M", "ź­’"), + (0xAB60, "V"), + (0xAB69, "M", "Ź"), + (0xAB6A, "V"), + (0xAB6C, "X"), + (0xAB70, "M", "įŽ "), + (0xAB71, "M", "įŽ”"), + (0xAB72, "M", "įŽ¢"), + (0xAB73, "M", "įŽ£"), + (0xAB74, "M", "įŽ¤"), + (0xAB75, "M", "įŽ„"), + (0xAB76, "M", "įŽ¦"), + (0xAB77, "M", "įŽ§"), + (0xAB78, "M", "įŽØ"), + (0xAB79, "M", "įŽ©"), + (0xAB7A, "M", "įŽŖ"), + (0xAB7B, "M", "įŽ«"), + (0xAB7C, "M", "įŽ¬"), + (0xAB7D, "M", "įŽ­"), + (0xAB7E, "M", "įŽ®"), + (0xAB7F, "M", "įŽÆ"), + (0xAB80, "M", "įŽ°"), + (0xAB81, "M", "įŽ±"), + (0xAB82, "M", "įŽ²"), + (0xAB83, "M", "įŽ³"), + (0xAB84, "M", "įŽ“"), + (0xAB85, "M", "įŽµ"), + (0xAB86, "M", "įŽ¶"), + (0xAB87, "M", "įŽ·"), + (0xAB88, "M", "įŽø"), + (0xAB89, "M", "įŽ¹"), + (0xAB8A, "M", "įŽŗ"), + (0xAB8B, "M", "įŽ»"), + (0xAB8C, "M", "įŽ¼"), + (0xAB8D, "M", "įŽ½"), + (0xAB8E, "M", "įŽ¾"), + (0xAB8F, "M", "įŽæ"), + (0xAB90, "M", "į€"), + (0xAB91, "M", "į"), + (0xAB92, "M", "į‚"), + (0xAB93, "M", "įƒ"), + (0xAB94, "M", "į„"), + (0xAB95, "M", "į…"), + (0xAB96, "M", "į†"), + (0xAB97, "M", "į‡"), + (0xAB98, "M", "įˆ"), + (0xAB99, "M", "į‰"), + (0xAB9A, "M", "įŠ"), + (0xAB9B, "M", "į‹"), + (0xAB9C, "M", "įŒ"), + (0xAB9D, "M", "į"), + (0xAB9E, "M", "įŽ"), + (0xAB9F, "M", "į"), + (0xABA0, "M", "į"), + (0xABA1, "M", "į‘"), + (0xABA2, "M", "į’"), + (0xABA3, "M", "į“"), + (0xABA4, "M", "į”"), + (0xABA5, "M", "į•"), + (0xABA6, "M", "į–"), + (0xABA7, "M", "į—"), + (0xABA8, "M", "į˜"), + (0xABA9, "M", "į™"), + (0xABAA, "M", "įš"), + (0xABAB, "M", "į›"), + (0xABAC, "M", "įœ"), + (0xABAD, "M", "į"), + (0xABAE, "M", "įž"), ] + def _seg_39() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xABAB, 'M', 'į›'), - (0xABAC, 'M', 'įœ'), - (0xABAD, 'M', 'į'), - (0xABAE, 'M', 'įž'), - (0xABAF, 'M', 'įŸ'), - (0xABB0, 'M', 'į '), - (0xABB1, 'M', 'į”'), - (0xABB2, 'M', 'į¢'), - (0xABB3, 'M', 'į£'), - (0xABB4, 'M', 'į¤'), - (0xABB5, 'M', 'į„'), - (0xABB6, 'M', 'į¦'), - (0xABB7, 'M', 'į§'), - (0xABB8, 'M', 'įØ'), - (0xABB9, 'M', 'į©'), - (0xABBA, 'M', 'įŖ'), - (0xABBB, 'M', 'į«'), - (0xABBC, 'M', 'į¬'), - (0xABBD, 'M', 'į­'), - (0xABBE, 'M', 'į®'), - (0xABBF, 'M', 'įÆ'), - (0xABC0, 'V'), - (0xABEE, 'X'), - (0xABF0, 'V'), - (0xABFA, 'X'), - (0xAC00, 'V'), - (0xD7A4, 'X'), - (0xD7B0, 'V'), - (0xD7C7, 'X'), - (0xD7CB, 'V'), - (0xD7FC, 'X'), - (0xF900, 'M', '豈'), - (0xF901, 'M', 'ꛓ'), - (0xF902, 'M', '車'), - (0xF903, 'M', '賈'), - (0xF904, 'M', '껑'), - (0xF905, 'M', 'äø²'), - (0xF906, 'M', '叄'), - (0xF907, 'M', '龜'), - (0xF909, 'M', 'å„‘'), - (0xF90A, 'M', '金'), - (0xF90B, 'M', '喇'), - (0xF90C, 'M', '儈'), - (0xF90D, 'M', 'ꇶ'), - (0xF90E, 'M', '癩'), - (0xF90F, 'M', 'ē¾…'), - (0xF910, 'M', '蘿'), - (0xF911, 'M', 'čžŗ'), - (0xF912, 'M', '裸'), - (0xF913, 'M', '邏'), - (0xF914, 'M', '樂'), - (0xF915, 'M', 'ę“›'), - (0xF916, 'M', 'ēƒ™'), - (0xF917, 'M', 'ēž'), - (0xF918, 'M', '落'), - (0xF919, 'M', 'é…Ŗ'), - (0xF91A, 'M', 'é§±'), - (0xF91B, 'M', 'äŗ‚'), - (0xF91C, 'M', '卵'), - (0xF91D, 'M', 'ꬄ'), - (0xF91E, 'M', 'ēˆ›'), - (0xF91F, 'M', '蘭'), - (0xF920, 'M', 'éøž'), - (0xF921, 'M', '嵐'), - (0xF922, 'M', 'ęæ«'), - (0xF923, 'M', '藍'), - (0xF924, 'M', '脤'), - (0xF925, 'M', 'ꋉ'), - (0xF926, 'M', '臘'), - (0xF927, 'M', '蠟'), - (0xF928, 'M', '廊'), - (0xF929, 'M', 'ꜗ'), - (0xF92A, 'M', 'ęµŖ'), - (0xF92B, 'M', '狼'), - (0xF92C, 'M', '郎'), - (0xF92D, 'M', '來'), - (0xF92E, 'M', '冷'), - (0xF92F, 'M', '勞'), - (0xF930, 'M', '꓄'), - (0xF931, 'M', 'ę«“'), - (0xF932, 'M', '爐'), - (0xF933, 'M', 'ē›§'), - (0xF934, 'M', '老'), - (0xF935, 'M', '蘆'), - (0xF936, 'M', '虜'), - (0xF937, 'M', 'č·Æ'), - (0xF938, 'M', '露'), - (0xF939, 'M', 'é­Æ'), - (0xF93A, 'M', 'é·ŗ'), - (0xF93B, 'M', '碌'), - (0xF93C, 'M', '焿'), - (0xF93D, 'M', 'ē¶ '), - (0xF93E, 'M', '菉'), - (0xF93F, 'M', '錄'), - (0xF940, 'M', '鹿'), - (0xF941, 'M', 'č«–'), - (0xF942, 'M', '壟'), - (0xF943, 'M', '弄'), - (0xF944, 'M', 'ē± '), - (0xF945, 'M', '聾'), + (0xABAF, "M", "įŸ"), + (0xABB0, "M", "į "), + (0xABB1, "M", "į”"), + (0xABB2, "M", "į¢"), + (0xABB3, "M", "į£"), + (0xABB4, "M", "į¤"), + (0xABB5, "M", "į„"), + (0xABB6, "M", "į¦"), + (0xABB7, "M", "į§"), + (0xABB8, "M", "įØ"), + (0xABB9, "M", "į©"), + (0xABBA, "M", "įŖ"), + (0xABBB, "M", "į«"), + (0xABBC, "M", "į¬"), + (0xABBD, "M", "į­"), + (0xABBE, "M", "į®"), + (0xABBF, "M", "įÆ"), + (0xABC0, "V"), + (0xABEE, "X"), + (0xABF0, "V"), + (0xABFA, "X"), + (0xAC00, "V"), + (0xD7A4, "X"), + (0xD7B0, "V"), + (0xD7C7, "X"), + (0xD7CB, "V"), + (0xD7FC, "X"), + (0xF900, "M", "豈"), + (0xF901, "M", "ꛓ"), + (0xF902, "M", "車"), + (0xF903, "M", "賈"), + (0xF904, "M", "껑"), + (0xF905, "M", "äø²"), + (0xF906, "M", "叄"), + (0xF907, "M", "龜"), + (0xF909, "M", "å„‘"), + (0xF90A, "M", "金"), + (0xF90B, "M", "喇"), + (0xF90C, "M", "儈"), + (0xF90D, "M", "ꇶ"), + (0xF90E, "M", "癩"), + (0xF90F, "M", "ē¾…"), + (0xF910, "M", "蘿"), + (0xF911, "M", "čžŗ"), + (0xF912, "M", "裸"), + (0xF913, "M", "邏"), + (0xF914, "M", "樂"), + (0xF915, "M", "ę“›"), + (0xF916, "M", "ēƒ™"), + (0xF917, "M", "ēž"), + (0xF918, "M", "落"), + (0xF919, "M", "é…Ŗ"), + (0xF91A, "M", "é§±"), + (0xF91B, "M", "äŗ‚"), + (0xF91C, "M", "卵"), + (0xF91D, "M", "ꬄ"), + (0xF91E, "M", "ēˆ›"), + (0xF91F, "M", "蘭"), + (0xF920, "M", "éøž"), + (0xF921, "M", "嵐"), + (0xF922, "M", "ęæ«"), + (0xF923, "M", "藍"), + (0xF924, "M", "脤"), + (0xF925, "M", "ꋉ"), + (0xF926, "M", "臘"), + (0xF927, "M", "蠟"), + (0xF928, "M", "廊"), + (0xF929, "M", "ꜗ"), + (0xF92A, "M", "ęµŖ"), + (0xF92B, "M", "狼"), + (0xF92C, "M", "郎"), + (0xF92D, "M", "來"), + (0xF92E, "M", "冷"), + (0xF92F, "M", "勞"), + (0xF930, "M", "꓄"), + (0xF931, "M", "ę«“"), + (0xF932, "M", "爐"), + (0xF933, "M", "ē›§"), + (0xF934, "M", "老"), + (0xF935, "M", "蘆"), + (0xF936, "M", "虜"), + (0xF937, "M", "č·Æ"), + (0xF938, "M", "露"), + (0xF939, "M", "é­Æ"), + (0xF93A, "M", "é·ŗ"), + (0xF93B, "M", "碌"), + (0xF93C, "M", "焿"), + (0xF93D, "M", "ē¶ "), + (0xF93E, "M", "菉"), + (0xF93F, "M", "錄"), + (0xF940, "M", "鹿"), + (0xF941, "M", "č«–"), + (0xF942, "M", "壟"), + (0xF943, "M", "弄"), + (0xF944, "M", "ē± "), + (0xF945, "M", "聾"), + (0xF946, "M", "牢"), + (0xF947, "M", "磊"), + (0xF948, "M", "賂"), + (0xF949, "M", "雷"), ] + def _seg_40() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xF946, 'M', '牢'), - (0xF947, 'M', '磊'), - (0xF948, 'M', '賂'), - (0xF949, 'M', '雷'), - (0xF94A, 'M', '壘'), - (0xF94B, 'M', 'å±¢'), - (0xF94C, 'M', '樓'), - (0xF94D, 'M', '淚'), - (0xF94E, 'M', 'ę¼'), - (0xF94F, 'M', '瓯'), - (0xF950, 'M', 'ēø·'), - (0xF951, 'M', '陋'), - (0xF952, 'M', '勒'), - (0xF953, 'M', '肋'), - (0xF954, 'M', '凜'), - (0xF955, 'M', '凌'), - (0xF956, 'M', '稜'), - (0xF957, 'M', 'ē¶¾'), - (0xF958, 'M', 'č±'), - (0xF959, 'M', '陵'), - (0xF95A, 'M', '讀'), - (0xF95B, 'M', 'ꋏ'), - (0xF95C, 'M', '樂'), - (0xF95D, 'M', '諾'), - (0xF95E, 'M', 'äø¹'), - (0xF95F, 'M', '寧'), - (0xF960, 'M', 'ꀒ'), - (0xF961, 'M', 'ēŽ‡'), - (0xF962, 'M', 'ē•°'), - (0xF963, 'M', '北'), - (0xF964, 'M', '磻'), - (0xF965, 'M', '便'), - (0xF966, 'M', '復'), - (0xF967, 'M', 'äø'), - (0xF968, 'M', '泌'), - (0xF969, 'M', '數'), - (0xF96A, 'M', 'ē“¢'), - (0xF96B, 'M', '參'), - (0xF96C, 'M', '唞'), - (0xF96D, 'M', '省'), - (0xF96E, 'M', '葉'), - (0xF96F, 'M', 'čŖŖ'), - (0xF970, 'M', '殺'), - (0xF971, 'M', 'č¾°'), - (0xF972, 'M', '沈'), - (0xF973, 'M', '拾'), - (0xF974, 'M', 'č‹„'), - (0xF975, 'M', 'ꎠ'), - (0xF976, 'M', 'ē•„'), - (0xF977, 'M', 'äŗ®'), - (0xF978, 'M', '兩'), - (0xF979, 'M', '凉'), - (0xF97A, 'M', '梁'), - (0xF97B, 'M', 'ē³§'), - (0xF97C, 'M', '良'), - (0xF97D, 'M', 'č«’'), - (0xF97E, 'M', '量'), - (0xF97F, 'M', '勵'), - (0xF980, 'M', '呂'), - (0xF981, 'M', '儳'), - (0xF982, 'M', '廬'), - (0xF983, 'M', 'ꗅ'), - (0xF984, 'M', 'ęæ¾'), - (0xF985, 'M', '礪'), - (0xF986, 'M', '閭'), - (0xF987, 'M', '驪'), - (0xF988, 'M', 'éŗ—'), - (0xF989, 'M', '黎'), - (0xF98A, 'M', '力'), - (0xF98B, 'M', 'ꛆ'), - (0xF98C, 'M', 'ę­·'), - (0xF98D, 'M', 'č½¢'), - (0xF98E, 'M', '幓'), - (0xF98F, 'M', 'ꆐ'), - (0xF990, 'M', 'ꈀ'), - (0xF991, 'M', '꒚'), - (0xF992, 'M', 'ę¼£'), - (0xF993, 'M', 'ē…‰'), - (0xF994, 'M', 'ē’‰'), - (0xF995, 'M', '秊'), - (0xF996, 'M', 'ē·“'), - (0xF997, 'M', '聯'), - (0xF998, 'M', '輦'), - (0xF999, 'M', 'č“®'), - (0xF99A, 'M', '連'), - (0xF99B, 'M', '鍊'), - (0xF99C, 'M', '列'), - (0xF99D, 'M', '劣'), - (0xF99E, 'M', '咽'), - (0xF99F, 'M', '烈'), - (0xF9A0, 'M', '裂'), - (0xF9A1, 'M', 'čŖŖ'), - (0xF9A2, 'M', '廉'), - (0xF9A3, 'M', 'åæµ'), - (0xF9A4, 'M', 'ę»'), - (0xF9A5, 'M', 'ę®®'), - (0xF9A6, 'M', 'ē°¾'), - (0xF9A7, 'M', 'ēµ'), - (0xF9A8, 'M', '令'), - (0xF9A9, 'M', '囹'), + (0xF94A, "M", "壘"), + (0xF94B, "M", "å±¢"), + (0xF94C, "M", "樓"), + (0xF94D, "M", "淚"), + (0xF94E, "M", "ę¼"), + (0xF94F, "M", "瓯"), + (0xF950, "M", "ēø·"), + (0xF951, "M", "陋"), + (0xF952, "M", "勒"), + (0xF953, "M", "肋"), + (0xF954, "M", "凜"), + (0xF955, "M", "凌"), + (0xF956, "M", "稜"), + (0xF957, "M", "ē¶¾"), + (0xF958, "M", "č±"), + (0xF959, "M", "陵"), + (0xF95A, "M", "讀"), + (0xF95B, "M", "ꋏ"), + (0xF95C, "M", "樂"), + (0xF95D, "M", "諾"), + (0xF95E, "M", "äø¹"), + (0xF95F, "M", "寧"), + (0xF960, "M", "ꀒ"), + (0xF961, "M", "ēŽ‡"), + (0xF962, "M", "ē•°"), + (0xF963, "M", "北"), + (0xF964, "M", "磻"), + (0xF965, "M", "便"), + (0xF966, "M", "復"), + (0xF967, "M", "äø"), + (0xF968, "M", "泌"), + (0xF969, "M", "數"), + (0xF96A, "M", "ē“¢"), + (0xF96B, "M", "參"), + (0xF96C, "M", "唞"), + (0xF96D, "M", "省"), + (0xF96E, "M", "葉"), + (0xF96F, "M", "čŖŖ"), + (0xF970, "M", "殺"), + (0xF971, "M", "č¾°"), + (0xF972, "M", "沈"), + (0xF973, "M", "拾"), + (0xF974, "M", "č‹„"), + (0xF975, "M", "ꎠ"), + (0xF976, "M", "ē•„"), + (0xF977, "M", "äŗ®"), + (0xF978, "M", "兩"), + (0xF979, "M", "凉"), + (0xF97A, "M", "梁"), + (0xF97B, "M", "ē³§"), + (0xF97C, "M", "良"), + (0xF97D, "M", "č«’"), + (0xF97E, "M", "量"), + (0xF97F, "M", "勵"), + (0xF980, "M", "呂"), + (0xF981, "M", "儳"), + (0xF982, "M", "廬"), + (0xF983, "M", "ꗅ"), + (0xF984, "M", "ęæ¾"), + (0xF985, "M", "礪"), + (0xF986, "M", "閭"), + (0xF987, "M", "驪"), + (0xF988, "M", "éŗ—"), + (0xF989, "M", "黎"), + (0xF98A, "M", "力"), + (0xF98B, "M", "ꛆ"), + (0xF98C, "M", "ę­·"), + (0xF98D, "M", "č½¢"), + (0xF98E, "M", "幓"), + (0xF98F, "M", "ꆐ"), + (0xF990, "M", "ꈀ"), + (0xF991, "M", "꒚"), + (0xF992, "M", "ę¼£"), + (0xF993, "M", "ē…‰"), + (0xF994, "M", "ē’‰"), + (0xF995, "M", "秊"), + (0xF996, "M", "ē·“"), + (0xF997, "M", "聯"), + (0xF998, "M", "輦"), + (0xF999, "M", "č“®"), + (0xF99A, "M", "連"), + (0xF99B, "M", "鍊"), + (0xF99C, "M", "列"), + (0xF99D, "M", "劣"), + (0xF99E, "M", "咽"), + (0xF99F, "M", "烈"), + (0xF9A0, "M", "裂"), + (0xF9A1, "M", "čŖŖ"), + (0xF9A2, "M", "廉"), + (0xF9A3, "M", "åæµ"), + (0xF9A4, "M", "ę»"), + (0xF9A5, "M", "ę®®"), + (0xF9A6, "M", "ē°¾"), + (0xF9A7, "M", "ēµ"), + (0xF9A8, "M", "令"), + (0xF9A9, "M", "囹"), + (0xF9AA, "M", "寧"), + (0xF9AB, "M", "å¶ŗ"), + (0xF9AC, "M", "ꀜ"), + (0xF9AD, "M", "ēŽ²"), ] + def _seg_41() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xF9AA, 'M', '寧'), - (0xF9AB, 'M', 'å¶ŗ'), - (0xF9AC, 'M', 'ꀜ'), - (0xF9AD, 'M', 'ēŽ²'), - (0xF9AE, 'M', 'ē‘©'), - (0xF9AF, 'M', '羚'), - (0xF9B0, 'M', '聆'), - (0xF9B1, 'M', '鈓'), - (0xF9B2, 'M', '零'), - (0xF9B3, 'M', '靈'), - (0xF9B4, 'M', '領'), - (0xF9B5, 'M', '例'), - (0xF9B6, 'M', '禮'), - (0xF9B7, 'M', '醓'), - (0xF9B8, 'M', '隸'), - (0xF9B9, 'M', 'ꃔ'), - (0xF9BA, 'M', 'äŗ†'), - (0xF9BB, 'M', '僚'), - (0xF9BC, 'M', '寮'), - (0xF9BD, 'M', 'å°æ'), - (0xF9BE, 'M', 'ꖙ'), - (0xF9BF, 'M', '樂'), - (0xF9C0, 'M', 'ē‡Ž'), - (0xF9C1, 'M', '療'), - (0xF9C2, 'M', '蓼'), - (0xF9C3, 'M', '遼'), - (0xF9C4, 'M', '龍'), - (0xF9C5, 'M', '暈'), - (0xF9C6, 'M', '阮'), - (0xF9C7, 'M', '劉'), - (0xF9C8, 'M', 'ę»'), - (0xF9C9, 'M', '柳'), - (0xF9CA, 'M', '굁'), - (0xF9CB, 'M', '溜'), - (0xF9CC, 'M', '琉'), - (0xF9CD, 'M', 'ē•™'), - (0xF9CE, 'M', '甫'), - (0xF9CF, 'M', '瓐'), - (0xF9D0, 'M', '锞'), - (0xF9D1, 'M', '六'), - (0xF9D2, 'M', 'ꈮ'), - (0xF9D3, 'M', '陸'), - (0xF9D4, 'M', '倫'), - (0xF9D5, 'M', 'å“™'), - (0xF9D6, 'M', 'ę·Ŗ'), - (0xF9D7, 'M', 'č¼Ŗ'), - (0xF9D8, 'M', '律'), - (0xF9D9, 'M', 'ꅄ'), - (0xF9DA, 'M', 'ꠗ'), - (0xF9DB, 'M', 'ēŽ‡'), - (0xF9DC, 'M', '隆'), - (0xF9DD, 'M', '利'), - (0xF9DE, 'M', '吏'), - (0xF9DF, 'M', '屄'), - (0xF9E0, 'M', 'ꘓ'), - (0xF9E1, 'M', 'Ꝏ'), - (0xF9E2, 'M', '梨'), - (0xF9E3, 'M', '泄'), - (0xF9E4, 'M', '理'), - (0xF9E5, 'M', 'ē—¢'), - (0xF9E6, 'M', 'ē½¹'), - (0xF9E7, 'M', 'č£'), - (0xF9E8, 'M', '裔'), - (0xF9E9, 'M', '里'), - (0xF9EA, 'M', '離'), - (0xF9EB, 'M', '匿'), - (0xF9EC, 'M', 'ęŗŗ'), - (0xF9ED, 'M', '吝'), - (0xF9EE, 'M', '燐'), - (0xF9EF, 'M', 'ē’˜'), - (0xF9F0, 'M', 'č—ŗ'), - (0xF9F1, 'M', '隣'), - (0xF9F2, 'M', '鱗'), - (0xF9F3, 'M', '麟'), - (0xF9F4, 'M', 'ꞗ'), - (0xF9F5, 'M', 'ę·‹'), - (0xF9F6, 'M', '臨'), - (0xF9F7, 'M', 'ē«‹'), - (0xF9F8, 'M', '笠'), - (0xF9F9, 'M', 'ē²’'), - (0xF9FA, 'M', 'ē‹€'), - (0xF9FB, 'M', 'ē‚™'), - (0xF9FC, 'M', '識'), - (0xF9FD, 'M', '什'), - (0xF9FE, 'M', '茶'), - (0xF9FF, 'M', '刺'), - (0xFA00, 'M', '切'), - (0xFA01, 'M', 'åŗ¦'), - (0xFA02, 'M', 'ꋓ'), - (0xFA03, 'M', 'ē³–'), - (0xFA04, 'M', '宅'), - (0xFA05, 'M', 'ꓞ'), - (0xFA06, 'M', '暓'), - (0xFA07, 'M', 'č¼»'), - (0xFA08, 'M', '蔌'), - (0xFA09, 'M', '降'), - (0xFA0A, 'M', '見'), - (0xFA0B, 'M', '廓'), - (0xFA0C, 'M', '兀'), - (0xFA0D, 'M', '嗀'), + (0xF9AE, "M", "ē‘©"), + (0xF9AF, "M", "羚"), + (0xF9B0, "M", "聆"), + (0xF9B1, "M", "鈓"), + (0xF9B2, "M", "零"), + (0xF9B3, "M", "靈"), + (0xF9B4, "M", "領"), + (0xF9B5, "M", "例"), + (0xF9B6, "M", "禮"), + (0xF9B7, "M", "醓"), + (0xF9B8, "M", "隸"), + (0xF9B9, "M", "ꃔ"), + (0xF9BA, "M", "äŗ†"), + (0xF9BB, "M", "僚"), + (0xF9BC, "M", "寮"), + (0xF9BD, "M", "å°æ"), + (0xF9BE, "M", "ꖙ"), + (0xF9BF, "M", "樂"), + (0xF9C0, "M", "ē‡Ž"), + (0xF9C1, "M", "療"), + (0xF9C2, "M", "蓼"), + (0xF9C3, "M", "遼"), + (0xF9C4, "M", "龍"), + (0xF9C5, "M", "暈"), + (0xF9C6, "M", "阮"), + (0xF9C7, "M", "劉"), + (0xF9C8, "M", "ę»"), + (0xF9C9, "M", "柳"), + (0xF9CA, "M", "굁"), + (0xF9CB, "M", "溜"), + (0xF9CC, "M", "琉"), + (0xF9CD, "M", "ē•™"), + (0xF9CE, "M", "甫"), + (0xF9CF, "M", "瓐"), + (0xF9D0, "M", "锞"), + (0xF9D1, "M", "六"), + (0xF9D2, "M", "ꈮ"), + (0xF9D3, "M", "陸"), + (0xF9D4, "M", "倫"), + (0xF9D5, "M", "å“™"), + (0xF9D6, "M", "ę·Ŗ"), + (0xF9D7, "M", "č¼Ŗ"), + (0xF9D8, "M", "律"), + (0xF9D9, "M", "ꅄ"), + (0xF9DA, "M", "ꠗ"), + (0xF9DB, "M", "ēŽ‡"), + (0xF9DC, "M", "隆"), + (0xF9DD, "M", "利"), + (0xF9DE, "M", "吏"), + (0xF9DF, "M", "屄"), + (0xF9E0, "M", "ꘓ"), + (0xF9E1, "M", "Ꝏ"), + (0xF9E2, "M", "梨"), + (0xF9E3, "M", "泄"), + (0xF9E4, "M", "理"), + (0xF9E5, "M", "ē—¢"), + (0xF9E6, "M", "ē½¹"), + (0xF9E7, "M", "č£"), + (0xF9E8, "M", "裔"), + (0xF9E9, "M", "里"), + (0xF9EA, "M", "離"), + (0xF9EB, "M", "匿"), + (0xF9EC, "M", "ęŗŗ"), + (0xF9ED, "M", "吝"), + (0xF9EE, "M", "燐"), + (0xF9EF, "M", "ē’˜"), + (0xF9F0, "M", "č—ŗ"), + (0xF9F1, "M", "隣"), + (0xF9F2, "M", "鱗"), + (0xF9F3, "M", "麟"), + (0xF9F4, "M", "ꞗ"), + (0xF9F5, "M", "ę·‹"), + (0xF9F6, "M", "臨"), + (0xF9F7, "M", "ē«‹"), + (0xF9F8, "M", "笠"), + (0xF9F9, "M", "ē²’"), + (0xF9FA, "M", "ē‹€"), + (0xF9FB, "M", "ē‚™"), + (0xF9FC, "M", "識"), + (0xF9FD, "M", "什"), + (0xF9FE, "M", "茶"), + (0xF9FF, "M", "刺"), + (0xFA00, "M", "切"), + (0xFA01, "M", "åŗ¦"), + (0xFA02, "M", "ꋓ"), + (0xFA03, "M", "ē³–"), + (0xFA04, "M", "宅"), + (0xFA05, "M", "ꓞ"), + (0xFA06, "M", "暓"), + (0xFA07, "M", "č¼»"), + (0xFA08, "M", "蔌"), + (0xFA09, "M", "降"), + (0xFA0A, "M", "見"), + (0xFA0B, "M", "廓"), + (0xFA0C, "M", "兀"), + (0xFA0D, "M", "嗀"), + (0xFA0E, "V"), + (0xFA10, "M", "唚"), + (0xFA11, "V"), + (0xFA12, "M", "ꙓ"), ] + def _seg_42() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFA0E, 'V'), - (0xFA10, 'M', '唚'), - (0xFA11, 'V'), - (0xFA12, 'M', 'ꙓ'), - (0xFA13, 'V'), - (0xFA15, 'M', '凞'), - (0xFA16, 'M', '猪'), - (0xFA17, 'M', 'ē›Š'), - (0xFA18, 'M', '礼'), - (0xFA19, 'M', 'ē„ž'), - (0xFA1A, 'M', 'ē„„'), - (0xFA1B, 'M', 'ē¦'), - (0xFA1C, 'M', '靖'), - (0xFA1D, 'M', 'ē²¾'), - (0xFA1E, 'M', 'ē¾½'), - (0xFA1F, 'V'), - (0xFA20, 'M', '蘒'), - (0xFA21, 'V'), - (0xFA22, 'M', '諸'), - (0xFA23, 'V'), - (0xFA25, 'M', '逸'), - (0xFA26, 'M', '都'), - (0xFA27, 'V'), - (0xFA2A, 'M', '飯'), - (0xFA2B, 'M', '飼'), - (0xFA2C, 'M', '館'), - (0xFA2D, 'M', 'é¶“'), - (0xFA2E, 'M', '郞'), - (0xFA2F, 'M', '隷'), - (0xFA30, 'M', 'ä¾®'), - (0xFA31, 'M', '僧'), - (0xFA32, 'M', '免'), - (0xFA33, 'M', '勉'), - (0xFA34, 'M', '勤'), - (0xFA35, 'M', '卑'), - (0xFA36, 'M', '喝'), - (0xFA37, 'M', '嘆'), - (0xFA38, 'M', '器'), - (0xFA39, 'M', '唀'), - (0xFA3A, 'M', '墨'), - (0xFA3B, 'M', '層'), - (0xFA3C, 'M', 'å±®'), - (0xFA3D, 'M', 'ꂔ'), - (0xFA3E, 'M', 'ę…Ø'), - (0xFA3F, 'M', 'ꆎ'), - (0xFA40, 'M', '懲'), - (0xFA41, 'M', 'ꕏ'), - (0xFA42, 'M', 'ę—¢'), - (0xFA43, 'M', 'ꚑ'), - (0xFA44, 'M', '梅'), - (0xFA45, 'M', 'ęµ·'), - (0xFA46, 'M', '渚'), - (0xFA47, 'M', 'ę¼¢'), - (0xFA48, 'M', 'ē…®'), - (0xFA49, 'M', '爫'), - (0xFA4A, 'M', '琢'), - (0xFA4B, 'M', '碑'), - (0xFA4C, 'M', '社'), - (0xFA4D, 'M', '焉'), - (0xFA4E, 'M', '焈'), - (0xFA4F, 'M', '焐'), - (0xFA50, 'M', 'ē„–'), - (0xFA51, 'M', 'ē„'), - (0xFA52, 'M', 'ē¦'), - (0xFA53, 'M', 'ē¦Ž'), - (0xFA54, 'M', 'ē©€'), - (0xFA55, 'M', '突'), - (0xFA56, 'M', '節'), - (0xFA57, 'M', 'ē·“'), - (0xFA58, 'M', 'ēø‰'), - (0xFA59, 'M', '繁'), - (0xFA5A, 'M', 'ē½²'), - (0xFA5B, 'M', '者'), - (0xFA5C, 'M', '臭'), - (0xFA5D, 'M', '艹'), - (0xFA5F, 'M', '著'), - (0xFA60, 'M', '褐'), - (0xFA61, 'M', '視'), - (0xFA62, 'M', '謁'), - (0xFA63, 'M', '謹'), - (0xFA64, 'M', '賓'), - (0xFA65, 'M', '蓈'), - (0xFA66, 'M', 'č¾¶'), - (0xFA67, 'M', '逸'), - (0xFA68, 'M', '難'), - (0xFA69, 'M', '響'), - (0xFA6A, 'M', 'é »'), - (0xFA6B, 'M', 'ꁵ'), - (0xFA6C, 'M', '𤋮'), - (0xFA6D, 'M', '舘'), - (0xFA6E, 'X'), - (0xFA70, 'M', 'äø¦'), - (0xFA71, 'M', '况'), - (0xFA72, 'M', 'å…Ø'), - (0xFA73, 'M', '侀'), - (0xFA74, 'M', '充'), - (0xFA75, 'M', '冀'), - (0xFA76, 'M', '勇'), - (0xFA77, 'M', '勺'), - (0xFA78, 'M', '喝'), + (0xFA13, "V"), + (0xFA15, "M", "凞"), + (0xFA16, "M", "猪"), + (0xFA17, "M", "ē›Š"), + (0xFA18, "M", "礼"), + (0xFA19, "M", "ē„ž"), + (0xFA1A, "M", "ē„„"), + (0xFA1B, "M", "ē¦"), + (0xFA1C, "M", "靖"), + (0xFA1D, "M", "ē²¾"), + (0xFA1E, "M", "ē¾½"), + (0xFA1F, "V"), + (0xFA20, "M", "蘒"), + (0xFA21, "V"), + (0xFA22, "M", "諸"), + (0xFA23, "V"), + (0xFA25, "M", "逸"), + (0xFA26, "M", "都"), + (0xFA27, "V"), + (0xFA2A, "M", "飯"), + (0xFA2B, "M", "飼"), + (0xFA2C, "M", "館"), + (0xFA2D, "M", "é¶“"), + (0xFA2E, "M", "郞"), + (0xFA2F, "M", "隷"), + (0xFA30, "M", "ä¾®"), + (0xFA31, "M", "僧"), + (0xFA32, "M", "免"), + (0xFA33, "M", "勉"), + (0xFA34, "M", "勤"), + (0xFA35, "M", "卑"), + (0xFA36, "M", "喝"), + (0xFA37, "M", "嘆"), + (0xFA38, "M", "器"), + (0xFA39, "M", "唀"), + (0xFA3A, "M", "墨"), + (0xFA3B, "M", "層"), + (0xFA3C, "M", "å±®"), + (0xFA3D, "M", "ꂔ"), + (0xFA3E, "M", "ę…Ø"), + (0xFA3F, "M", "ꆎ"), + (0xFA40, "M", "懲"), + (0xFA41, "M", "ꕏ"), + (0xFA42, "M", "ę—¢"), + (0xFA43, "M", "ꚑ"), + (0xFA44, "M", "梅"), + (0xFA45, "M", "ęµ·"), + (0xFA46, "M", "渚"), + (0xFA47, "M", "ę¼¢"), + (0xFA48, "M", "ē…®"), + (0xFA49, "M", "爫"), + (0xFA4A, "M", "琢"), + (0xFA4B, "M", "碑"), + (0xFA4C, "M", "社"), + (0xFA4D, "M", "焉"), + (0xFA4E, "M", "焈"), + (0xFA4F, "M", "焐"), + (0xFA50, "M", "ē„–"), + (0xFA51, "M", "ē„"), + (0xFA52, "M", "ē¦"), + (0xFA53, "M", "ē¦Ž"), + (0xFA54, "M", "ē©€"), + (0xFA55, "M", "突"), + (0xFA56, "M", "節"), + (0xFA57, "M", "ē·“"), + (0xFA58, "M", "ēø‰"), + (0xFA59, "M", "繁"), + (0xFA5A, "M", "ē½²"), + (0xFA5B, "M", "者"), + (0xFA5C, "M", "臭"), + (0xFA5D, "M", "艹"), + (0xFA5F, "M", "著"), + (0xFA60, "M", "褐"), + (0xFA61, "M", "視"), + (0xFA62, "M", "謁"), + (0xFA63, "M", "謹"), + (0xFA64, "M", "賓"), + (0xFA65, "M", "蓈"), + (0xFA66, "M", "č¾¶"), + (0xFA67, "M", "逸"), + (0xFA68, "M", "難"), + (0xFA69, "M", "響"), + (0xFA6A, "M", "é »"), + (0xFA6B, "M", "ꁵ"), + (0xFA6C, "M", "𤋮"), + (0xFA6D, "M", "舘"), + (0xFA6E, "X"), + (0xFA70, "M", "äø¦"), + (0xFA71, "M", "况"), + (0xFA72, "M", "å…Ø"), + (0xFA73, "M", "侀"), + (0xFA74, "M", "充"), + (0xFA75, "M", "冀"), + (0xFA76, "M", "勇"), + (0xFA77, "M", "勺"), + (0xFA78, "M", "喝"), + (0xFA79, "M", "啕"), + (0xFA7A, "M", "喙"), + (0xFA7B, "M", "嗢"), + (0xFA7C, "M", "唚"), ] + def _seg_43() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFA79, 'M', '啕'), - (0xFA7A, 'M', '喙'), - (0xFA7B, 'M', '嗢'), - (0xFA7C, 'M', '唚'), - (0xFA7D, 'M', '墳'), - (0xFA7E, 'M', 'å„„'), - (0xFA7F, 'M', 'å„”'), - (0xFA80, 'M', 'å©¢'), - (0xFA81, 'M', '嬨'), - (0xFA82, 'M', '廒'), - (0xFA83, 'M', '廙'), - (0xFA84, 'M', '彩'), - (0xFA85, 'M', 'å¾­'), - (0xFA86, 'M', 'ꃘ'), - (0xFA87, 'M', 'ꅎ'), - (0xFA88, 'M', 'ꄈ'), - (0xFA89, 'M', 'ꆎ'), - (0xFA8A, 'M', 'ꅠ'), - (0xFA8B, 'M', '懲'), - (0xFA8C, 'M', 'ꈓ'), - (0xFA8D, 'M', 'ꏄ'), - (0xFA8E, 'M', '搜'), - (0xFA8F, 'M', 'ꑒ'), - (0xFA90, 'M', 'ꕖ'), - (0xFA91, 'M', 'ꙓ'), - (0xFA92, 'M', 'ꜗ'), - (0xFA93, 'M', 'ꜛ'), - (0xFA94, 'M', 'Ꝗ'), - (0xFA95, 'M', 'ę­¹'), - (0xFA96, 'M', '殺'), - (0xFA97, 'M', '굁'), - (0xFA98, 'M', 'ę»›'), - (0xFA99, 'M', '껋'), - (0xFA9A, 'M', 'ę¼¢'), - (0xFA9B, 'M', 'ē€ž'), - (0xFA9C, 'M', 'ē…®'), - (0xFA9D, 'M', 'ēž§'), - (0xFA9E, 'M', '爵'), - (0xFA9F, 'M', '犯'), - (0xFAA0, 'M', '猪'), - (0xFAA1, 'M', '瑱'), - (0xFAA2, 'M', '甆'), - (0xFAA3, 'M', 'ē”»'), - (0xFAA4, 'M', 'ē˜'), - (0xFAA5, 'M', '瘟'), - (0xFAA6, 'M', 'ē›Š'), - (0xFAA7, 'M', 'ē››'), - (0xFAA8, 'M', '盓'), - (0xFAA9, 'M', 'ēŠ'), - (0xFAAA, 'M', 'ē€'), - (0xFAAB, 'M', '磌'), - (0xFAAC, 'M', 'ēŖ±'), - (0xFAAD, 'M', '節'), - (0xFAAE, 'M', 'ē±»'), - (0xFAAF, 'M', 'ēµ›'), - (0xFAB0, 'M', 'ē·“'), - (0xFAB1, 'M', 'ē¼¾'), - (0xFAB2, 'M', '者'), - (0xFAB3, 'M', '荒'), - (0xFAB4, 'M', 'čÆ'), - (0xFAB5, 'M', 'č¹'), - (0xFAB6, 'M', '脁'), - (0xFAB7, 'M', '覆'), - (0xFAB8, 'M', '視'), - (0xFAB9, 'M', 'čŖæ'), - (0xFABA, 'M', '諸'), - (0xFABB, 'M', 'č«‹'), - (0xFABC, 'M', '謁'), - (0xFABD, 'M', '諾'), - (0xFABE, 'M', 'č«­'), - (0xFABF, 'M', '謹'), - (0xFAC0, 'M', '變'), - (0xFAC1, 'M', '蓈'), - (0xFAC2, 'M', 'č¼ø'), - (0xFAC3, 'M', '遲'), - (0xFAC4, 'M', '醙'), - (0xFAC5, 'M', '鉶'), - (0xFAC6, 'M', '陼'), - (0xFAC7, 'M', '難'), - (0xFAC8, 'M', '靖'), - (0xFAC9, 'M', '韛'), - (0xFACA, 'M', '響'), - (0xFACB, 'M', '頋'), - (0xFACC, 'M', 'é »'), - (0xFACD, 'M', '鬒'), - (0xFACE, 'M', '龜'), - (0xFACF, 'M', '𢔊'), - (0xFAD0, 'M', '𢔄'), - (0xFAD1, 'M', 'š£•'), - (0xFAD2, 'M', 'ć®'), - (0xFAD3, 'M', '䀘'), - (0xFAD4, 'M', '䀹'), - (0xFAD5, 'M', 'š„‰‰'), - (0xFAD6, 'M', 'š„³'), - (0xFAD7, 'M', '𧻓'), - (0xFAD8, 'M', '齃'), - (0xFAD9, 'M', '龎'), - (0xFADA, 'X'), - (0xFB00, 'M', 'ff'), - (0xFB01, 'M', 'fi'), + (0xFA7D, "M", "墳"), + (0xFA7E, "M", "å„„"), + (0xFA7F, "M", "å„”"), + (0xFA80, "M", "å©¢"), + (0xFA81, "M", "嬨"), + (0xFA82, "M", "廒"), + (0xFA83, "M", "廙"), + (0xFA84, "M", "彩"), + (0xFA85, "M", "å¾­"), + (0xFA86, "M", "ꃘ"), + (0xFA87, "M", "ꅎ"), + (0xFA88, "M", "ꄈ"), + (0xFA89, "M", "ꆎ"), + (0xFA8A, "M", "ꅠ"), + (0xFA8B, "M", "懲"), + (0xFA8C, "M", "ꈓ"), + (0xFA8D, "M", "ꏄ"), + (0xFA8E, "M", "搜"), + (0xFA8F, "M", "ꑒ"), + (0xFA90, "M", "ꕖ"), + (0xFA91, "M", "ꙓ"), + (0xFA92, "M", "ꜗ"), + (0xFA93, "M", "ꜛ"), + (0xFA94, "M", "Ꝗ"), + (0xFA95, "M", "ę­¹"), + (0xFA96, "M", "殺"), + (0xFA97, "M", "굁"), + (0xFA98, "M", "ę»›"), + (0xFA99, "M", "껋"), + (0xFA9A, "M", "ę¼¢"), + (0xFA9B, "M", "ē€ž"), + (0xFA9C, "M", "ē…®"), + (0xFA9D, "M", "ēž§"), + (0xFA9E, "M", "爵"), + (0xFA9F, "M", "犯"), + (0xFAA0, "M", "猪"), + (0xFAA1, "M", "瑱"), + (0xFAA2, "M", "甆"), + (0xFAA3, "M", "ē”»"), + (0xFAA4, "M", "ē˜"), + (0xFAA5, "M", "瘟"), + (0xFAA6, "M", "ē›Š"), + (0xFAA7, "M", "ē››"), + (0xFAA8, "M", "盓"), + (0xFAA9, "M", "ēŠ"), + (0xFAAA, "M", "ē€"), + (0xFAAB, "M", "磌"), + (0xFAAC, "M", "ēŖ±"), + (0xFAAD, "M", "節"), + (0xFAAE, "M", "ē±»"), + (0xFAAF, "M", "ēµ›"), + (0xFAB0, "M", "ē·“"), + (0xFAB1, "M", "ē¼¾"), + (0xFAB2, "M", "者"), + (0xFAB3, "M", "荒"), + (0xFAB4, "M", "čÆ"), + (0xFAB5, "M", "č¹"), + (0xFAB6, "M", "脁"), + (0xFAB7, "M", "覆"), + (0xFAB8, "M", "視"), + (0xFAB9, "M", "čŖæ"), + (0xFABA, "M", "諸"), + (0xFABB, "M", "č«‹"), + (0xFABC, "M", "謁"), + (0xFABD, "M", "諾"), + (0xFABE, "M", "č«­"), + (0xFABF, "M", "謹"), + (0xFAC0, "M", "變"), + (0xFAC1, "M", "蓈"), + (0xFAC2, "M", "č¼ø"), + (0xFAC3, "M", "遲"), + (0xFAC4, "M", "醙"), + (0xFAC5, "M", "鉶"), + (0xFAC6, "M", "陼"), + (0xFAC7, "M", "難"), + (0xFAC8, "M", "靖"), + (0xFAC9, "M", "韛"), + (0xFACA, "M", "響"), + (0xFACB, "M", "頋"), + (0xFACC, "M", "é »"), + (0xFACD, "M", "鬒"), + (0xFACE, "M", "龜"), + (0xFACF, "M", "𢔊"), + (0xFAD0, "M", "𢔄"), + (0xFAD1, "M", "š£•"), + (0xFAD2, "M", "ć®"), + (0xFAD3, "M", "䀘"), + (0xFAD4, "M", "䀹"), + (0xFAD5, "M", "š„‰‰"), + (0xFAD6, "M", "š„³"), + (0xFAD7, "M", "𧻓"), + (0xFAD8, "M", "齃"), + (0xFAD9, "M", "龎"), + (0xFADA, "X"), + (0xFB00, "M", "ff"), + (0xFB01, "M", "fi"), + (0xFB02, "M", "fl"), + (0xFB03, "M", "ffi"), + (0xFB04, "M", "ffl"), + (0xFB05, "M", "st"), ] + def _seg_44() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFB02, 'M', 'fl'), - (0xFB03, 'M', 'ffi'), - (0xFB04, 'M', 'ffl'), - (0xFB05, 'M', 'st'), - (0xFB07, 'X'), - (0xFB13, 'M', 'Õ“Õ¶'), - (0xFB14, 'M', 'Õ“Õ„'), - (0xFB15, 'M', 'Õ“Õ«'), - (0xFB16, 'M', 'Õ¾Õ¶'), - (0xFB17, 'M', 'Õ“Õ­'), - (0xFB18, 'X'), - (0xFB1D, 'M', '×™Ö“'), - (0xFB1E, 'V'), - (0xFB1F, 'M', 'ײַ'), - (0xFB20, 'M', '×¢'), - (0xFB21, 'M', 'א'), - (0xFB22, 'M', 'ד'), - (0xFB23, 'M', 'ה'), - (0xFB24, 'M', 'כ'), - (0xFB25, 'M', 'ל'), - (0xFB26, 'M', 'ם'), - (0xFB27, 'M', 'ר'), - (0xFB28, 'M', '×Ŗ'), - (0xFB29, '3', '+'), - (0xFB2A, 'M', 'שׁ'), - (0xFB2B, 'M', 'שׂ'), - (0xFB2C, 'M', 'שּׁ'), - (0xFB2D, 'M', 'שּׂ'), - (0xFB2E, 'M', 'אַ'), - (0xFB2F, 'M', 'אָ'), - (0xFB30, 'M', 'אּ'), - (0xFB31, 'M', 'בּ'), - (0xFB32, 'M', 'גּ'), - (0xFB33, 'M', 'דּ'), - (0xFB34, 'M', 'הּ'), - (0xFB35, 'M', 'וּ'), - (0xFB36, 'M', 'זּ'), - (0xFB37, 'X'), - (0xFB38, 'M', 'טּ'), - (0xFB39, 'M', 'יּ'), - (0xFB3A, 'M', 'ךּ'), - (0xFB3B, 'M', 'כּ'), - (0xFB3C, 'M', 'לּ'), - (0xFB3D, 'X'), - (0xFB3E, 'M', 'מּ'), - (0xFB3F, 'X'), - (0xFB40, 'M', '× Ö¼'), - (0xFB41, 'M', '×”Ö¼'), - (0xFB42, 'X'), - (0xFB43, 'M', '×£Ö¼'), - (0xFB44, 'M', 'פּ'), - (0xFB45, 'X'), - (0xFB46, 'M', 'צּ'), - (0xFB47, 'M', '×§Ö¼'), - (0xFB48, 'M', 'רּ'), - (0xFB49, 'M', 'שּ'), - (0xFB4A, 'M', '×ŖÖ¼'), - (0xFB4B, 'M', 'וֹ'), - (0xFB4C, 'M', 'בֿ'), - (0xFB4D, 'M', '×›Öæ'), - (0xFB4E, 'M', 'פֿ'), - (0xFB4F, 'M', 'אל'), - (0xFB50, 'M', 'ٱ'), - (0xFB52, 'M', 'Ł»'), - (0xFB56, 'M', 'پ'), - (0xFB5A, 'M', 'Ś€'), - (0xFB5E, 'M', 'Łŗ'), - (0xFB62, 'M', 'Łæ'), - (0xFB66, 'M', 'ٹ'), - (0xFB6A, 'M', 'ڤ'), - (0xFB6E, 'M', 'ڦ'), - (0xFB72, 'M', 'Ś„'), - (0xFB76, 'M', 'ڃ'), - (0xFB7A, 'M', 'چ'), - (0xFB7E, 'M', 'ڇ'), - (0xFB82, 'M', 'Ś'), - (0xFB84, 'M', 'ڌ'), - (0xFB86, 'M', 'ŚŽ'), - (0xFB88, 'M', 'ڈ'), - (0xFB8A, 'M', 'ژ'), - (0xFB8C, 'M', 'Ś‘'), - (0xFB8E, 'M', 'Ś©'), - (0xFB92, 'M', 'ŚÆ'), - (0xFB96, 'M', 'ڳ'), - (0xFB9A, 'M', 'ڱ'), - (0xFB9E, 'M', 'Śŗ'), - (0xFBA0, 'M', 'Ś»'), - (0xFBA4, 'M', 'Ū€'), - (0xFBA6, 'M', 'ہ'), - (0xFBAA, 'M', 'ھ'), - (0xFBAE, 'M', 'Ū’'), - (0xFBB0, 'M', 'Ū“'), - (0xFBB2, 'V'), - (0xFBC3, 'X'), - (0xFBD3, 'M', 'Ś­'), - (0xFBD7, 'M', 'Ū‡'), - (0xFBD9, 'M', 'Ū†'), - (0xFBDB, 'M', 'ۈ'), - (0xFBDD, 'M', 'ۇٓ'), - (0xFBDE, 'M', 'Ū‹'), + (0xFB07, "X"), + (0xFB13, "M", "Õ“Õ¶"), + (0xFB14, "M", "Õ“Õ„"), + (0xFB15, "M", "Õ“Õ«"), + (0xFB16, "M", "Õ¾Õ¶"), + (0xFB17, "M", "Õ“Õ­"), + (0xFB18, "X"), + (0xFB1D, "M", "×™Ö“"), + (0xFB1E, "V"), + (0xFB1F, "M", "ײַ"), + (0xFB20, "M", "×¢"), + (0xFB21, "M", "א"), + (0xFB22, "M", "ד"), + (0xFB23, "M", "ה"), + (0xFB24, "M", "כ"), + (0xFB25, "M", "ל"), + (0xFB26, "M", "ם"), + (0xFB27, "M", "ר"), + (0xFB28, "M", "×Ŗ"), + (0xFB29, "3", "+"), + (0xFB2A, "M", "שׁ"), + (0xFB2B, "M", "שׂ"), + (0xFB2C, "M", "שּׁ"), + (0xFB2D, "M", "שּׂ"), + (0xFB2E, "M", "אַ"), + (0xFB2F, "M", "אָ"), + (0xFB30, "M", "אּ"), + (0xFB31, "M", "בּ"), + (0xFB32, "M", "גּ"), + (0xFB33, "M", "דּ"), + (0xFB34, "M", "הּ"), + (0xFB35, "M", "וּ"), + (0xFB36, "M", "זּ"), + (0xFB37, "X"), + (0xFB38, "M", "טּ"), + (0xFB39, "M", "יּ"), + (0xFB3A, "M", "ךּ"), + (0xFB3B, "M", "כּ"), + (0xFB3C, "M", "לּ"), + (0xFB3D, "X"), + (0xFB3E, "M", "מּ"), + (0xFB3F, "X"), + (0xFB40, "M", "× Ö¼"), + (0xFB41, "M", "×”Ö¼"), + (0xFB42, "X"), + (0xFB43, "M", "×£Ö¼"), + (0xFB44, "M", "פּ"), + (0xFB45, "X"), + (0xFB46, "M", "צּ"), + (0xFB47, "M", "×§Ö¼"), + (0xFB48, "M", "רּ"), + (0xFB49, "M", "שּ"), + (0xFB4A, "M", "×ŖÖ¼"), + (0xFB4B, "M", "וֹ"), + (0xFB4C, "M", "בֿ"), + (0xFB4D, "M", "×›Öæ"), + (0xFB4E, "M", "פֿ"), + (0xFB4F, "M", "אל"), + (0xFB50, "M", "ٱ"), + (0xFB52, "M", "Ł»"), + (0xFB56, "M", "پ"), + (0xFB5A, "M", "Ś€"), + (0xFB5E, "M", "Łŗ"), + (0xFB62, "M", "Łæ"), + (0xFB66, "M", "ٹ"), + (0xFB6A, "M", "ڤ"), + (0xFB6E, "M", "ڦ"), + (0xFB72, "M", "Ś„"), + (0xFB76, "M", "ڃ"), + (0xFB7A, "M", "چ"), + (0xFB7E, "M", "ڇ"), + (0xFB82, "M", "Ś"), + (0xFB84, "M", "ڌ"), + (0xFB86, "M", "ŚŽ"), + (0xFB88, "M", "ڈ"), + (0xFB8A, "M", "ژ"), + (0xFB8C, "M", "Ś‘"), + (0xFB8E, "M", "Ś©"), + (0xFB92, "M", "ŚÆ"), + (0xFB96, "M", "ڳ"), + (0xFB9A, "M", "ڱ"), + (0xFB9E, "M", "Śŗ"), + (0xFBA0, "M", "Ś»"), + (0xFBA4, "M", "Ū€"), + (0xFBA6, "M", "ہ"), + (0xFBAA, "M", "ھ"), + (0xFBAE, "M", "Ū’"), + (0xFBB0, "M", "Ū“"), + (0xFBB2, "V"), + (0xFBC3, "X"), + (0xFBD3, "M", "Ś­"), + (0xFBD7, "M", "Ū‡"), + (0xFBD9, "M", "Ū†"), + (0xFBDB, "M", "ۈ"), + (0xFBDD, "M", "ۇٓ"), + (0xFBDE, "M", "Ū‹"), + (0xFBE0, "M", "Ū…"), + (0xFBE2, "M", "Ū‰"), + (0xFBE4, "M", "ې"), + (0xFBE8, "M", "ى"), ] + def _seg_45() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFBE0, 'M', 'Ū…'), - (0xFBE2, 'M', 'Ū‰'), - (0xFBE4, 'M', 'ې'), - (0xFBE8, 'M', 'ى'), - (0xFBEA, 'M', 'Ų¦Ų§'), - (0xFBEC, 'M', 'Ų¦Ū•'), - (0xFBEE, 'M', 'ئو'), - (0xFBF0, 'M', 'Ų¦Ū‡'), - (0xFBF2, 'M', 'Ų¦Ū†'), - (0xFBF4, 'M', 'ئۈ'), - (0xFBF6, 'M', 'ئې'), - (0xFBF9, 'M', 'ئى'), - (0xFBFC, 'M', 'ی'), - (0xFC00, 'M', 'Ų¦Ų¬'), - (0xFC01, 'M', 'Ų¦Ų­'), - (0xFC02, 'M', 'ئم'), - (0xFC03, 'M', 'ئى'), - (0xFC04, 'M', 'ئي'), - (0xFC05, 'M', 'ŲØŲ¬'), - (0xFC06, 'M', 'ŲØŲ­'), - (0xFC07, 'M', 'ŲØŲ®'), - (0xFC08, 'M', 'ŲØŁ…'), - (0xFC09, 'M', 'بى'), - (0xFC0A, 'M', 'بي'), - (0xFC0B, 'M', 'ŲŖŲ¬'), - (0xFC0C, 'M', 'ŲŖŲ­'), - (0xFC0D, 'M', 'ŲŖŲ®'), - (0xFC0E, 'M', 'ŲŖŁ…'), - (0xFC0F, 'M', 'تى'), - (0xFC10, 'M', 'تي'), - (0xFC11, 'M', 'Ų«Ų¬'), - (0xFC12, 'M', 'Ų«Ł…'), - (0xFC13, 'M', 'ثى'), - (0xFC14, 'M', 'ثي'), - (0xFC15, 'M', 'Ų¬Ų­'), - (0xFC16, 'M', 'جم'), - (0xFC17, 'M', 'Ų­Ų¬'), - (0xFC18, 'M', 'Ų­Ł…'), - (0xFC19, 'M', 'Ų®Ų¬'), - (0xFC1A, 'M', 'Ų®Ų­'), - (0xFC1B, 'M', 'خم'), - (0xFC1C, 'M', 'Ų³Ų¬'), - (0xFC1D, 'M', 'Ų³Ų­'), - (0xFC1E, 'M', 'Ų³Ų®'), - (0xFC1F, 'M', 'سم'), - (0xFC20, 'M', 'ŲµŲ­'), - (0xFC21, 'M', 'صم'), - (0xFC22, 'M', 'Ų¶Ų¬'), - (0xFC23, 'M', 'Ų¶Ų­'), - (0xFC24, 'M', 'Ų¶Ų®'), - (0xFC25, 'M', 'Ų¶Ł…'), - (0xFC26, 'M', 'Ų·Ų­'), - (0xFC27, 'M', 'Ų·Ł…'), - (0xFC28, 'M', 'ŲøŁ…'), - (0xFC29, 'M', 'Ų¹Ų¬'), - (0xFC2A, 'M', 'عم'), - (0xFC2B, 'M', 'ŲŗŲ¬'), - (0xFC2C, 'M', 'ŲŗŁ…'), - (0xFC2D, 'M', 'فج'), - (0xFC2E, 'M', 'فح'), - (0xFC2F, 'M', 'فخ'), - (0xFC30, 'M', 'فم'), - (0xFC31, 'M', 'فى'), - (0xFC32, 'M', 'في'), - (0xFC33, 'M', 'قح'), - (0xFC34, 'M', 'قم'), - (0xFC35, 'M', 'قى'), - (0xFC36, 'M', 'Ł‚ŁŠ'), - (0xFC37, 'M', 'كا'), - (0xFC38, 'M', 'كج'), - (0xFC39, 'M', 'كح'), - (0xFC3A, 'M', 'كخ'), - (0xFC3B, 'M', 'ŁƒŁ„'), - (0xFC3C, 'M', 'ŁƒŁ…'), - (0xFC3D, 'M', 'ŁƒŁ‰'), - (0xFC3E, 'M', 'كي'), - (0xFC3F, 'M', 'لج'), - (0xFC40, 'M', 'لح'), - (0xFC41, 'M', 'لخ'), - (0xFC42, 'M', 'لم'), - (0xFC43, 'M', 'لى'), - (0xFC44, 'M', 'Ł„ŁŠ'), - (0xFC45, 'M', 'Ł…Ų¬'), - (0xFC46, 'M', 'Ł…Ų­'), - (0xFC47, 'M', 'Ł…Ų®'), - (0xFC48, 'M', 'Ł…Ł…'), - (0xFC49, 'M', 'مى'), - (0xFC4A, 'M', 'Ł…ŁŠ'), - (0xFC4B, 'M', 'نج'), - (0xFC4C, 'M', 'نح'), - (0xFC4D, 'M', 'نخ'), - (0xFC4E, 'M', 'نم'), - (0xFC4F, 'M', 'نى'), - (0xFC50, 'M', 'Ł†ŁŠ'), - (0xFC51, 'M', 'هج'), - (0xFC52, 'M', 'هم'), - (0xFC53, 'M', 'هى'), - (0xFC54, 'M', 'Ł‡ŁŠ'), - (0xFC55, 'M', 'يج'), - (0xFC56, 'M', 'يح'), + (0xFBEA, "M", "Ų¦Ų§"), + (0xFBEC, "M", "Ų¦Ū•"), + (0xFBEE, "M", "ئو"), + (0xFBF0, "M", "Ų¦Ū‡"), + (0xFBF2, "M", "Ų¦Ū†"), + (0xFBF4, "M", "ئۈ"), + (0xFBF6, "M", "ئې"), + (0xFBF9, "M", "ئى"), + (0xFBFC, "M", "ی"), + (0xFC00, "M", "Ų¦Ų¬"), + (0xFC01, "M", "Ų¦Ų­"), + (0xFC02, "M", "ئم"), + (0xFC03, "M", "ئى"), + (0xFC04, "M", "ئي"), + (0xFC05, "M", "ŲØŲ¬"), + (0xFC06, "M", "ŲØŲ­"), + (0xFC07, "M", "ŲØŲ®"), + (0xFC08, "M", "ŲØŁ…"), + (0xFC09, "M", "بى"), + (0xFC0A, "M", "بي"), + (0xFC0B, "M", "ŲŖŲ¬"), + (0xFC0C, "M", "ŲŖŲ­"), + (0xFC0D, "M", "ŲŖŲ®"), + (0xFC0E, "M", "ŲŖŁ…"), + (0xFC0F, "M", "تى"), + (0xFC10, "M", "تي"), + (0xFC11, "M", "Ų«Ų¬"), + (0xFC12, "M", "Ų«Ł…"), + (0xFC13, "M", "ثى"), + (0xFC14, "M", "ثي"), + (0xFC15, "M", "Ų¬Ų­"), + (0xFC16, "M", "جم"), + (0xFC17, "M", "Ų­Ų¬"), + (0xFC18, "M", "Ų­Ł…"), + (0xFC19, "M", "Ų®Ų¬"), + (0xFC1A, "M", "Ų®Ų­"), + (0xFC1B, "M", "خم"), + (0xFC1C, "M", "Ų³Ų¬"), + (0xFC1D, "M", "Ų³Ų­"), + (0xFC1E, "M", "Ų³Ų®"), + (0xFC1F, "M", "سم"), + (0xFC20, "M", "ŲµŲ­"), + (0xFC21, "M", "صم"), + (0xFC22, "M", "Ų¶Ų¬"), + (0xFC23, "M", "Ų¶Ų­"), + (0xFC24, "M", "Ų¶Ų®"), + (0xFC25, "M", "Ų¶Ł…"), + (0xFC26, "M", "Ų·Ų­"), + (0xFC27, "M", "Ų·Ł…"), + (0xFC28, "M", "ŲøŁ…"), + (0xFC29, "M", "Ų¹Ų¬"), + (0xFC2A, "M", "عم"), + (0xFC2B, "M", "ŲŗŲ¬"), + (0xFC2C, "M", "ŲŗŁ…"), + (0xFC2D, "M", "فج"), + (0xFC2E, "M", "فح"), + (0xFC2F, "M", "فخ"), + (0xFC30, "M", "فم"), + (0xFC31, "M", "فى"), + (0xFC32, "M", "في"), + (0xFC33, "M", "قح"), + (0xFC34, "M", "قم"), + (0xFC35, "M", "قى"), + (0xFC36, "M", "Ł‚ŁŠ"), + (0xFC37, "M", "كا"), + (0xFC38, "M", "كج"), + (0xFC39, "M", "كح"), + (0xFC3A, "M", "كخ"), + (0xFC3B, "M", "ŁƒŁ„"), + (0xFC3C, "M", "ŁƒŁ…"), + (0xFC3D, "M", "ŁƒŁ‰"), + (0xFC3E, "M", "كي"), + (0xFC3F, "M", "لج"), + (0xFC40, "M", "لح"), + (0xFC41, "M", "لخ"), + (0xFC42, "M", "لم"), + (0xFC43, "M", "لى"), + (0xFC44, "M", "Ł„ŁŠ"), + (0xFC45, "M", "Ł…Ų¬"), + (0xFC46, "M", "Ł…Ų­"), + (0xFC47, "M", "Ł…Ų®"), + (0xFC48, "M", "Ł…Ł…"), + (0xFC49, "M", "مى"), + (0xFC4A, "M", "Ł…ŁŠ"), + (0xFC4B, "M", "نج"), + (0xFC4C, "M", "نح"), + (0xFC4D, "M", "نخ"), + (0xFC4E, "M", "نم"), + (0xFC4F, "M", "نى"), + (0xFC50, "M", "Ł†ŁŠ"), + (0xFC51, "M", "هج"), + (0xFC52, "M", "هم"), + (0xFC53, "M", "هى"), + (0xFC54, "M", "Ł‡ŁŠ"), + (0xFC55, "M", "يج"), + (0xFC56, "M", "يح"), + (0xFC57, "M", "يخ"), + (0xFC58, "M", "ŁŠŁ…"), + (0xFC59, "M", "ŁŠŁ‰"), + (0xFC5A, "M", "يي"), ] + def _seg_46() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFC57, 'M', 'يخ'), - (0xFC58, 'M', 'ŁŠŁ…'), - (0xFC59, 'M', 'ŁŠŁ‰'), - (0xFC5A, 'M', 'يي'), - (0xFC5B, 'M', 'ذٰ'), - (0xFC5C, 'M', 'رٰ'), - (0xFC5D, 'M', 'ىٰ'), - (0xFC5E, '3', ' ŁŒŁ‘'), - (0xFC5F, '3', ' ŁŁ‘'), - (0xFC60, '3', ' ŁŽŁ‘'), - (0xFC61, '3', ' ŁŁ‘'), - (0xFC62, '3', ' ِّ'), - (0xFC63, '3', ' ّٰ'), - (0xFC64, 'M', 'Ų¦Ų±'), - (0xFC65, 'M', 'Ų¦Ų²'), - (0xFC66, 'M', 'ئم'), - (0xFC67, 'M', 'ئن'), - (0xFC68, 'M', 'ئى'), - (0xFC69, 'M', 'ئي'), - (0xFC6A, 'M', 'ŲØŲ±'), - (0xFC6B, 'M', 'ŲØŲ²'), - (0xFC6C, 'M', 'ŲØŁ…'), - (0xFC6D, 'M', 'بن'), - (0xFC6E, 'M', 'بى'), - (0xFC6F, 'M', 'بي'), - (0xFC70, 'M', 'ŲŖŲ±'), - (0xFC71, 'M', 'ŲŖŲ²'), - (0xFC72, 'M', 'ŲŖŁ…'), - (0xFC73, 'M', 'تن'), - (0xFC74, 'M', 'تى'), - (0xFC75, 'M', 'تي'), - (0xFC76, 'M', 'Ų«Ų±'), - (0xFC77, 'M', 'Ų«Ų²'), - (0xFC78, 'M', 'Ų«Ł…'), - (0xFC79, 'M', 'ثن'), - (0xFC7A, 'M', 'ثى'), - (0xFC7B, 'M', 'ثي'), - (0xFC7C, 'M', 'فى'), - (0xFC7D, 'M', 'في'), - (0xFC7E, 'M', 'قى'), - (0xFC7F, 'M', 'Ł‚ŁŠ'), - (0xFC80, 'M', 'كا'), - (0xFC81, 'M', 'ŁƒŁ„'), - (0xFC82, 'M', 'ŁƒŁ…'), - (0xFC83, 'M', 'ŁƒŁ‰'), - (0xFC84, 'M', 'كي'), - (0xFC85, 'M', 'لم'), - (0xFC86, 'M', 'لى'), - (0xFC87, 'M', 'Ł„ŁŠ'), - (0xFC88, 'M', 'Ł…Ų§'), - (0xFC89, 'M', 'Ł…Ł…'), - (0xFC8A, 'M', 'نر'), - (0xFC8B, 'M', 'نز'), - (0xFC8C, 'M', 'نم'), - (0xFC8D, 'M', 'نن'), - (0xFC8E, 'M', 'نى'), - (0xFC8F, 'M', 'Ł†ŁŠ'), - (0xFC90, 'M', 'ىٰ'), - (0xFC91, 'M', 'ير'), - (0xFC92, 'M', 'يز'), - (0xFC93, 'M', 'ŁŠŁ…'), - (0xFC94, 'M', 'ŁŠŁ†'), - (0xFC95, 'M', 'ŁŠŁ‰'), - (0xFC96, 'M', 'يي'), - (0xFC97, 'M', 'Ų¦Ų¬'), - (0xFC98, 'M', 'Ų¦Ų­'), - (0xFC99, 'M', 'Ų¦Ų®'), - (0xFC9A, 'M', 'ئم'), - (0xFC9B, 'M', 'ئه'), - (0xFC9C, 'M', 'ŲØŲ¬'), - (0xFC9D, 'M', 'ŲØŲ­'), - (0xFC9E, 'M', 'ŲØŲ®'), - (0xFC9F, 'M', 'ŲØŁ…'), - (0xFCA0, 'M', 'به'), - (0xFCA1, 'M', 'ŲŖŲ¬'), - (0xFCA2, 'M', 'ŲŖŲ­'), - (0xFCA3, 'M', 'ŲŖŲ®'), - (0xFCA4, 'M', 'ŲŖŁ…'), - (0xFCA5, 'M', 'ته'), - (0xFCA6, 'M', 'Ų«Ł…'), - (0xFCA7, 'M', 'Ų¬Ų­'), - (0xFCA8, 'M', 'جم'), - (0xFCA9, 'M', 'Ų­Ų¬'), - (0xFCAA, 'M', 'Ų­Ł…'), - (0xFCAB, 'M', 'Ų®Ų¬'), - (0xFCAC, 'M', 'خم'), - (0xFCAD, 'M', 'Ų³Ų¬'), - (0xFCAE, 'M', 'Ų³Ų­'), - (0xFCAF, 'M', 'Ų³Ų®'), - (0xFCB0, 'M', 'سم'), - (0xFCB1, 'M', 'ŲµŲ­'), - (0xFCB2, 'M', 'ŲµŲ®'), - (0xFCB3, 'M', 'صم'), - (0xFCB4, 'M', 'Ų¶Ų¬'), - (0xFCB5, 'M', 'Ų¶Ų­'), - (0xFCB6, 'M', 'Ų¶Ų®'), - (0xFCB7, 'M', 'Ų¶Ł…'), - (0xFCB8, 'M', 'Ų·Ų­'), - (0xFCB9, 'M', 'ŲøŁ…'), - (0xFCBA, 'M', 'Ų¹Ų¬'), + (0xFC5B, "M", "ذٰ"), + (0xFC5C, "M", "رٰ"), + (0xFC5D, "M", "ىٰ"), + (0xFC5E, "3", " ŁŒŁ‘"), + (0xFC5F, "3", " ŁŁ‘"), + (0xFC60, "3", " ŁŽŁ‘"), + (0xFC61, "3", " ŁŁ‘"), + (0xFC62, "3", " ِّ"), + (0xFC63, "3", " ّٰ"), + (0xFC64, "M", "Ų¦Ų±"), + (0xFC65, "M", "Ų¦Ų²"), + (0xFC66, "M", "ئم"), + (0xFC67, "M", "ئن"), + (0xFC68, "M", "ئى"), + (0xFC69, "M", "ئي"), + (0xFC6A, "M", "ŲØŲ±"), + (0xFC6B, "M", "ŲØŲ²"), + (0xFC6C, "M", "ŲØŁ…"), + (0xFC6D, "M", "بن"), + (0xFC6E, "M", "بى"), + (0xFC6F, "M", "بي"), + (0xFC70, "M", "ŲŖŲ±"), + (0xFC71, "M", "ŲŖŲ²"), + (0xFC72, "M", "ŲŖŁ…"), + (0xFC73, "M", "تن"), + (0xFC74, "M", "تى"), + (0xFC75, "M", "تي"), + (0xFC76, "M", "Ų«Ų±"), + (0xFC77, "M", "Ų«Ų²"), + (0xFC78, "M", "Ų«Ł…"), + (0xFC79, "M", "ثن"), + (0xFC7A, "M", "ثى"), + (0xFC7B, "M", "ثي"), + (0xFC7C, "M", "فى"), + (0xFC7D, "M", "في"), + (0xFC7E, "M", "قى"), + (0xFC7F, "M", "Ł‚ŁŠ"), + (0xFC80, "M", "كا"), + (0xFC81, "M", "ŁƒŁ„"), + (0xFC82, "M", "ŁƒŁ…"), + (0xFC83, "M", "ŁƒŁ‰"), + (0xFC84, "M", "كي"), + (0xFC85, "M", "لم"), + (0xFC86, "M", "لى"), + (0xFC87, "M", "Ł„ŁŠ"), + (0xFC88, "M", "Ł…Ų§"), + (0xFC89, "M", "Ł…Ł…"), + (0xFC8A, "M", "نر"), + (0xFC8B, "M", "نز"), + (0xFC8C, "M", "نم"), + (0xFC8D, "M", "نن"), + (0xFC8E, "M", "نى"), + (0xFC8F, "M", "Ł†ŁŠ"), + (0xFC90, "M", "ىٰ"), + (0xFC91, "M", "ير"), + (0xFC92, "M", "يز"), + (0xFC93, "M", "ŁŠŁ…"), + (0xFC94, "M", "ŁŠŁ†"), + (0xFC95, "M", "ŁŠŁ‰"), + (0xFC96, "M", "يي"), + (0xFC97, "M", "Ų¦Ų¬"), + (0xFC98, "M", "Ų¦Ų­"), + (0xFC99, "M", "Ų¦Ų®"), + (0xFC9A, "M", "ئم"), + (0xFC9B, "M", "ئه"), + (0xFC9C, "M", "ŲØŲ¬"), + (0xFC9D, "M", "ŲØŲ­"), + (0xFC9E, "M", "ŲØŲ®"), + (0xFC9F, "M", "ŲØŁ…"), + (0xFCA0, "M", "به"), + (0xFCA1, "M", "ŲŖŲ¬"), + (0xFCA2, "M", "ŲŖŲ­"), + (0xFCA3, "M", "ŲŖŲ®"), + (0xFCA4, "M", "ŲŖŁ…"), + (0xFCA5, "M", "ته"), + (0xFCA6, "M", "Ų«Ł…"), + (0xFCA7, "M", "Ų¬Ų­"), + (0xFCA8, "M", "جم"), + (0xFCA9, "M", "Ų­Ų¬"), + (0xFCAA, "M", "Ų­Ł…"), + (0xFCAB, "M", "Ų®Ų¬"), + (0xFCAC, "M", "خم"), + (0xFCAD, "M", "Ų³Ų¬"), + (0xFCAE, "M", "Ų³Ų­"), + (0xFCAF, "M", "Ų³Ų®"), + (0xFCB0, "M", "سم"), + (0xFCB1, "M", "ŲµŲ­"), + (0xFCB2, "M", "ŲµŲ®"), + (0xFCB3, "M", "صم"), + (0xFCB4, "M", "Ų¶Ų¬"), + (0xFCB5, "M", "Ų¶Ų­"), + (0xFCB6, "M", "Ų¶Ų®"), + (0xFCB7, "M", "Ų¶Ł…"), + (0xFCB8, "M", "Ų·Ų­"), + (0xFCB9, "M", "ŲøŁ…"), + (0xFCBA, "M", "Ų¹Ų¬"), + (0xFCBB, "M", "عم"), + (0xFCBC, "M", "ŲŗŲ¬"), + (0xFCBD, "M", "ŲŗŁ…"), + (0xFCBE, "M", "فج"), ] + def _seg_47() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFCBB, 'M', 'عم'), - (0xFCBC, 'M', 'ŲŗŲ¬'), - (0xFCBD, 'M', 'ŲŗŁ…'), - (0xFCBE, 'M', 'فج'), - (0xFCBF, 'M', 'فح'), - (0xFCC0, 'M', 'فخ'), - (0xFCC1, 'M', 'فم'), - (0xFCC2, 'M', 'قح'), - (0xFCC3, 'M', 'قم'), - (0xFCC4, 'M', 'كج'), - (0xFCC5, 'M', 'كح'), - (0xFCC6, 'M', 'كخ'), - (0xFCC7, 'M', 'ŁƒŁ„'), - (0xFCC8, 'M', 'ŁƒŁ…'), - (0xFCC9, 'M', 'لج'), - (0xFCCA, 'M', 'لح'), - (0xFCCB, 'M', 'لخ'), - (0xFCCC, 'M', 'لم'), - (0xFCCD, 'M', 'له'), - (0xFCCE, 'M', 'Ł…Ų¬'), - (0xFCCF, 'M', 'Ł…Ų­'), - (0xFCD0, 'M', 'Ł…Ų®'), - (0xFCD1, 'M', 'Ł…Ł…'), - (0xFCD2, 'M', 'نج'), - (0xFCD3, 'M', 'نح'), - (0xFCD4, 'M', 'نخ'), - (0xFCD5, 'M', 'نم'), - (0xFCD6, 'M', 'نه'), - (0xFCD7, 'M', 'هج'), - (0xFCD8, 'M', 'هم'), - (0xFCD9, 'M', 'هٰ'), - (0xFCDA, 'M', 'يج'), - (0xFCDB, 'M', 'يح'), - (0xFCDC, 'M', 'يخ'), - (0xFCDD, 'M', 'ŁŠŁ…'), - (0xFCDE, 'M', 'ŁŠŁ‡'), - (0xFCDF, 'M', 'ئم'), - (0xFCE0, 'M', 'ئه'), - (0xFCE1, 'M', 'ŲØŁ…'), - (0xFCE2, 'M', 'به'), - (0xFCE3, 'M', 'ŲŖŁ…'), - (0xFCE4, 'M', 'ته'), - (0xFCE5, 'M', 'Ų«Ł…'), - (0xFCE6, 'M', 'ثه'), - (0xFCE7, 'M', 'سم'), - (0xFCE8, 'M', 'سه'), - (0xFCE9, 'M', 'Ų“Ł…'), - (0xFCEA, 'M', 'ؓه'), - (0xFCEB, 'M', 'ŁƒŁ„'), - (0xFCEC, 'M', 'ŁƒŁ…'), - (0xFCED, 'M', 'لم'), - (0xFCEE, 'M', 'نم'), - (0xFCEF, 'M', 'نه'), - (0xFCF0, 'M', 'ŁŠŁ…'), - (0xFCF1, 'M', 'ŁŠŁ‡'), - (0xFCF2, 'M', 'Ł€ŁŽŁ‘'), - (0xFCF3, 'M', 'Ł€ŁŁ‘'), - (0xFCF4, 'M', 'ـِّ'), - (0xFCF5, 'M', 'طى'), - (0xFCF6, 'M', 'طي'), - (0xFCF7, 'M', 'عى'), - (0xFCF8, 'M', 'عي'), - (0xFCF9, 'M', 'غى'), - (0xFCFA, 'M', 'غي'), - (0xFCFB, 'M', 'سى'), - (0xFCFC, 'M', 'سي'), - (0xFCFD, 'M', 'ؓى'), - (0xFCFE, 'M', 'ؓي'), - (0xFCFF, 'M', 'حى'), - (0xFD00, 'M', 'حي'), - (0xFD01, 'M', 'جى'), - (0xFD02, 'M', 'جي'), - (0xFD03, 'M', 'خى'), - (0xFD04, 'M', 'خي'), - (0xFD05, 'M', 'صى'), - (0xFD06, 'M', 'صي'), - (0xFD07, 'M', 'ضى'), - (0xFD08, 'M', 'ضي'), - (0xFD09, 'M', 'Ų“Ų¬'), - (0xFD0A, 'M', 'Ų“Ų­'), - (0xFD0B, 'M', 'Ų“Ų®'), - (0xFD0C, 'M', 'Ų“Ł…'), - (0xFD0D, 'M', 'Ų“Ų±'), - (0xFD0E, 'M', 'Ų³Ų±'), - (0xFD0F, 'M', 'ŲµŲ±'), - (0xFD10, 'M', 'Ų¶Ų±'), - (0xFD11, 'M', 'طى'), - (0xFD12, 'M', 'طي'), - (0xFD13, 'M', 'عى'), - (0xFD14, 'M', 'عي'), - (0xFD15, 'M', 'غى'), - (0xFD16, 'M', 'غي'), - (0xFD17, 'M', 'سى'), - (0xFD18, 'M', 'سي'), - (0xFD19, 'M', 'ؓى'), - (0xFD1A, 'M', 'ؓي'), - (0xFD1B, 'M', 'حى'), - (0xFD1C, 'M', 'حي'), - (0xFD1D, 'M', 'جى'), - (0xFD1E, 'M', 'جي'), + (0xFCBF, "M", "فح"), + (0xFCC0, "M", "فخ"), + (0xFCC1, "M", "فم"), + (0xFCC2, "M", "قح"), + (0xFCC3, "M", "قم"), + (0xFCC4, "M", "كج"), + (0xFCC5, "M", "كح"), + (0xFCC6, "M", "كخ"), + (0xFCC7, "M", "ŁƒŁ„"), + (0xFCC8, "M", "ŁƒŁ…"), + (0xFCC9, "M", "لج"), + (0xFCCA, "M", "لح"), + (0xFCCB, "M", "لخ"), + (0xFCCC, "M", "لم"), + (0xFCCD, "M", "له"), + (0xFCCE, "M", "Ł…Ų¬"), + (0xFCCF, "M", "Ł…Ų­"), + (0xFCD0, "M", "Ł…Ų®"), + (0xFCD1, "M", "Ł…Ł…"), + (0xFCD2, "M", "نج"), + (0xFCD3, "M", "نح"), + (0xFCD4, "M", "نخ"), + (0xFCD5, "M", "نم"), + (0xFCD6, "M", "نه"), + (0xFCD7, "M", "هج"), + (0xFCD8, "M", "هم"), + (0xFCD9, "M", "هٰ"), + (0xFCDA, "M", "يج"), + (0xFCDB, "M", "يح"), + (0xFCDC, "M", "يخ"), + (0xFCDD, "M", "ŁŠŁ…"), + (0xFCDE, "M", "ŁŠŁ‡"), + (0xFCDF, "M", "ئم"), + (0xFCE0, "M", "ئه"), + (0xFCE1, "M", "ŲØŁ…"), + (0xFCE2, "M", "به"), + (0xFCE3, "M", "ŲŖŁ…"), + (0xFCE4, "M", "ته"), + (0xFCE5, "M", "Ų«Ł…"), + (0xFCE6, "M", "ثه"), + (0xFCE7, "M", "سم"), + (0xFCE8, "M", "سه"), + (0xFCE9, "M", "Ų“Ł…"), + (0xFCEA, "M", "ؓه"), + (0xFCEB, "M", "ŁƒŁ„"), + (0xFCEC, "M", "ŁƒŁ…"), + (0xFCED, "M", "لم"), + (0xFCEE, "M", "نم"), + (0xFCEF, "M", "نه"), + (0xFCF0, "M", "ŁŠŁ…"), + (0xFCF1, "M", "ŁŠŁ‡"), + (0xFCF2, "M", "Ł€ŁŽŁ‘"), + (0xFCF3, "M", "Ł€ŁŁ‘"), + (0xFCF4, "M", "ـِّ"), + (0xFCF5, "M", "طى"), + (0xFCF6, "M", "طي"), + (0xFCF7, "M", "عى"), + (0xFCF8, "M", "عي"), + (0xFCF9, "M", "غى"), + (0xFCFA, "M", "غي"), + (0xFCFB, "M", "سى"), + (0xFCFC, "M", "سي"), + (0xFCFD, "M", "ؓى"), + (0xFCFE, "M", "ؓي"), + (0xFCFF, "M", "حى"), + (0xFD00, "M", "حي"), + (0xFD01, "M", "جى"), + (0xFD02, "M", "جي"), + (0xFD03, "M", "خى"), + (0xFD04, "M", "خي"), + (0xFD05, "M", "صى"), + (0xFD06, "M", "صي"), + (0xFD07, "M", "ضى"), + (0xFD08, "M", "ضي"), + (0xFD09, "M", "Ų“Ų¬"), + (0xFD0A, "M", "Ų“Ų­"), + (0xFD0B, "M", "Ų“Ų®"), + (0xFD0C, "M", "Ų“Ł…"), + (0xFD0D, "M", "Ų“Ų±"), + (0xFD0E, "M", "Ų³Ų±"), + (0xFD0F, "M", "ŲµŲ±"), + (0xFD10, "M", "Ų¶Ų±"), + (0xFD11, "M", "طى"), + (0xFD12, "M", "طي"), + (0xFD13, "M", "عى"), + (0xFD14, "M", "عي"), + (0xFD15, "M", "غى"), + (0xFD16, "M", "غي"), + (0xFD17, "M", "سى"), + (0xFD18, "M", "سي"), + (0xFD19, "M", "ؓى"), + (0xFD1A, "M", "ؓي"), + (0xFD1B, "M", "حى"), + (0xFD1C, "M", "حي"), + (0xFD1D, "M", "جى"), + (0xFD1E, "M", "جي"), + (0xFD1F, "M", "خى"), + (0xFD20, "M", "خي"), + (0xFD21, "M", "صى"), + (0xFD22, "M", "صي"), ] + def _seg_48() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFD1F, 'M', 'خى'), - (0xFD20, 'M', 'خي'), - (0xFD21, 'M', 'صى'), - (0xFD22, 'M', 'صي'), - (0xFD23, 'M', 'ضى'), - (0xFD24, 'M', 'ضي'), - (0xFD25, 'M', 'Ų“Ų¬'), - (0xFD26, 'M', 'Ų“Ų­'), - (0xFD27, 'M', 'Ų“Ų®'), - (0xFD28, 'M', 'Ų“Ł…'), - (0xFD29, 'M', 'Ų“Ų±'), - (0xFD2A, 'M', 'Ų³Ų±'), - (0xFD2B, 'M', 'ŲµŲ±'), - (0xFD2C, 'M', 'Ų¶Ų±'), - (0xFD2D, 'M', 'Ų“Ų¬'), - (0xFD2E, 'M', 'Ų“Ų­'), - (0xFD2F, 'M', 'Ų“Ų®'), - (0xFD30, 'M', 'Ų“Ł…'), - (0xFD31, 'M', 'سه'), - (0xFD32, 'M', 'ؓه'), - (0xFD33, 'M', 'Ų·Ł…'), - (0xFD34, 'M', 'Ų³Ų¬'), - (0xFD35, 'M', 'Ų³Ų­'), - (0xFD36, 'M', 'Ų³Ų®'), - (0xFD37, 'M', 'Ų“Ų¬'), - (0xFD38, 'M', 'Ų“Ų­'), - (0xFD39, 'M', 'Ų“Ų®'), - (0xFD3A, 'M', 'Ų·Ł…'), - (0xFD3B, 'M', 'ŲøŁ…'), - (0xFD3C, 'M', 'Ų§Ł‹'), - (0xFD3E, 'V'), - (0xFD50, 'M', 'تجم'), - (0xFD51, 'M', 'ŲŖŲ­Ų¬'), - (0xFD53, 'M', 'ŲŖŲ­Ł…'), - (0xFD54, 'M', 'تخم'), - (0xFD55, 'M', 'ŲŖŁ…Ų¬'), - (0xFD56, 'M', 'ŲŖŁ…Ų­'), - (0xFD57, 'M', 'ŲŖŁ…Ų®'), - (0xFD58, 'M', 'جمح'), - (0xFD5A, 'M', 'Ų­Ł…ŁŠ'), - (0xFD5B, 'M', 'حمى'), - (0xFD5C, 'M', 'Ų³Ų­Ų¬'), - (0xFD5D, 'M', 'Ų³Ų¬Ų­'), - (0xFD5E, 'M', 'سجى'), - (0xFD5F, 'M', 'سمح'), - (0xFD61, 'M', 'سمج'), - (0xFD62, 'M', 'سمم'), - (0xFD64, 'M', 'ŲµŲ­Ų­'), - (0xFD66, 'M', 'صمم'), - (0xFD67, 'M', 'Ų“Ų­Ł…'), - (0xFD69, 'M', 'ؓجي'), - (0xFD6A, 'M', 'Ų“Ł…Ų®'), - (0xFD6C, 'M', 'Ų“Ł…Ł…'), - (0xFD6E, 'M', 'ضحى'), - (0xFD6F, 'M', 'ضخم'), - (0xFD71, 'M', 'Ų·Ł…Ų­'), - (0xFD73, 'M', 'Ų·Ł…Ł…'), - (0xFD74, 'M', 'Ų·Ł…ŁŠ'), - (0xFD75, 'M', 'عجم'), - (0xFD76, 'M', 'عمم'), - (0xFD78, 'M', 'عمى'), - (0xFD79, 'M', 'ŲŗŁ…Ł…'), - (0xFD7A, 'M', 'ŲŗŁ…ŁŠ'), - (0xFD7B, 'M', 'غمى'), - (0xFD7C, 'M', 'فخم'), - (0xFD7E, 'M', 'قمح'), - (0xFD7F, 'M', 'قمم'), - (0xFD80, 'M', 'لحم'), - (0xFD81, 'M', 'Ł„Ų­ŁŠ'), - (0xFD82, 'M', 'لحى'), - (0xFD83, 'M', 'لجج'), - (0xFD85, 'M', 'لخم'), - (0xFD87, 'M', 'لمح'), - (0xFD89, 'M', 'Ł…Ų­Ų¬'), - (0xFD8A, 'M', 'Ł…Ų­Ł…'), - (0xFD8B, 'M', 'Ł…Ų­ŁŠ'), - (0xFD8C, 'M', 'Ł…Ų¬Ų­'), - (0xFD8D, 'M', 'مجم'), - (0xFD8E, 'M', 'Ł…Ų®Ų¬'), - (0xFD8F, 'M', 'مخم'), - (0xFD90, 'X'), - (0xFD92, 'M', 'Ł…Ų¬Ų®'), - (0xFD93, 'M', 'همج'), - (0xFD94, 'M', 'همم'), - (0xFD95, 'M', 'نحم'), - (0xFD96, 'M', 'نحى'), - (0xFD97, 'M', 'نجم'), - (0xFD99, 'M', 'نجى'), - (0xFD9A, 'M', 'Ł†Ł…ŁŠ'), - (0xFD9B, 'M', 'نمى'), - (0xFD9C, 'M', 'ŁŠŁ…Ł…'), - (0xFD9E, 'M', 'بخي'), - (0xFD9F, 'M', 'تجي'), - (0xFDA0, 'M', 'تجى'), - (0xFDA1, 'M', 'تخي'), - (0xFDA2, 'M', 'تخى'), - (0xFDA3, 'M', 'ŲŖŁ…ŁŠ'), - (0xFDA4, 'M', 'تمى'), - (0xFDA5, 'M', 'Ų¬Ł…ŁŠ'), - (0xFDA6, 'M', 'جحى'), + (0xFD23, "M", "ضى"), + (0xFD24, "M", "ضي"), + (0xFD25, "M", "Ų“Ų¬"), + (0xFD26, "M", "Ų“Ų­"), + (0xFD27, "M", "Ų“Ų®"), + (0xFD28, "M", "Ų“Ł…"), + (0xFD29, "M", "Ų“Ų±"), + (0xFD2A, "M", "Ų³Ų±"), + (0xFD2B, "M", "ŲµŲ±"), + (0xFD2C, "M", "Ų¶Ų±"), + (0xFD2D, "M", "Ų“Ų¬"), + (0xFD2E, "M", "Ų“Ų­"), + (0xFD2F, "M", "Ų“Ų®"), + (0xFD30, "M", "Ų“Ł…"), + (0xFD31, "M", "سه"), + (0xFD32, "M", "ؓه"), + (0xFD33, "M", "Ų·Ł…"), + (0xFD34, "M", "Ų³Ų¬"), + (0xFD35, "M", "Ų³Ų­"), + (0xFD36, "M", "Ų³Ų®"), + (0xFD37, "M", "Ų“Ų¬"), + (0xFD38, "M", "Ų“Ų­"), + (0xFD39, "M", "Ų“Ų®"), + (0xFD3A, "M", "Ų·Ł…"), + (0xFD3B, "M", "ŲøŁ…"), + (0xFD3C, "M", "Ų§Ł‹"), + (0xFD3E, "V"), + (0xFD50, "M", "تجم"), + (0xFD51, "M", "ŲŖŲ­Ų¬"), + (0xFD53, "M", "ŲŖŲ­Ł…"), + (0xFD54, "M", "تخم"), + (0xFD55, "M", "ŲŖŁ…Ų¬"), + (0xFD56, "M", "ŲŖŁ…Ų­"), + (0xFD57, "M", "ŲŖŁ…Ų®"), + (0xFD58, "M", "جمح"), + (0xFD5A, "M", "Ų­Ł…ŁŠ"), + (0xFD5B, "M", "حمى"), + (0xFD5C, "M", "Ų³Ų­Ų¬"), + (0xFD5D, "M", "Ų³Ų¬Ų­"), + (0xFD5E, "M", "سجى"), + (0xFD5F, "M", "سمح"), + (0xFD61, "M", "سمج"), + (0xFD62, "M", "سمم"), + (0xFD64, "M", "ŲµŲ­Ų­"), + (0xFD66, "M", "صمم"), + (0xFD67, "M", "Ų“Ų­Ł…"), + (0xFD69, "M", "ؓجي"), + (0xFD6A, "M", "Ų“Ł…Ų®"), + (0xFD6C, "M", "Ų“Ł…Ł…"), + (0xFD6E, "M", "ضحى"), + (0xFD6F, "M", "ضخم"), + (0xFD71, "M", "Ų·Ł…Ų­"), + (0xFD73, "M", "Ų·Ł…Ł…"), + (0xFD74, "M", "Ų·Ł…ŁŠ"), + (0xFD75, "M", "عجم"), + (0xFD76, "M", "عمم"), + (0xFD78, "M", "عمى"), + (0xFD79, "M", "ŲŗŁ…Ł…"), + (0xFD7A, "M", "ŲŗŁ…ŁŠ"), + (0xFD7B, "M", "غمى"), + (0xFD7C, "M", "فخم"), + (0xFD7E, "M", "قمح"), + (0xFD7F, "M", "قمم"), + (0xFD80, "M", "لحم"), + (0xFD81, "M", "Ł„Ų­ŁŠ"), + (0xFD82, "M", "لحى"), + (0xFD83, "M", "لجج"), + (0xFD85, "M", "لخم"), + (0xFD87, "M", "لمح"), + (0xFD89, "M", "Ł…Ų­Ų¬"), + (0xFD8A, "M", "Ł…Ų­Ł…"), + (0xFD8B, "M", "Ł…Ų­ŁŠ"), + (0xFD8C, "M", "Ł…Ų¬Ų­"), + (0xFD8D, "M", "مجم"), + (0xFD8E, "M", "Ł…Ų®Ų¬"), + (0xFD8F, "M", "مخم"), + (0xFD90, "X"), + (0xFD92, "M", "Ł…Ų¬Ų®"), + (0xFD93, "M", "همج"), + (0xFD94, "M", "همم"), + (0xFD95, "M", "نحم"), + (0xFD96, "M", "نحى"), + (0xFD97, "M", "نجم"), + (0xFD99, "M", "نجى"), + (0xFD9A, "M", "Ł†Ł…ŁŠ"), + (0xFD9B, "M", "نمى"), + (0xFD9C, "M", "ŁŠŁ…Ł…"), + (0xFD9E, "M", "بخي"), + (0xFD9F, "M", "تجي"), + (0xFDA0, "M", "تجى"), + (0xFDA1, "M", "تخي"), + (0xFDA2, "M", "تخى"), + (0xFDA3, "M", "ŲŖŁ…ŁŠ"), + (0xFDA4, "M", "تمى"), + (0xFDA5, "M", "Ų¬Ł…ŁŠ"), + (0xFDA6, "M", "جحى"), + (0xFDA7, "M", "جمى"), + (0xFDA8, "M", "سخى"), + (0xFDA9, "M", "صحي"), + (0xFDAA, "M", "ؓحي"), ] + def _seg_49() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFDA7, 'M', 'جمى'), - (0xFDA8, 'M', 'سخى'), - (0xFDA9, 'M', 'صحي'), - (0xFDAA, 'M', 'ؓحي'), - (0xFDAB, 'M', 'ضحي'), - (0xFDAC, 'M', 'Ł„Ų¬ŁŠ'), - (0xFDAD, 'M', 'Ł„Ł…ŁŠ'), - (0xFDAE, 'M', 'يحي'), - (0xFDAF, 'M', 'يجي'), - (0xFDB0, 'M', 'ŁŠŁ…ŁŠ'), - (0xFDB1, 'M', 'Ł…Ł…ŁŠ'), - (0xFDB2, 'M', 'Ł‚Ł…ŁŠ'), - (0xFDB3, 'M', 'Ł†Ų­ŁŠ'), - (0xFDB4, 'M', 'قمح'), - (0xFDB5, 'M', 'لحم'), - (0xFDB6, 'M', 'Ų¹Ł…ŁŠ'), - (0xFDB7, 'M', 'ŁƒŁ…ŁŠ'), - (0xFDB8, 'M', 'نجح'), - (0xFDB9, 'M', 'Ł…Ų®ŁŠ'), - (0xFDBA, 'M', 'لجم'), - (0xFDBB, 'M', 'ŁƒŁ…Ł…'), - (0xFDBC, 'M', 'لجم'), - (0xFDBD, 'M', 'نجح'), - (0xFDBE, 'M', 'جحي'), - (0xFDBF, 'M', 'حجي'), - (0xFDC0, 'M', 'Ł…Ų¬ŁŠ'), - (0xFDC1, 'M', 'ŁŁ…ŁŠ'), - (0xFDC2, 'M', 'بحي'), - (0xFDC3, 'M', 'ŁƒŁ…Ł…'), - (0xFDC4, 'M', 'عجم'), - (0xFDC5, 'M', 'صمم'), - (0xFDC6, 'M', 'سخي'), - (0xFDC7, 'M', 'Ł†Ų¬ŁŠ'), - (0xFDC8, 'X'), - (0xFDCF, 'V'), - (0xFDD0, 'X'), - (0xFDF0, 'M', 'صلے'), - (0xFDF1, 'M', 'قلے'), - (0xFDF2, 'M', 'الله'), - (0xFDF3, 'M', 'اكبر'), - (0xFDF4, 'M', 'Ł…Ų­Ł…ŲÆ'), - (0xFDF5, 'M', 'صلعم'), - (0xFDF6, 'M', 'Ų±Ų³ŁˆŁ„'), - (0xFDF7, 'M', 'Ų¹Ł„ŁŠŁ‡'), - (0xFDF8, 'M', 'ŁˆŲ³Ł„Ł…'), - (0xFDF9, 'M', 'صلى'), - (0xFDFA, '3', 'صلى الله Ų¹Ł„ŁŠŁ‡ ŁˆŲ³Ł„Ł…'), - (0xFDFB, '3', 'جل جلاله'), - (0xFDFC, 'M', 'Ų±ŪŒŲ§Ł„'), - (0xFDFD, 'V'), - (0xFE00, 'I'), - (0xFE10, '3', ','), - (0xFE11, 'M', '态'), - (0xFE12, 'X'), - (0xFE13, '3', ':'), - (0xFE14, '3', ';'), - (0xFE15, '3', '!'), - (0xFE16, '3', '?'), - (0xFE17, 'M', '怖'), - (0xFE18, 'M', '怗'), - (0xFE19, 'X'), - (0xFE20, 'V'), - (0xFE30, 'X'), - (0xFE31, 'M', '—'), - (0xFE32, 'M', '–'), - (0xFE33, '3', '_'), - (0xFE35, '3', '('), - (0xFE36, '3', ')'), - (0xFE37, '3', '{'), - (0xFE38, '3', '}'), - (0xFE39, 'M', '怔'), - (0xFE3A, 'M', '怕'), - (0xFE3B, 'M', '怐'), - (0xFE3C, 'M', '怑'), - (0xFE3D, 'M', '怊'), - (0xFE3E, 'M', '怋'), - (0xFE3F, 'M', '怈'), - (0xFE40, 'M', '怉'), - (0xFE41, 'M', '怌'), - (0xFE42, 'M', '怍'), - (0xFE43, 'M', '怎'), - (0xFE44, 'M', '怏'), - (0xFE45, 'V'), - (0xFE47, '3', '['), - (0xFE48, '3', ']'), - (0xFE49, '3', ' Ģ…'), - (0xFE4D, '3', '_'), - (0xFE50, '3', ','), - (0xFE51, 'M', '态'), - (0xFE52, 'X'), - (0xFE54, '3', ';'), - (0xFE55, '3', ':'), - (0xFE56, '3', '?'), - (0xFE57, '3', '!'), - (0xFE58, 'M', '—'), - (0xFE59, '3', '('), - (0xFE5A, '3', ')'), - (0xFE5B, '3', '{'), - (0xFE5C, '3', '}'), - (0xFE5D, 'M', '怔'), + (0xFDAB, "M", "ضحي"), + (0xFDAC, "M", "Ł„Ų¬ŁŠ"), + (0xFDAD, "M", "Ł„Ł…ŁŠ"), + (0xFDAE, "M", "يحي"), + (0xFDAF, "M", "يجي"), + (0xFDB0, "M", "ŁŠŁ…ŁŠ"), + (0xFDB1, "M", "Ł…Ł…ŁŠ"), + (0xFDB2, "M", "Ł‚Ł…ŁŠ"), + (0xFDB3, "M", "Ł†Ų­ŁŠ"), + (0xFDB4, "M", "قمح"), + (0xFDB5, "M", "لحم"), + (0xFDB6, "M", "Ų¹Ł…ŁŠ"), + (0xFDB7, "M", "ŁƒŁ…ŁŠ"), + (0xFDB8, "M", "نجح"), + (0xFDB9, "M", "Ł…Ų®ŁŠ"), + (0xFDBA, "M", "لجم"), + (0xFDBB, "M", "ŁƒŁ…Ł…"), + (0xFDBC, "M", "لجم"), + (0xFDBD, "M", "نجح"), + (0xFDBE, "M", "جحي"), + (0xFDBF, "M", "حجي"), + (0xFDC0, "M", "Ł…Ų¬ŁŠ"), + (0xFDC1, "M", "ŁŁ…ŁŠ"), + (0xFDC2, "M", "بحي"), + (0xFDC3, "M", "ŁƒŁ…Ł…"), + (0xFDC4, "M", "عجم"), + (0xFDC5, "M", "صمم"), + (0xFDC6, "M", "سخي"), + (0xFDC7, "M", "Ł†Ų¬ŁŠ"), + (0xFDC8, "X"), + (0xFDCF, "V"), + (0xFDD0, "X"), + (0xFDF0, "M", "صلے"), + (0xFDF1, "M", "قلے"), + (0xFDF2, "M", "الله"), + (0xFDF3, "M", "اكبر"), + (0xFDF4, "M", "Ł…Ų­Ł…ŲÆ"), + (0xFDF5, "M", "صلعم"), + (0xFDF6, "M", "Ų±Ų³ŁˆŁ„"), + (0xFDF7, "M", "Ų¹Ł„ŁŠŁ‡"), + (0xFDF8, "M", "ŁˆŲ³Ł„Ł…"), + (0xFDF9, "M", "صلى"), + (0xFDFA, "3", "صلى الله Ų¹Ł„ŁŠŁ‡ ŁˆŲ³Ł„Ł…"), + (0xFDFB, "3", "جل جلاله"), + (0xFDFC, "M", "Ų±ŪŒŲ§Ł„"), + (0xFDFD, "V"), + (0xFE00, "I"), + (0xFE10, "3", ","), + (0xFE11, "M", "态"), + (0xFE12, "X"), + (0xFE13, "3", ":"), + (0xFE14, "3", ";"), + (0xFE15, "3", "!"), + (0xFE16, "3", "?"), + (0xFE17, "M", "怖"), + (0xFE18, "M", "怗"), + (0xFE19, "X"), + (0xFE20, "V"), + (0xFE30, "X"), + (0xFE31, "M", "—"), + (0xFE32, "M", "–"), + (0xFE33, "3", "_"), + (0xFE35, "3", "("), + (0xFE36, "3", ")"), + (0xFE37, "3", "{"), + (0xFE38, "3", "}"), + (0xFE39, "M", "怔"), + (0xFE3A, "M", "怕"), + (0xFE3B, "M", "怐"), + (0xFE3C, "M", "怑"), + (0xFE3D, "M", "怊"), + (0xFE3E, "M", "怋"), + (0xFE3F, "M", "怈"), + (0xFE40, "M", "怉"), + (0xFE41, "M", "怌"), + (0xFE42, "M", "怍"), + (0xFE43, "M", "怎"), + (0xFE44, "M", "怏"), + (0xFE45, "V"), + (0xFE47, "3", "["), + (0xFE48, "3", "]"), + (0xFE49, "3", " Ģ…"), + (0xFE4D, "3", "_"), + (0xFE50, "3", ","), + (0xFE51, "M", "态"), + (0xFE52, "X"), + (0xFE54, "3", ";"), + (0xFE55, "3", ":"), + (0xFE56, "3", "?"), + (0xFE57, "3", "!"), + (0xFE58, "M", "—"), + (0xFE59, "3", "("), + (0xFE5A, "3", ")"), + (0xFE5B, "3", "{"), + (0xFE5C, "3", "}"), + (0xFE5D, "M", "怔"), + (0xFE5E, "M", "怕"), + (0xFE5F, "3", "#"), + (0xFE60, "3", "&"), + (0xFE61, "3", "*"), ] + def _seg_50() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFE5E, 'M', '怕'), - (0xFE5F, '3', '#'), - (0xFE60, '3', '&'), - (0xFE61, '3', '*'), - (0xFE62, '3', '+'), - (0xFE63, 'M', '-'), - (0xFE64, '3', '<'), - (0xFE65, '3', '>'), - (0xFE66, '3', '='), - (0xFE67, 'X'), - (0xFE68, '3', '\\'), - (0xFE69, '3', '$'), - (0xFE6A, '3', '%'), - (0xFE6B, '3', '@'), - (0xFE6C, 'X'), - (0xFE70, '3', ' Ł‹'), - (0xFE71, 'M', 'ـً'), - (0xFE72, '3', ' ٌ'), - (0xFE73, 'V'), - (0xFE74, '3', ' Ł'), - (0xFE75, 'X'), - (0xFE76, '3', ' ŁŽ'), - (0xFE77, 'M', 'Ł€ŁŽ'), - (0xFE78, '3', ' Ł'), - (0xFE79, 'M', 'Ł€Ł'), - (0xFE7A, '3', ' ِ'), - (0xFE7B, 'M', 'ـِ'), - (0xFE7C, '3', ' Ł‘'), - (0xFE7D, 'M', 'ـّ'), - (0xFE7E, '3', ' Ł’'), - (0xFE7F, 'M', 'ـْ'), - (0xFE80, 'M', 'Ų”'), - (0xFE81, 'M', 'Ų¢'), - (0xFE83, 'M', 'Ų£'), - (0xFE85, 'M', 'Ų¤'), - (0xFE87, 'M', 'Ų„'), - (0xFE89, 'M', 'Ų¦'), - (0xFE8D, 'M', 'Ų§'), - (0xFE8F, 'M', 'ŲØ'), - (0xFE93, 'M', 'Ų©'), - (0xFE95, 'M', 'ŲŖ'), - (0xFE99, 'M', 'Ų«'), - (0xFE9D, 'M', 'Ų¬'), - (0xFEA1, 'M', 'Ų­'), - (0xFEA5, 'M', 'Ų®'), - (0xFEA9, 'M', 'ŲÆ'), - (0xFEAB, 'M', 'Ų°'), - (0xFEAD, 'M', 'Ų±'), - (0xFEAF, 'M', 'Ų²'), - (0xFEB1, 'M', 'Ų³'), - (0xFEB5, 'M', 'Ų“'), - (0xFEB9, 'M', 'Ųµ'), - (0xFEBD, 'M', 'Ų¶'), - (0xFEC1, 'M', 'Ų·'), - (0xFEC5, 'M', 'Ųø'), - (0xFEC9, 'M', 'Ų¹'), - (0xFECD, 'M', 'Ųŗ'), - (0xFED1, 'M', 'ف'), - (0xFED5, 'M', 'Ł‚'), - (0xFED9, 'M', 'ك'), - (0xFEDD, 'M', 'Ł„'), - (0xFEE1, 'M', 'Ł…'), - (0xFEE5, 'M', 'ن'), - (0xFEE9, 'M', 'ه'), - (0xFEED, 'M', 'و'), - (0xFEEF, 'M', 'ى'), - (0xFEF1, 'M', 'ي'), - (0xFEF5, 'M', 'لآ'), - (0xFEF7, 'M', 'لأ'), - (0xFEF9, 'M', 'ل؄'), - (0xFEFB, 'M', 'لا'), - (0xFEFD, 'X'), - (0xFEFF, 'I'), - (0xFF00, 'X'), - (0xFF01, '3', '!'), - (0xFF02, '3', '"'), - (0xFF03, '3', '#'), - (0xFF04, '3', '$'), - (0xFF05, '3', '%'), - (0xFF06, '3', '&'), - (0xFF07, '3', '\''), - (0xFF08, '3', '('), - (0xFF09, '3', ')'), - (0xFF0A, '3', '*'), - (0xFF0B, '3', '+'), - (0xFF0C, '3', ','), - (0xFF0D, 'M', '-'), - (0xFF0E, 'M', '.'), - (0xFF0F, '3', '/'), - (0xFF10, 'M', '0'), - (0xFF11, 'M', '1'), - (0xFF12, 'M', '2'), - (0xFF13, 'M', '3'), - (0xFF14, 'M', '4'), - (0xFF15, 'M', '5'), - (0xFF16, 'M', '6'), - (0xFF17, 'M', '7'), - (0xFF18, 'M', '8'), - (0xFF19, 'M', '9'), - (0xFF1A, '3', ':'), + (0xFE62, "3", "+"), + (0xFE63, "M", "-"), + (0xFE64, "3", "<"), + (0xFE65, "3", ">"), + (0xFE66, "3", "="), + (0xFE67, "X"), + (0xFE68, "3", "\\"), + (0xFE69, "3", "$"), + (0xFE6A, "3", "%"), + (0xFE6B, "3", "@"), + (0xFE6C, "X"), + (0xFE70, "3", " Ł‹"), + (0xFE71, "M", "ـً"), + (0xFE72, "3", " ٌ"), + (0xFE73, "V"), + (0xFE74, "3", " Ł"), + (0xFE75, "X"), + (0xFE76, "3", " ŁŽ"), + (0xFE77, "M", "Ł€ŁŽ"), + (0xFE78, "3", " Ł"), + (0xFE79, "M", "Ł€Ł"), + (0xFE7A, "3", " ِ"), + (0xFE7B, "M", "ـِ"), + (0xFE7C, "3", " Ł‘"), + (0xFE7D, "M", "ـّ"), + (0xFE7E, "3", " Ł’"), + (0xFE7F, "M", "ـْ"), + (0xFE80, "M", "Ų”"), + (0xFE81, "M", "Ų¢"), + (0xFE83, "M", "Ų£"), + (0xFE85, "M", "Ų¤"), + (0xFE87, "M", "Ų„"), + (0xFE89, "M", "Ų¦"), + (0xFE8D, "M", "Ų§"), + (0xFE8F, "M", "ŲØ"), + (0xFE93, "M", "Ų©"), + (0xFE95, "M", "ŲŖ"), + (0xFE99, "M", "Ų«"), + (0xFE9D, "M", "Ų¬"), + (0xFEA1, "M", "Ų­"), + (0xFEA5, "M", "Ų®"), + (0xFEA9, "M", "ŲÆ"), + (0xFEAB, "M", "Ų°"), + (0xFEAD, "M", "Ų±"), + (0xFEAF, "M", "Ų²"), + (0xFEB1, "M", "Ų³"), + (0xFEB5, "M", "Ų“"), + (0xFEB9, "M", "Ųµ"), + (0xFEBD, "M", "Ų¶"), + (0xFEC1, "M", "Ų·"), + (0xFEC5, "M", "Ųø"), + (0xFEC9, "M", "Ų¹"), + (0xFECD, "M", "Ųŗ"), + (0xFED1, "M", "ف"), + (0xFED5, "M", "Ł‚"), + (0xFED9, "M", "ك"), + (0xFEDD, "M", "Ł„"), + (0xFEE1, "M", "Ł…"), + (0xFEE5, "M", "ن"), + (0xFEE9, "M", "ه"), + (0xFEED, "M", "و"), + (0xFEEF, "M", "ى"), + (0xFEF1, "M", "ي"), + (0xFEF5, "M", "لآ"), + (0xFEF7, "M", "لأ"), + (0xFEF9, "M", "ل؄"), + (0xFEFB, "M", "لا"), + (0xFEFD, "X"), + (0xFEFF, "I"), + (0xFF00, "X"), + (0xFF01, "3", "!"), + (0xFF02, "3", '"'), + (0xFF03, "3", "#"), + (0xFF04, "3", "$"), + (0xFF05, "3", "%"), + (0xFF06, "3", "&"), + (0xFF07, "3", "'"), + (0xFF08, "3", "("), + (0xFF09, "3", ")"), + (0xFF0A, "3", "*"), + (0xFF0B, "3", "+"), + (0xFF0C, "3", ","), + (0xFF0D, "M", "-"), + (0xFF0E, "M", "."), + (0xFF0F, "3", "/"), + (0xFF10, "M", "0"), + (0xFF11, "M", "1"), + (0xFF12, "M", "2"), + (0xFF13, "M", "3"), + (0xFF14, "M", "4"), + (0xFF15, "M", "5"), + (0xFF16, "M", "6"), + (0xFF17, "M", "7"), + (0xFF18, "M", "8"), + (0xFF19, "M", "9"), + (0xFF1A, "3", ":"), + (0xFF1B, "3", ";"), + (0xFF1C, "3", "<"), + (0xFF1D, "3", "="), + (0xFF1E, "3", ">"), ] + def _seg_51() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFF1B, '3', ';'), - (0xFF1C, '3', '<'), - (0xFF1D, '3', '='), - (0xFF1E, '3', '>'), - (0xFF1F, '3', '?'), - (0xFF20, '3', '@'), - (0xFF21, 'M', 'a'), - (0xFF22, 'M', 'b'), - (0xFF23, 'M', 'c'), - (0xFF24, 'M', 'd'), - (0xFF25, 'M', 'e'), - (0xFF26, 'M', 'f'), - (0xFF27, 'M', 'g'), - (0xFF28, 'M', 'h'), - (0xFF29, 'M', 'i'), - (0xFF2A, 'M', 'j'), - (0xFF2B, 'M', 'k'), - (0xFF2C, 'M', 'l'), - (0xFF2D, 'M', 'm'), - (0xFF2E, 'M', 'n'), - (0xFF2F, 'M', 'o'), - (0xFF30, 'M', 'p'), - (0xFF31, 'M', 'q'), - (0xFF32, 'M', 'r'), - (0xFF33, 'M', 's'), - (0xFF34, 'M', 't'), - (0xFF35, 'M', 'u'), - (0xFF36, 'M', 'v'), - (0xFF37, 'M', 'w'), - (0xFF38, 'M', 'x'), - (0xFF39, 'M', 'y'), - (0xFF3A, 'M', 'z'), - (0xFF3B, '3', '['), - (0xFF3C, '3', '\\'), - (0xFF3D, '3', ']'), - (0xFF3E, '3', '^'), - (0xFF3F, '3', '_'), - (0xFF40, '3', '`'), - (0xFF41, 'M', 'a'), - (0xFF42, 'M', 'b'), - (0xFF43, 'M', 'c'), - (0xFF44, 'M', 'd'), - (0xFF45, 'M', 'e'), - (0xFF46, 'M', 'f'), - (0xFF47, 'M', 'g'), - (0xFF48, 'M', 'h'), - (0xFF49, 'M', 'i'), - (0xFF4A, 'M', 'j'), - (0xFF4B, 'M', 'k'), - (0xFF4C, 'M', 'l'), - (0xFF4D, 'M', 'm'), - (0xFF4E, 'M', 'n'), - (0xFF4F, 'M', 'o'), - (0xFF50, 'M', 'p'), - (0xFF51, 'M', 'q'), - (0xFF52, 'M', 'r'), - (0xFF53, 'M', 's'), - (0xFF54, 'M', 't'), - (0xFF55, 'M', 'u'), - (0xFF56, 'M', 'v'), - (0xFF57, 'M', 'w'), - (0xFF58, 'M', 'x'), - (0xFF59, 'M', 'y'), - (0xFF5A, 'M', 'z'), - (0xFF5B, '3', '{'), - (0xFF5C, '3', '|'), - (0xFF5D, '3', '}'), - (0xFF5E, '3', '~'), - (0xFF5F, 'M', '⦅'), - (0xFF60, 'M', '⦆'), - (0xFF61, 'M', '.'), - (0xFF62, 'M', '怌'), - (0xFF63, 'M', '怍'), - (0xFF64, 'M', '态'), - (0xFF65, 'M', '惻'), - (0xFF66, 'M', 'ヲ'), - (0xFF67, 'M', 'ć‚”'), - (0xFF68, 'M', 'ć‚£'), - (0xFF69, 'M', 'ć‚„'), - (0xFF6A, 'M', '悧'), - (0xFF6B, 'M', 'ć‚©'), - (0xFF6C, 'M', 'ャ'), - (0xFF6D, 'M', '惄'), - (0xFF6E, 'M', '惧'), - (0xFF6F, 'M', '惃'), - (0xFF70, 'M', 'ー'), - (0xFF71, 'M', 'ć‚¢'), - (0xFF72, 'M', '悤'), - (0xFF73, 'M', '悦'), - (0xFF74, 'M', 'エ'), - (0xFF75, 'M', 'オ'), - (0xFF76, 'M', 'ć‚«'), - (0xFF77, 'M', '悭'), - (0xFF78, 'M', 'ク'), - (0xFF79, 'M', '悱'), - (0xFF7A, 'M', 'コ'), - (0xFF7B, 'M', '悵'), - (0xFF7C, 'M', 'ć‚·'), - (0xFF7D, 'M', 'ス'), - (0xFF7E, 'M', 'ć‚»'), + (0xFF1F, "3", "?"), + (0xFF20, "3", "@"), + (0xFF21, "M", "a"), + (0xFF22, "M", "b"), + (0xFF23, "M", "c"), + (0xFF24, "M", "d"), + (0xFF25, "M", "e"), + (0xFF26, "M", "f"), + (0xFF27, "M", "g"), + (0xFF28, "M", "h"), + (0xFF29, "M", "i"), + (0xFF2A, "M", "j"), + (0xFF2B, "M", "k"), + (0xFF2C, "M", "l"), + (0xFF2D, "M", "m"), + (0xFF2E, "M", "n"), + (0xFF2F, "M", "o"), + (0xFF30, "M", "p"), + (0xFF31, "M", "q"), + (0xFF32, "M", "r"), + (0xFF33, "M", "s"), + (0xFF34, "M", "t"), + (0xFF35, "M", "u"), + (0xFF36, "M", "v"), + (0xFF37, "M", "w"), + (0xFF38, "M", "x"), + (0xFF39, "M", "y"), + (0xFF3A, "M", "z"), + (0xFF3B, "3", "["), + (0xFF3C, "3", "\\"), + (0xFF3D, "3", "]"), + (0xFF3E, "3", "^"), + (0xFF3F, "3", "_"), + (0xFF40, "3", "`"), + (0xFF41, "M", "a"), + (0xFF42, "M", "b"), + (0xFF43, "M", "c"), + (0xFF44, "M", "d"), + (0xFF45, "M", "e"), + (0xFF46, "M", "f"), + (0xFF47, "M", "g"), + (0xFF48, "M", "h"), + (0xFF49, "M", "i"), + (0xFF4A, "M", "j"), + (0xFF4B, "M", "k"), + (0xFF4C, "M", "l"), + (0xFF4D, "M", "m"), + (0xFF4E, "M", "n"), + (0xFF4F, "M", "o"), + (0xFF50, "M", "p"), + (0xFF51, "M", "q"), + (0xFF52, "M", "r"), + (0xFF53, "M", "s"), + (0xFF54, "M", "t"), + (0xFF55, "M", "u"), + (0xFF56, "M", "v"), + (0xFF57, "M", "w"), + (0xFF58, "M", "x"), + (0xFF59, "M", "y"), + (0xFF5A, "M", "z"), + (0xFF5B, "3", "{"), + (0xFF5C, "3", "|"), + (0xFF5D, "3", "}"), + (0xFF5E, "3", "~"), + (0xFF5F, "M", "⦅"), + (0xFF60, "M", "⦆"), + (0xFF61, "M", "."), + (0xFF62, "M", "怌"), + (0xFF63, "M", "怍"), + (0xFF64, "M", "态"), + (0xFF65, "M", "惻"), + (0xFF66, "M", "ヲ"), + (0xFF67, "M", "ć‚”"), + (0xFF68, "M", "ć‚£"), + (0xFF69, "M", "ć‚„"), + (0xFF6A, "M", "悧"), + (0xFF6B, "M", "ć‚©"), + (0xFF6C, "M", "ャ"), + (0xFF6D, "M", "惄"), + (0xFF6E, "M", "惧"), + (0xFF6F, "M", "惃"), + (0xFF70, "M", "ー"), + (0xFF71, "M", "ć‚¢"), + (0xFF72, "M", "悤"), + (0xFF73, "M", "悦"), + (0xFF74, "M", "エ"), + (0xFF75, "M", "オ"), + (0xFF76, "M", "ć‚«"), + (0xFF77, "M", "悭"), + (0xFF78, "M", "ク"), + (0xFF79, "M", "悱"), + (0xFF7A, "M", "コ"), + (0xFF7B, "M", "悵"), + (0xFF7C, "M", "ć‚·"), + (0xFF7D, "M", "ス"), + (0xFF7E, "M", "ć‚»"), + (0xFF7F, "M", "ソ"), + (0xFF80, "M", "タ"), + (0xFF81, "M", "惁"), + (0xFF82, "M", "惄"), ] + def _seg_52() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFF7F, 'M', 'ソ'), - (0xFF80, 'M', 'タ'), - (0xFF81, 'M', '惁'), - (0xFF82, 'M', '惄'), - (0xFF83, 'M', '惆'), - (0xFF84, 'M', '惈'), - (0xFF85, 'M', 'ナ'), - (0xFF86, 'M', '惋'), - (0xFF87, 'M', 'ヌ'), - (0xFF88, 'M', '惍'), - (0xFF89, 'M', '惎'), - (0xFF8A, 'M', '惏'), - (0xFF8B, 'M', '惒'), - (0xFF8C, 'M', '惕'), - (0xFF8D, 'M', '惘'), - (0xFF8E, 'M', '惛'), - (0xFF8F, 'M', '惞'), - (0xFF90, 'M', 'ミ'), - (0xFF91, 'M', '惠'), - (0xFF92, 'M', '惔'), - (0xFF93, 'M', 'モ'), - (0xFF94, 'M', '惤'), - (0xFF95, 'M', '惦'), - (0xFF96, 'M', 'ヨ'), - (0xFF97, 'M', '惩'), - (0xFF98, 'M', 'リ'), - (0xFF99, 'M', '惫'), - (0xFF9A, 'M', '惬'), - (0xFF9B, 'M', '惭'), - (0xFF9C, 'M', 'ワ'), - (0xFF9D, 'M', 'ン'), - (0xFF9E, 'M', '悙'), - (0xFF9F, 'M', '悚'), - (0xFFA0, 'X'), - (0xFFA1, 'M', 'į„€'), - (0xFFA2, 'M', 'ᄁ'), - (0xFFA3, 'M', 'ᆪ'), - (0xFFA4, 'M', 'į„‚'), - (0xFFA5, 'M', 'ᆬ'), - (0xFFA6, 'M', 'ᆭ'), - (0xFFA7, 'M', 'į„ƒ'), - (0xFFA8, 'M', 'į„„'), - (0xFFA9, 'M', 'į„…'), - (0xFFAA, 'M', 'ᆰ'), - (0xFFAB, 'M', 'ᆱ'), - (0xFFAC, 'M', 'ᆲ'), - (0xFFAD, 'M', 'ᆳ'), - (0xFFAE, 'M', 'ᆓ'), - (0xFFAF, 'M', 'ᆵ'), - (0xFFB0, 'M', 'į„š'), - (0xFFB1, 'M', 'ᄆ'), - (0xFFB2, 'M', 'ᄇ'), - (0xFFB3, 'M', 'į„ˆ'), - (0xFFB4, 'M', 'į„”'), - (0xFFB5, 'M', 'ᄉ'), - (0xFFB6, 'M', 'į„Š'), - (0xFFB7, 'M', 'į„‹'), - (0xFFB8, 'M', 'į„Œ'), - (0xFFB9, 'M', 'į„'), - (0xFFBA, 'M', 'į„Ž'), - (0xFFBB, 'M', 'į„'), - (0xFFBC, 'M', 'ᄐ'), - (0xFFBD, 'M', 'į„‘'), - (0xFFBE, 'M', 'į„’'), - (0xFFBF, 'X'), - (0xFFC2, 'M', 'į…”'), - (0xFFC3, 'M', 'į…¢'), - (0xFFC4, 'M', 'į…£'), - (0xFFC5, 'M', 'į…¤'), - (0xFFC6, 'M', 'į…„'), - (0xFFC7, 'M', 'į…¦'), - (0xFFC8, 'X'), - (0xFFCA, 'M', 'į…§'), - (0xFFCB, 'M', 'į…Ø'), - (0xFFCC, 'M', 'į…©'), - (0xFFCD, 'M', 'į…Ŗ'), - (0xFFCE, 'M', 'į…«'), - (0xFFCF, 'M', 'į…¬'), - (0xFFD0, 'X'), - (0xFFD2, 'M', 'į…­'), - (0xFFD3, 'M', 'į…®'), - (0xFFD4, 'M', 'į…Æ'), - (0xFFD5, 'M', 'į…°'), - (0xFFD6, 'M', 'į…±'), - (0xFFD7, 'M', 'į…²'), - (0xFFD8, 'X'), - (0xFFDA, 'M', 'į…³'), - (0xFFDB, 'M', 'į…“'), - (0xFFDC, 'M', 'į…µ'), - (0xFFDD, 'X'), - (0xFFE0, 'M', 'Ā¢'), - (0xFFE1, 'M', 'Ā£'), - (0xFFE2, 'M', '¬'), - (0xFFE3, '3', ' Ģ„'), - (0xFFE4, 'M', '¦'), - (0xFFE5, 'M', 'Ā„'), - (0xFFE6, 'M', 'ā‚©'), - (0xFFE7, 'X'), - (0xFFE8, 'M', '│'), - (0xFFE9, 'M', '←'), + (0xFF83, "M", "惆"), + (0xFF84, "M", "惈"), + (0xFF85, "M", "ナ"), + (0xFF86, "M", "惋"), + (0xFF87, "M", "ヌ"), + (0xFF88, "M", "惍"), + (0xFF89, "M", "惎"), + (0xFF8A, "M", "惏"), + (0xFF8B, "M", "惒"), + (0xFF8C, "M", "惕"), + (0xFF8D, "M", "惘"), + (0xFF8E, "M", "惛"), + (0xFF8F, "M", "惞"), + (0xFF90, "M", "ミ"), + (0xFF91, "M", "惠"), + (0xFF92, "M", "惔"), + (0xFF93, "M", "モ"), + (0xFF94, "M", "惤"), + (0xFF95, "M", "惦"), + (0xFF96, "M", "ヨ"), + (0xFF97, "M", "惩"), + (0xFF98, "M", "リ"), + (0xFF99, "M", "惫"), + (0xFF9A, "M", "惬"), + (0xFF9B, "M", "惭"), + (0xFF9C, "M", "ワ"), + (0xFF9D, "M", "ン"), + (0xFF9E, "M", "悙"), + (0xFF9F, "M", "悚"), + (0xFFA0, "X"), + (0xFFA1, "M", "į„€"), + (0xFFA2, "M", "ᄁ"), + (0xFFA3, "M", "ᆪ"), + (0xFFA4, "M", "į„‚"), + (0xFFA5, "M", "ᆬ"), + (0xFFA6, "M", "ᆭ"), + (0xFFA7, "M", "į„ƒ"), + (0xFFA8, "M", "į„„"), + (0xFFA9, "M", "į„…"), + (0xFFAA, "M", "ᆰ"), + (0xFFAB, "M", "ᆱ"), + (0xFFAC, "M", "ᆲ"), + (0xFFAD, "M", "ᆳ"), + (0xFFAE, "M", "ᆓ"), + (0xFFAF, "M", "ᆵ"), + (0xFFB0, "M", "į„š"), + (0xFFB1, "M", "ᄆ"), + (0xFFB2, "M", "ᄇ"), + (0xFFB3, "M", "į„ˆ"), + (0xFFB4, "M", "į„”"), + (0xFFB5, "M", "ᄉ"), + (0xFFB6, "M", "į„Š"), + (0xFFB7, "M", "į„‹"), + (0xFFB8, "M", "į„Œ"), + (0xFFB9, "M", "į„"), + (0xFFBA, "M", "į„Ž"), + (0xFFBB, "M", "į„"), + (0xFFBC, "M", "ᄐ"), + (0xFFBD, "M", "į„‘"), + (0xFFBE, "M", "į„’"), + (0xFFBF, "X"), + (0xFFC2, "M", "į…”"), + (0xFFC3, "M", "į…¢"), + (0xFFC4, "M", "į…£"), + (0xFFC5, "M", "į…¤"), + (0xFFC6, "M", "į…„"), + (0xFFC7, "M", "į…¦"), + (0xFFC8, "X"), + (0xFFCA, "M", "į…§"), + (0xFFCB, "M", "į…Ø"), + (0xFFCC, "M", "į…©"), + (0xFFCD, "M", "į…Ŗ"), + (0xFFCE, "M", "į…«"), + (0xFFCF, "M", "į…¬"), + (0xFFD0, "X"), + (0xFFD2, "M", "į…­"), + (0xFFD3, "M", "į…®"), + (0xFFD4, "M", "į…Æ"), + (0xFFD5, "M", "į…°"), + (0xFFD6, "M", "į…±"), + (0xFFD7, "M", "į…²"), + (0xFFD8, "X"), + (0xFFDA, "M", "į…³"), + (0xFFDB, "M", "į…“"), + (0xFFDC, "M", "į…µ"), + (0xFFDD, "X"), + (0xFFE0, "M", "Ā¢"), + (0xFFE1, "M", "Ā£"), + (0xFFE2, "M", "¬"), + (0xFFE3, "3", " Ģ„"), + (0xFFE4, "M", "¦"), + (0xFFE5, "M", "Ā„"), + (0xFFE6, "M", "ā‚©"), + (0xFFE7, "X"), + (0xFFE8, "M", "│"), + (0xFFE9, "M", "←"), + (0xFFEA, "M", "↑"), + (0xFFEB, "M", "→"), + (0xFFEC, "M", "↓"), + (0xFFED, "M", "ā– "), ] + def _seg_53() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0xFFEA, 'M', '↑'), - (0xFFEB, 'M', '→'), - (0xFFEC, 'M', '↓'), - (0xFFED, 'M', 'ā– '), - (0xFFEE, 'M', 'ā—‹'), - (0xFFEF, 'X'), - (0x10000, 'V'), - (0x1000C, 'X'), - (0x1000D, 'V'), - (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', '𐐨'), - (0x10401, 'M', '𐐩'), - (0x10402, 'M', '𐐪'), - (0x10403, 'M', '𐐫'), - (0x10404, 'M', '𐐬'), - (0x10405, 'M', '𐐭'), - (0x10406, 'M', '𐐮'), - (0x10407, 'M', '𐐯'), - (0x10408, 'M', '𐐰'), - (0x10409, 'M', '𐐱'), - (0x1040A, 'M', '𐐲'), - (0x1040B, 'M', '𐐳'), - (0x1040C, 'M', '𐐓'), - (0x1040D, 'M', '𐐵'), - (0x1040E, 'M', '𐐶'), - (0x1040F, 'M', '𐐷'), - (0x10410, 'M', '𐐸'), - (0x10411, 'M', '𐐹'), - (0x10412, 'M', '𐐺'), - (0x10413, 'M', '𐐻'), - (0x10414, 'M', '𐐼'), - (0x10415, 'M', '𐐽'), - (0x10416, 'M', '𐐾'), - (0x10417, 'M', '𐐿'), - (0x10418, 'M', '𐑀'), - (0x10419, 'M', '𐑁'), - (0x1041A, 'M', '𐑂'), - (0x1041B, 'M', 'š‘ƒ'), - (0x1041C, 'M', '𐑄'), - (0x1041D, 'M', '𐑅'), - (0x1041E, 'M', '𐑆'), - (0x1041F, 'M', '𐑇'), - (0x10420, 'M', 'š‘ˆ'), - (0x10421, 'M', '𐑉'), - (0x10422, 'M', 'š‘Š'), - (0x10423, 'M', '𐑋'), - (0x10424, 'M', 'š‘Œ'), - (0x10425, 'M', 'š‘'), - (0x10426, 'M', 'š‘Ž'), - (0x10427, 'M', 'š‘'), - (0x10428, 'V'), - (0x1049E, 'X'), - (0x104A0, 'V'), - (0x104AA, 'X'), - (0x104B0, 'M', 'š“˜'), - (0x104B1, 'M', '𐓙'), - (0x104B2, 'M', 'š“š'), - (0x104B3, 'M', '𐓛'), - (0x104B4, 'M', 'š“œ'), - (0x104B5, 'M', 'š“'), + (0xFFEE, "M", "ā—‹"), + (0xFFEF, "X"), + (0x10000, "V"), + (0x1000C, "X"), + (0x1000D, "V"), + (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", "𐐨"), + (0x10401, "M", "𐐩"), + (0x10402, "M", "𐐪"), + (0x10403, "M", "𐐫"), + (0x10404, "M", "𐐬"), + (0x10405, "M", "𐐭"), + (0x10406, "M", "𐐮"), + (0x10407, "M", "𐐯"), + (0x10408, "M", "𐐰"), + (0x10409, "M", "𐐱"), + (0x1040A, "M", "𐐲"), + (0x1040B, "M", "𐐳"), + (0x1040C, "M", "𐐓"), + (0x1040D, "M", "𐐵"), + (0x1040E, "M", "𐐶"), + (0x1040F, "M", "𐐷"), + (0x10410, "M", "𐐸"), + (0x10411, "M", "𐐹"), + (0x10412, "M", "𐐺"), + (0x10413, "M", "𐐻"), + (0x10414, "M", "𐐼"), + (0x10415, "M", "𐐽"), + (0x10416, "M", "𐐾"), + (0x10417, "M", "𐐿"), + (0x10418, "M", "𐑀"), + (0x10419, "M", "𐑁"), + (0x1041A, "M", "𐑂"), + (0x1041B, "M", "š‘ƒ"), + (0x1041C, "M", "𐑄"), + (0x1041D, "M", "𐑅"), + (0x1041E, "M", "𐑆"), + (0x1041F, "M", "𐑇"), + (0x10420, "M", "š‘ˆ"), + (0x10421, "M", "𐑉"), + (0x10422, "M", "š‘Š"), + (0x10423, "M", "𐑋"), + (0x10424, "M", "š‘Œ"), + (0x10425, "M", "š‘"), + (0x10426, "M", "š‘Ž"), + (0x10427, "M", "š‘"), + (0x10428, "V"), + (0x1049E, "X"), + (0x104A0, "V"), + (0x104AA, "X"), + (0x104B0, "M", "š“˜"), + (0x104B1, "M", "𐓙"), + (0x104B2, "M", "š“š"), + (0x104B3, "M", "𐓛"), + (0x104B4, "M", "š“œ"), + (0x104B5, "M", "š“"), + (0x104B6, "M", "š“ž"), + (0x104B7, "M", "š“Ÿ"), + (0x104B8, "M", "𐓠"), + (0x104B9, "M", "𐓔"), ] + def _seg_54() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x104B6, 'M', 'š“ž'), - (0x104B7, 'M', 'š“Ÿ'), - (0x104B8, 'M', '𐓠'), - (0x104B9, 'M', '𐓔'), - (0x104BA, 'M', '𐓢'), - (0x104BB, 'M', '𐓣'), - (0x104BC, 'M', '𐓤'), - (0x104BD, 'M', '𐓄'), - (0x104BE, 'M', '𐓦'), - (0x104BF, 'M', '𐓧'), - (0x104C0, 'M', '𐓨'), - (0x104C1, 'M', '𐓩'), - (0x104C2, 'M', '𐓪'), - (0x104C3, 'M', '𐓫'), - (0x104C4, 'M', '𐓬'), - (0x104C5, 'M', '𐓭'), - (0x104C6, 'M', '𐓮'), - (0x104C7, 'M', '𐓯'), - (0x104C8, 'M', '𐓰'), - (0x104C9, 'M', '𐓱'), - (0x104CA, 'M', '𐓲'), - (0x104CB, 'M', '𐓳'), - (0x104CC, 'M', '𐓓'), - (0x104CD, 'M', '𐓵'), - (0x104CE, 'M', '𐓶'), - (0x104CF, 'M', '𐓷'), - (0x104D0, 'M', '𐓸'), - (0x104D1, 'M', '𐓹'), - (0x104D2, 'M', '𐓺'), - (0x104D3, 'M', '𐓻'), - (0x104D4, 'X'), - (0x104D8, 'V'), - (0x104FC, 'X'), - (0x10500, 'V'), - (0x10528, 'X'), - (0x10530, 'V'), - (0x10564, 'X'), - (0x1056F, 'V'), - (0x10570, 'M', '𐖗'), - (0x10571, 'M', 'š–˜'), - (0x10572, 'M', '𐖙'), - (0x10573, 'M', 'š–š'), - (0x10574, 'M', '𐖛'), - (0x10575, 'M', 'š–œ'), - (0x10576, 'M', 'š–'), - (0x10577, 'M', 'š–ž'), - (0x10578, 'M', 'š–Ÿ'), - (0x10579, 'M', '𐖠'), - (0x1057A, 'M', '𐖔'), - (0x1057B, 'X'), - (0x1057C, 'M', '𐖣'), - (0x1057D, 'M', '𐖤'), - (0x1057E, 'M', '𐖄'), - (0x1057F, 'M', '𐖦'), - (0x10580, 'M', '𐖧'), - (0x10581, 'M', '𐖨'), - (0x10582, 'M', '𐖩'), - (0x10583, 'M', '𐖪'), - (0x10584, 'M', '𐖫'), - (0x10585, 'M', '𐖬'), - (0x10586, 'M', '𐖭'), - (0x10587, 'M', '𐖮'), - (0x10588, 'M', '𐖯'), - (0x10589, 'M', '𐖰'), - (0x1058A, 'M', '𐖱'), - (0x1058B, 'X'), - (0x1058C, 'M', '𐖳'), - (0x1058D, 'M', '𐖓'), - (0x1058E, 'M', '𐖵'), - (0x1058F, 'M', '𐖶'), - (0x10590, 'M', '𐖷'), - (0x10591, 'M', '𐖸'), - (0x10592, 'M', '𐖹'), - (0x10593, 'X'), - (0x10594, 'M', '𐖻'), - (0x10595, 'M', '𐖼'), - (0x10596, 'X'), - (0x10597, 'V'), - (0x105A2, 'X'), - (0x105A3, 'V'), - (0x105B2, 'X'), - (0x105B3, 'V'), - (0x105BA, 'X'), - (0x105BB, 'V'), - (0x105BD, 'X'), - (0x10600, 'V'), - (0x10737, 'X'), - (0x10740, 'V'), - (0x10756, 'X'), - (0x10760, 'V'), - (0x10768, 'X'), - (0x10780, 'V'), - (0x10781, 'M', 'ː'), - (0x10782, 'M', 'Ė‘'), - (0x10783, 'M', 'Ʀ'), - (0x10784, 'M', 'Ź™'), - (0x10785, 'M', 'ɓ'), - (0x10786, 'X'), - (0x10787, 'M', 'Ź£'), - (0x10788, 'M', 'ź­¦'), + (0x104BA, "M", "𐓢"), + (0x104BB, "M", "𐓣"), + (0x104BC, "M", "𐓤"), + (0x104BD, "M", "𐓄"), + (0x104BE, "M", "𐓦"), + (0x104BF, "M", "𐓧"), + (0x104C0, "M", "𐓨"), + (0x104C1, "M", "𐓩"), + (0x104C2, "M", "𐓪"), + (0x104C3, "M", "𐓫"), + (0x104C4, "M", "𐓬"), + (0x104C5, "M", "𐓭"), + (0x104C6, "M", "𐓮"), + (0x104C7, "M", "𐓯"), + (0x104C8, "M", "𐓰"), + (0x104C9, "M", "𐓱"), + (0x104CA, "M", "𐓲"), + (0x104CB, "M", "𐓳"), + (0x104CC, "M", "𐓓"), + (0x104CD, "M", "𐓵"), + (0x104CE, "M", "𐓶"), + (0x104CF, "M", "𐓷"), + (0x104D0, "M", "𐓸"), + (0x104D1, "M", "𐓹"), + (0x104D2, "M", "𐓺"), + (0x104D3, "M", "𐓻"), + (0x104D4, "X"), + (0x104D8, "V"), + (0x104FC, "X"), + (0x10500, "V"), + (0x10528, "X"), + (0x10530, "V"), + (0x10564, "X"), + (0x1056F, "V"), + (0x10570, "M", "𐖗"), + (0x10571, "M", "š–˜"), + (0x10572, "M", "𐖙"), + (0x10573, "M", "š–š"), + (0x10574, "M", "𐖛"), + (0x10575, "M", "š–œ"), + (0x10576, "M", "š–"), + (0x10577, "M", "š–ž"), + (0x10578, "M", "š–Ÿ"), + (0x10579, "M", "𐖠"), + (0x1057A, "M", "𐖔"), + (0x1057B, "X"), + (0x1057C, "M", "𐖣"), + (0x1057D, "M", "𐖤"), + (0x1057E, "M", "𐖄"), + (0x1057F, "M", "𐖦"), + (0x10580, "M", "𐖧"), + (0x10581, "M", "𐖨"), + (0x10582, "M", "𐖩"), + (0x10583, "M", "𐖪"), + (0x10584, "M", "𐖫"), + (0x10585, "M", "𐖬"), + (0x10586, "M", "𐖭"), + (0x10587, "M", "𐖮"), + (0x10588, "M", "𐖯"), + (0x10589, "M", "𐖰"), + (0x1058A, "M", "𐖱"), + (0x1058B, "X"), + (0x1058C, "M", "𐖳"), + (0x1058D, "M", "𐖓"), + (0x1058E, "M", "𐖵"), + (0x1058F, "M", "𐖶"), + (0x10590, "M", "𐖷"), + (0x10591, "M", "𐖸"), + (0x10592, "M", "𐖹"), + (0x10593, "X"), + (0x10594, "M", "𐖻"), + (0x10595, "M", "𐖼"), + (0x10596, "X"), + (0x10597, "V"), + (0x105A2, "X"), + (0x105A3, "V"), + (0x105B2, "X"), + (0x105B3, "V"), + (0x105BA, "X"), + (0x105BB, "V"), + (0x105BD, "X"), + (0x10600, "V"), + (0x10737, "X"), + (0x10740, "V"), + (0x10756, "X"), + (0x10760, "V"), + (0x10768, "X"), + (0x10780, "V"), + (0x10781, "M", "ː"), + (0x10782, "M", "Ė‘"), + (0x10783, "M", "Ʀ"), + (0x10784, "M", "Ź™"), + (0x10785, "M", "ɓ"), + (0x10786, "X"), + (0x10787, "M", "Ź£"), + (0x10788, "M", "ź­¦"), + (0x10789, "M", "Ź„"), + (0x1078A, "M", "ʤ"), + (0x1078B, "M", "ɖ"), + (0x1078C, "M", "ɗ"), ] + def _seg_55() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x10789, 'M', 'Ź„'), - (0x1078A, 'M', 'ʤ'), - (0x1078B, 'M', 'ɖ'), - (0x1078C, 'M', 'ɗ'), - (0x1078D, 'M', 'į¶‘'), - (0x1078E, 'M', 'ɘ'), - (0x1078F, 'M', 'ɞ'), - (0x10790, 'M', 'Ź©'), - (0x10791, 'M', 'ɤ'), - (0x10792, 'M', 'É¢'), - (0x10793, 'M', 'É '), - (0x10794, 'M', 'Ź›'), - (0x10795, 'M', 'ħ'), - (0x10796, 'M', 'ʜ'), - (0x10797, 'M', 'ɧ'), - (0x10798, 'M', 'Ź„'), - (0x10799, 'M', 'ŹŖ'), - (0x1079A, 'M', 'Ź«'), - (0x1079B, 'M', 'ɬ'), - (0x1079C, 'M', 'š¼„'), - (0x1079D, 'M', 'źžŽ'), - (0x1079E, 'M', 'É®'), - (0x1079F, 'M', 'š¼…'), - (0x107A0, 'M', 'ŹŽ'), - (0x107A1, 'M', 'š¼†'), - (0x107A2, 'M', 'Ćø'), - (0x107A3, 'M', 'ɶ'), - (0x107A4, 'M', 'É·'), - (0x107A5, 'M', 'q'), - (0x107A6, 'M', 'Éŗ'), - (0x107A7, 'M', 'š¼ˆ'), - (0x107A8, 'M', 'ɽ'), - (0x107A9, 'M', 'ɾ'), - (0x107AA, 'M', 'Ź€'), - (0x107AB, 'M', 'ŹØ'), - (0x107AC, 'M', 'ʦ'), - (0x107AD, 'M', 'ź­§'), - (0x107AE, 'M', 'ʧ'), - (0x107AF, 'M', 'ʈ'), - (0x107B0, 'M', 'ā±±'), - (0x107B1, 'X'), - (0x107B2, 'M', 'Ź'), - (0x107B3, 'M', 'Ź”'), - (0x107B4, 'M', 'Ź¢'), - (0x107B5, 'M', 'ʘ'), - (0x107B6, 'M', 'Ē€'), - (0x107B7, 'M', 'ǁ'), - (0x107B8, 'M', 'Ē‚'), - (0x107B9, 'M', 'š¼Š'), - (0x107BA, 'M', 'š¼ž'), - (0x107BB, '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'), + (0x1078D, "M", "į¶‘"), + (0x1078E, "M", "ɘ"), + (0x1078F, "M", "ɞ"), + (0x10790, "M", "Ź©"), + (0x10791, "M", "ɤ"), + (0x10792, "M", "É¢"), + (0x10793, "M", "É "), + (0x10794, "M", "Ź›"), + (0x10795, "M", "ħ"), + (0x10796, "M", "ʜ"), + (0x10797, "M", "ɧ"), + (0x10798, "M", "Ź„"), + (0x10799, "M", "ŹŖ"), + (0x1079A, "M", "Ź«"), + (0x1079B, "M", "ɬ"), + (0x1079C, "M", "š¼„"), + (0x1079D, "M", "źžŽ"), + (0x1079E, "M", "É®"), + (0x1079F, "M", "š¼…"), + (0x107A0, "M", "ŹŽ"), + (0x107A1, "M", "š¼†"), + (0x107A2, "M", "Ćø"), + (0x107A3, "M", "ɶ"), + (0x107A4, "M", "É·"), + (0x107A5, "M", "q"), + (0x107A6, "M", "Éŗ"), + (0x107A7, "M", "š¼ˆ"), + (0x107A8, "M", "ɽ"), + (0x107A9, "M", "ɾ"), + (0x107AA, "M", "Ź€"), + (0x107AB, "M", "ŹØ"), + (0x107AC, "M", "ʦ"), + (0x107AD, "M", "ź­§"), + (0x107AE, "M", "ʧ"), + (0x107AF, "M", "ʈ"), + (0x107B0, "M", "ā±±"), + (0x107B1, "X"), + (0x107B2, "M", "Ź"), + (0x107B3, "M", "Ź”"), + (0x107B4, "M", "Ź¢"), + (0x107B5, "M", "ʘ"), + (0x107B6, "M", "Ē€"), + (0x107B7, "M", "ǁ"), + (0x107B8, "M", "Ē‚"), + (0x107B9, "M", "š¼Š"), + (0x107BA, "M", "š¼ž"), + (0x107BB, "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"), ] + def _seg_56() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (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'), - (0x10C00, 'V'), - (0x10C49, 'X'), - (0x10C80, 'M', '𐳀'), - (0x10C81, 'M', '𐳁'), - (0x10C82, 'M', '𐳂'), - (0x10C83, 'M', '𐳃'), - (0x10C84, 'M', '𐳄'), - (0x10C85, 'M', '𐳅'), - (0x10C86, 'M', '𐳆'), - (0x10C87, 'M', '𐳇'), - (0x10C88, 'M', '𐳈'), - (0x10C89, 'M', '𐳉'), - (0x10C8A, 'M', '𐳊'), - (0x10C8B, 'M', '𐳋'), - (0x10C8C, 'M', '𐳌'), - (0x10C8D, 'M', 'š³'), - (0x10C8E, 'M', 'š³Ž'), - (0x10C8F, 'M', 'š³'), - (0x10C90, 'M', '𐳐'), - (0x10C91, 'M', '𐳑'), - (0x10C92, 'M', '𐳒'), - (0x10C93, 'M', '𐳓'), - (0x10C94, 'M', '𐳔'), - (0x10C95, 'M', '𐳕'), - (0x10C96, 'M', '𐳖'), - (0x10C97, 'M', '𐳗'), - (0x10C98, 'M', '𐳘'), - (0x10C99, 'M', '𐳙'), - (0x10C9A, 'M', '𐳚'), - (0x10C9B, 'M', '𐳛'), - (0x10C9C, 'M', '𐳜'), - (0x10C9D, 'M', 'š³'), - (0x10C9E, 'M', 'š³ž'), - (0x10C9F, 'M', '𐳟'), - (0x10CA0, 'M', '𐳠'), - (0x10CA1, 'M', '𐳔'), - (0x10CA2, 'M', '𐳢'), - (0x10CA3, 'M', '𐳣'), - (0x10CA4, 'M', '𐳤'), - (0x10CA5, 'M', '𐳄'), - (0x10CA6, 'M', '𐳦'), - (0x10CA7, 'M', '𐳧'), - (0x10CA8, 'M', '𐳨'), - (0x10CA9, 'M', '𐳩'), - (0x10CAA, 'M', '𐳪'), - (0x10CAB, 'M', '𐳫'), - (0x10CAC, 'M', '𐳬'), - (0x10CAD, 'M', '𐳭'), - (0x10CAE, 'M', '𐳮'), - (0x10CAF, 'M', '𐳯'), - (0x10CB0, 'M', '𐳰'), - (0x10CB1, 'M', '𐳱'), - (0x10CB2, 'M', '𐳲'), - (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'), - (0x10EFD, 'V'), - (0x10F28, 'X'), - (0x10F30, 'V'), - (0x10F5A, 'X'), - (0x10F70, 'V'), - (0x10F8A, 'X'), - (0x10FB0, 'V'), - (0x10FCC, 'X'), - (0x10FE0, 'V'), - (0x10FF7, 'X'), - (0x11000, 'V'), - (0x1104E, 'X'), - (0x11052, 'V'), - (0x11076, 'X'), - (0x1107F, 'V'), - (0x110BD, 'X'), - (0x110BE, 'V'), + (0x10B36, "X"), + (0x10B39, "V"), + (0x10B56, "X"), + (0x10B58, "V"), + (0x10B73, "X"), + (0x10B78, "V"), + (0x10B92, "X"), + (0x10B99, "V"), + (0x10B9D, "X"), + (0x10BA9, "V"), + (0x10BB0, "X"), + (0x10C00, "V"), + (0x10C49, "X"), + (0x10C80, "M", "𐳀"), + (0x10C81, "M", "𐳁"), + (0x10C82, "M", "𐳂"), + (0x10C83, "M", "𐳃"), + (0x10C84, "M", "𐳄"), + (0x10C85, "M", "𐳅"), + (0x10C86, "M", "𐳆"), + (0x10C87, "M", "𐳇"), + (0x10C88, "M", "𐳈"), + (0x10C89, "M", "𐳉"), + (0x10C8A, "M", "𐳊"), + (0x10C8B, "M", "𐳋"), + (0x10C8C, "M", "𐳌"), + (0x10C8D, "M", "š³"), + (0x10C8E, "M", "š³Ž"), + (0x10C8F, "M", "š³"), + (0x10C90, "M", "𐳐"), + (0x10C91, "M", "𐳑"), + (0x10C92, "M", "𐳒"), + (0x10C93, "M", "𐳓"), + (0x10C94, "M", "𐳔"), + (0x10C95, "M", "𐳕"), + (0x10C96, "M", "𐳖"), + (0x10C97, "M", "𐳗"), + (0x10C98, "M", "𐳘"), + (0x10C99, "M", "𐳙"), + (0x10C9A, "M", "𐳚"), + (0x10C9B, "M", "𐳛"), + (0x10C9C, "M", "𐳜"), + (0x10C9D, "M", "š³"), + (0x10C9E, "M", "š³ž"), + (0x10C9F, "M", "𐳟"), + (0x10CA0, "M", "𐳠"), + (0x10CA1, "M", "𐳔"), + (0x10CA2, "M", "𐳢"), + (0x10CA3, "M", "𐳣"), + (0x10CA4, "M", "𐳤"), + (0x10CA5, "M", "𐳄"), + (0x10CA6, "M", "𐳦"), + (0x10CA7, "M", "𐳧"), + (0x10CA8, "M", "𐳨"), + (0x10CA9, "M", "𐳩"), + (0x10CAA, "M", "𐳪"), + (0x10CAB, "M", "𐳫"), + (0x10CAC, "M", "𐳬"), + (0x10CAD, "M", "𐳭"), + (0x10CAE, "M", "𐳮"), + (0x10CAF, "M", "𐳯"), + (0x10CB0, "M", "𐳰"), + (0x10CB1, "M", "𐳱"), + (0x10CB2, "M", "𐳲"), + (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"), + (0x10EFD, "V"), + (0x10F28, "X"), + (0x10F30, "V"), + (0x10F5A, "X"), + (0x10F70, "V"), + (0x10F8A, "X"), + (0x10FB0, "V"), + (0x10FCC, "X"), + (0x10FE0, "V"), + (0x10FF7, "X"), + (0x11000, "V"), + (0x1104E, "X"), + (0x11052, "V"), + (0x11076, "X"), + (0x1107F, "V"), + (0x110BD, "X"), + (0x110BE, "V"), + (0x110C3, "X"), + (0x110D0, "V"), + (0x110E9, "X"), + (0x110F0, "V"), ] + def _seg_57() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x110C3, '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'), - (0x11213, 'V'), - (0x11242, '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'), - (0x116BA, 'X'), - (0x116C0, 'V'), - (0x116CA, 'X'), - (0x11700, 'V'), - (0x1171B, 'X'), - (0x1171D, 'V'), - (0x1172C, 'X'), - (0x11730, 'V'), - (0x11747, 'X'), - (0x11800, 'V'), - (0x1183C, 'X'), - (0x118A0, 'M', 'š‘£€'), - (0x118A1, 'M', '𑣁'), - (0x118A2, 'M', '𑣂'), - (0x118A3, 'M', 'š‘£ƒ'), - (0x118A4, 'M', '𑣄'), - (0x118A5, 'M', 'š‘£…'), - (0x118A6, 'M', '𑣆'), + (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"), + (0x11213, "V"), + (0x11242, "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"), + (0x116BA, "X"), + (0x116C0, "V"), + (0x116CA, "X"), + (0x11700, "V"), + (0x1171B, "X"), + (0x1171D, "V"), + (0x1172C, "X"), + (0x11730, "V"), + (0x11747, "X"), + (0x11800, "V"), + (0x1183C, "X"), + (0x118A0, "M", "š‘£€"), + (0x118A1, "M", "𑣁"), + (0x118A2, "M", "𑣂"), + (0x118A3, "M", "š‘£ƒ"), + (0x118A4, "M", "𑣄"), + (0x118A5, "M", "š‘£…"), + (0x118A6, "M", "𑣆"), + (0x118A7, "M", "𑣇"), + (0x118A8, "M", "š‘£ˆ"), + (0x118A9, "M", "𑣉"), + (0x118AA, "M", "š‘£Š"), ] + def _seg_58() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x118A7, 'M', '𑣇'), - (0x118A8, 'M', 'š‘£ˆ'), - (0x118A9, 'M', '𑣉'), - (0x118AA, 'M', 'š‘£Š'), - (0x118AB, 'M', '𑣋'), - (0x118AC, 'M', 'š‘£Œ'), - (0x118AD, 'M', 'š‘£'), - (0x118AE, 'M', 'š‘£Ž'), - (0x118AF, 'M', 'š‘£'), - (0x118B0, 'M', '𑣐'), - (0x118B1, 'M', '𑣑'), - (0x118B2, 'M', 'š‘£’'), - (0x118B3, 'M', '𑣓'), - (0x118B4, 'M', 'š‘£”'), - (0x118B5, 'M', '𑣕'), - (0x118B6, 'M', 'š‘£–'), - (0x118B7, 'M', 'š‘£—'), - (0x118B8, 'M', 'š‘£˜'), - (0x118B9, 'M', 'š‘£™'), - (0x118BA, 'M', 'š‘£š'), - (0x118BB, 'M', 'š‘£›'), - (0x118BC, 'M', 'š‘£œ'), - (0x118BD, 'M', 'š‘£'), - (0x118BE, 'M', 'š‘£ž'), - (0x118BF, 'M', 'š‘£Ÿ'), - (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'), - (0x11AB0, 'V'), - (0x11AF9, 'X'), - (0x11B00, 'V'), - (0x11B0A, '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'), - (0x11F00, 'V'), + (0x118AB, "M", "𑣋"), + (0x118AC, "M", "š‘£Œ"), + (0x118AD, "M", "š‘£"), + (0x118AE, "M", "š‘£Ž"), + (0x118AF, "M", "š‘£"), + (0x118B0, "M", "𑣐"), + (0x118B1, "M", "𑣑"), + (0x118B2, "M", "š‘£’"), + (0x118B3, "M", "𑣓"), + (0x118B4, "M", "š‘£”"), + (0x118B5, "M", "𑣕"), + (0x118B6, "M", "š‘£–"), + (0x118B7, "M", "š‘£—"), + (0x118B8, "M", "š‘£˜"), + (0x118B9, "M", "š‘£™"), + (0x118BA, "M", "š‘£š"), + (0x118BB, "M", "š‘£›"), + (0x118BC, "M", "š‘£œ"), + (0x118BD, "M", "š‘£"), + (0x118BE, "M", "š‘£ž"), + (0x118BF, "M", "š‘£Ÿ"), + (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"), + (0x11AB0, "V"), + (0x11AF9, "X"), + (0x11B00, "V"), + (0x11B0A, "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"), + (0x11F00, "V"), + (0x11F11, "X"), + (0x11F12, "V"), + (0x11F3B, "X"), + (0x11F3E, "V"), ] + def _seg_59() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x11F11, 'X'), - (0x11F12, 'V'), - (0x11F3B, 'X'), - (0x11F3E, 'V'), - (0x11F5A, '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'), - (0x12F90, 'V'), - (0x12FF3, 'X'), - (0x13000, 'V'), - (0x13430, 'X'), - (0x13440, 'V'), - (0x13456, 'X'), - (0x14400, 'V'), - (0x14647, 'X'), - (0x16800, 'V'), - (0x16A39, 'X'), - (0x16A40, 'V'), - (0x16A5F, 'X'), - (0x16A60, 'V'), - (0x16A6A, 'X'), - (0x16A6E, 'V'), - (0x16ABF, 'X'), - (0x16AC0, 'V'), - (0x16ACA, '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', 'š–¹ '), - (0x16E41, 'M', 'š–¹”'), - (0x16E42, 'M', 'š–¹¢'), - (0x16E43, 'M', 'š–¹£'), - (0x16E44, 'M', '𖹤'), - (0x16E45, 'M', '𖹄'), - (0x16E46, 'M', '𖹦'), - (0x16E47, 'M', 'š–¹§'), - (0x16E48, 'M', '𖹨'), - (0x16E49, 'M', '𖹩'), - (0x16E4A, 'M', 'š–¹Ŗ'), - (0x16E4B, 'M', '𖹫'), - (0x16E4C, 'M', '𖹬'), - (0x16E4D, 'M', 'š–¹­'), - (0x16E4E, 'M', 'š–¹®'), - (0x16E4F, 'M', '𖹯'), - (0x16E50, 'M', 'š–¹°'), - (0x16E51, 'M', 'š–¹±'), - (0x16E52, 'M', 'š–¹²'), - (0x16E53, 'M', 'š–¹³'), - (0x16E54, 'M', '𖹓'), - (0x16E55, 'M', 'š–¹µ'), - (0x16E56, 'M', 'š–¹¶'), - (0x16E57, 'M', 'š–¹·'), - (0x16E58, 'M', 'š–¹ø'), - (0x16E59, 'M', 'š–¹¹'), - (0x16E5A, 'M', 'š–¹ŗ'), - (0x16E5B, 'M', 'š–¹»'), - (0x16E5C, 'M', 'š–¹¼'), - (0x16E5D, 'M', 'š–¹½'), - (0x16E5E, 'M', 'š–¹¾'), - (0x16E5F, 'M', '𖹿'), - (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'), - (0x1AFF0, 'V'), + (0x11F5A, "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"), + (0x12F90, "V"), + (0x12FF3, "X"), + (0x13000, "V"), + (0x13430, "X"), + (0x13440, "V"), + (0x13456, "X"), + (0x14400, "V"), + (0x14647, "X"), + (0x16800, "V"), + (0x16A39, "X"), + (0x16A40, "V"), + (0x16A5F, "X"), + (0x16A60, "V"), + (0x16A6A, "X"), + (0x16A6E, "V"), + (0x16ABF, "X"), + (0x16AC0, "V"), + (0x16ACA, "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", "š–¹ "), + (0x16E41, "M", "š–¹”"), + (0x16E42, "M", "š–¹¢"), + (0x16E43, "M", "š–¹£"), + (0x16E44, "M", "𖹤"), + (0x16E45, "M", "𖹄"), + (0x16E46, "M", "𖹦"), + (0x16E47, "M", "š–¹§"), + (0x16E48, "M", "𖹨"), + (0x16E49, "M", "𖹩"), + (0x16E4A, "M", "š–¹Ŗ"), + (0x16E4B, "M", "𖹫"), + (0x16E4C, "M", "𖹬"), + (0x16E4D, "M", "š–¹­"), + (0x16E4E, "M", "š–¹®"), + (0x16E4F, "M", "𖹯"), + (0x16E50, "M", "š–¹°"), + (0x16E51, "M", "š–¹±"), + (0x16E52, "M", "š–¹²"), + (0x16E53, "M", "š–¹³"), + (0x16E54, "M", "𖹓"), + (0x16E55, "M", "š–¹µ"), + (0x16E56, "M", "š–¹¶"), + (0x16E57, "M", "š–¹·"), + (0x16E58, "M", "š–¹ø"), + (0x16E59, "M", "š–¹¹"), + (0x16E5A, "M", "š–¹ŗ"), + (0x16E5B, "M", "š–¹»"), + (0x16E5C, "M", "š–¹¼"), + (0x16E5D, "M", "š–¹½"), + (0x16E5E, "M", "š–¹¾"), + (0x16E5F, "M", "𖹿"), + (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"), + (0x1AFF0, "V"), + (0x1AFF4, "X"), + (0x1AFF5, "V"), + (0x1AFFC, "X"), + (0x1AFFD, "V"), ] + def _seg_60() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1AFF4, 'X'), - (0x1AFF5, 'V'), - (0x1AFFC, 'X'), - (0x1AFFD, 'V'), - (0x1AFFF, 'X'), - (0x1B000, 'V'), - (0x1B123, 'X'), - (0x1B132, 'V'), - (0x1B133, 'X'), - (0x1B150, 'V'), - (0x1B153, 'X'), - (0x1B155, 'V'), - (0x1B156, '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'), - (0x1CF00, 'V'), - (0x1CF2E, 'X'), - (0x1CF30, 'V'), - (0x1CF47, 'X'), - (0x1CF50, 'V'), - (0x1CFC4, 'X'), - (0x1D000, 'V'), - (0x1D0F6, 'X'), - (0x1D100, 'V'), - (0x1D127, 'X'), - (0x1D129, 'V'), - (0x1D15E, 'M', 'š…—š…„'), - (0x1D15F, 'M', 'š…˜š…„'), - (0x1D160, 'M', 'š…˜š…„š…®'), - (0x1D161, 'M', 'š…˜š…„š…Æ'), - (0x1D162, 'M', 'š…˜š…„š…°'), - (0x1D163, 'M', 'š…˜š…„š…±'), - (0x1D164, 'M', 'š…˜š…„š…²'), - (0x1D165, 'V'), - (0x1D173, 'X'), - (0x1D17B, 'V'), - (0x1D1BB, 'M', 'š†¹š…„'), - (0x1D1BC, 'M', 'š†ŗš…„'), - (0x1D1BD, 'M', 'š†¹š…„š…®'), - (0x1D1BE, 'M', 'š†ŗš…„š…®'), - (0x1D1BF, 'M', 'š†¹š…„š…Æ'), - (0x1D1C0, 'M', 'š†ŗš…„š…Æ'), - (0x1D1C1, 'V'), - (0x1D1EB, 'X'), - (0x1D200, 'V'), - (0x1D246, 'X'), - (0x1D2C0, 'V'), - (0x1D2D4, 'X'), - (0x1D2E0, 'V'), - (0x1D2F4, 'X'), - (0x1D300, 'V'), - (0x1D357, 'X'), - (0x1D360, 'V'), - (0x1D379, 'X'), - (0x1D400, 'M', 'a'), - (0x1D401, 'M', 'b'), - (0x1D402, 'M', 'c'), - (0x1D403, 'M', 'd'), - (0x1D404, 'M', 'e'), - (0x1D405, 'M', 'f'), - (0x1D406, 'M', 'g'), - (0x1D407, 'M', 'h'), - (0x1D408, 'M', 'i'), - (0x1D409, 'M', 'j'), - (0x1D40A, 'M', 'k'), - (0x1D40B, 'M', 'l'), - (0x1D40C, 'M', 'm'), - (0x1D40D, 'M', 'n'), - (0x1D40E, 'M', 'o'), - (0x1D40F, 'M', 'p'), - (0x1D410, 'M', 'q'), - (0x1D411, 'M', 'r'), - (0x1D412, 'M', 's'), - (0x1D413, 'M', 't'), - (0x1D414, 'M', 'u'), - (0x1D415, 'M', 'v'), - (0x1D416, 'M', 'w'), - (0x1D417, 'M', 'x'), - (0x1D418, 'M', 'y'), - (0x1D419, 'M', 'z'), - (0x1D41A, 'M', 'a'), - (0x1D41B, 'M', 'b'), - (0x1D41C, 'M', 'c'), - (0x1D41D, 'M', 'd'), - (0x1D41E, 'M', 'e'), - (0x1D41F, 'M', 'f'), - (0x1D420, 'M', 'g'), + (0x1AFFF, "X"), + (0x1B000, "V"), + (0x1B123, "X"), + (0x1B132, "V"), + (0x1B133, "X"), + (0x1B150, "V"), + (0x1B153, "X"), + (0x1B155, "V"), + (0x1B156, "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"), + (0x1CF00, "V"), + (0x1CF2E, "X"), + (0x1CF30, "V"), + (0x1CF47, "X"), + (0x1CF50, "V"), + (0x1CFC4, "X"), + (0x1D000, "V"), + (0x1D0F6, "X"), + (0x1D100, "V"), + (0x1D127, "X"), + (0x1D129, "V"), + (0x1D15E, "M", "š…—š…„"), + (0x1D15F, "M", "š…˜š…„"), + (0x1D160, "M", "š…˜š…„š…®"), + (0x1D161, "M", "š…˜š…„š…Æ"), + (0x1D162, "M", "š…˜š…„š…°"), + (0x1D163, "M", "š…˜š…„š…±"), + (0x1D164, "M", "š…˜š…„š…²"), + (0x1D165, "V"), + (0x1D173, "X"), + (0x1D17B, "V"), + (0x1D1BB, "M", "š†¹š…„"), + (0x1D1BC, "M", "š†ŗš…„"), + (0x1D1BD, "M", "š†¹š…„š…®"), + (0x1D1BE, "M", "š†ŗš…„š…®"), + (0x1D1BF, "M", "š†¹š…„š…Æ"), + (0x1D1C0, "M", "š†ŗš…„š…Æ"), + (0x1D1C1, "V"), + (0x1D1EB, "X"), + (0x1D200, "V"), + (0x1D246, "X"), + (0x1D2C0, "V"), + (0x1D2D4, "X"), + (0x1D2E0, "V"), + (0x1D2F4, "X"), + (0x1D300, "V"), + (0x1D357, "X"), + (0x1D360, "V"), + (0x1D379, "X"), + (0x1D400, "M", "a"), + (0x1D401, "M", "b"), + (0x1D402, "M", "c"), + (0x1D403, "M", "d"), + (0x1D404, "M", "e"), + (0x1D405, "M", "f"), + (0x1D406, "M", "g"), + (0x1D407, "M", "h"), + (0x1D408, "M", "i"), + (0x1D409, "M", "j"), + (0x1D40A, "M", "k"), + (0x1D40B, "M", "l"), + (0x1D40C, "M", "m"), + (0x1D40D, "M", "n"), + (0x1D40E, "M", "o"), + (0x1D40F, "M", "p"), + (0x1D410, "M", "q"), + (0x1D411, "M", "r"), + (0x1D412, "M", "s"), + (0x1D413, "M", "t"), + (0x1D414, "M", "u"), + (0x1D415, "M", "v"), + (0x1D416, "M", "w"), + (0x1D417, "M", "x"), + (0x1D418, "M", "y"), + (0x1D419, "M", "z"), + (0x1D41A, "M", "a"), + (0x1D41B, "M", "b"), + (0x1D41C, "M", "c"), + (0x1D41D, "M", "d"), + (0x1D41E, "M", "e"), + (0x1D41F, "M", "f"), + (0x1D420, "M", "g"), + (0x1D421, "M", "h"), + (0x1D422, "M", "i"), + (0x1D423, "M", "j"), + (0x1D424, "M", "k"), ] + def _seg_61() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D421, 'M', 'h'), - (0x1D422, 'M', 'i'), - (0x1D423, 'M', 'j'), - (0x1D424, 'M', 'k'), - (0x1D425, 'M', 'l'), - (0x1D426, 'M', 'm'), - (0x1D427, 'M', 'n'), - (0x1D428, 'M', 'o'), - (0x1D429, 'M', 'p'), - (0x1D42A, 'M', 'q'), - (0x1D42B, 'M', 'r'), - (0x1D42C, 'M', 's'), - (0x1D42D, 'M', 't'), - (0x1D42E, 'M', 'u'), - (0x1D42F, 'M', 'v'), - (0x1D430, 'M', 'w'), - (0x1D431, 'M', 'x'), - (0x1D432, 'M', 'y'), - (0x1D433, 'M', 'z'), - (0x1D434, 'M', 'a'), - (0x1D435, 'M', 'b'), - (0x1D436, 'M', 'c'), - (0x1D437, 'M', 'd'), - (0x1D438, 'M', 'e'), - (0x1D439, 'M', 'f'), - (0x1D43A, 'M', 'g'), - (0x1D43B, 'M', 'h'), - (0x1D43C, 'M', 'i'), - (0x1D43D, 'M', 'j'), - (0x1D43E, 'M', 'k'), - (0x1D43F, 'M', 'l'), - (0x1D440, 'M', 'm'), - (0x1D441, 'M', 'n'), - (0x1D442, 'M', 'o'), - (0x1D443, 'M', 'p'), - (0x1D444, 'M', 'q'), - (0x1D445, 'M', 'r'), - (0x1D446, 'M', 's'), - (0x1D447, 'M', 't'), - (0x1D448, 'M', 'u'), - (0x1D449, 'M', 'v'), - (0x1D44A, 'M', 'w'), - (0x1D44B, 'M', 'x'), - (0x1D44C, 'M', 'y'), - (0x1D44D, 'M', 'z'), - (0x1D44E, 'M', 'a'), - (0x1D44F, 'M', 'b'), - (0x1D450, 'M', 'c'), - (0x1D451, 'M', 'd'), - (0x1D452, 'M', 'e'), - (0x1D453, 'M', 'f'), - (0x1D454, 'M', 'g'), - (0x1D455, 'X'), - (0x1D456, 'M', 'i'), - (0x1D457, 'M', 'j'), - (0x1D458, 'M', 'k'), - (0x1D459, 'M', 'l'), - (0x1D45A, 'M', 'm'), - (0x1D45B, 'M', 'n'), - (0x1D45C, 'M', 'o'), - (0x1D45D, 'M', 'p'), - (0x1D45E, 'M', 'q'), - (0x1D45F, 'M', 'r'), - (0x1D460, 'M', 's'), - (0x1D461, 'M', 't'), - (0x1D462, 'M', 'u'), - (0x1D463, 'M', 'v'), - (0x1D464, 'M', 'w'), - (0x1D465, 'M', 'x'), - (0x1D466, 'M', 'y'), - (0x1D467, 'M', 'z'), - (0x1D468, 'M', 'a'), - (0x1D469, 'M', 'b'), - (0x1D46A, 'M', 'c'), - (0x1D46B, 'M', 'd'), - (0x1D46C, 'M', 'e'), - (0x1D46D, 'M', 'f'), - (0x1D46E, 'M', 'g'), - (0x1D46F, 'M', 'h'), - (0x1D470, 'M', 'i'), - (0x1D471, 'M', 'j'), - (0x1D472, 'M', 'k'), - (0x1D473, 'M', 'l'), - (0x1D474, 'M', 'm'), - (0x1D475, 'M', 'n'), - (0x1D476, 'M', 'o'), - (0x1D477, 'M', 'p'), - (0x1D478, 'M', 'q'), - (0x1D479, 'M', 'r'), - (0x1D47A, 'M', 's'), - (0x1D47B, 'M', 't'), - (0x1D47C, 'M', 'u'), - (0x1D47D, 'M', 'v'), - (0x1D47E, 'M', 'w'), - (0x1D47F, 'M', 'x'), - (0x1D480, 'M', 'y'), - (0x1D481, 'M', 'z'), - (0x1D482, 'M', 'a'), - (0x1D483, 'M', 'b'), - (0x1D484, 'M', 'c'), + (0x1D425, "M", "l"), + (0x1D426, "M", "m"), + (0x1D427, "M", "n"), + (0x1D428, "M", "o"), + (0x1D429, "M", "p"), + (0x1D42A, "M", "q"), + (0x1D42B, "M", "r"), + (0x1D42C, "M", "s"), + (0x1D42D, "M", "t"), + (0x1D42E, "M", "u"), + (0x1D42F, "M", "v"), + (0x1D430, "M", "w"), + (0x1D431, "M", "x"), + (0x1D432, "M", "y"), + (0x1D433, "M", "z"), + (0x1D434, "M", "a"), + (0x1D435, "M", "b"), + (0x1D436, "M", "c"), + (0x1D437, "M", "d"), + (0x1D438, "M", "e"), + (0x1D439, "M", "f"), + (0x1D43A, "M", "g"), + (0x1D43B, "M", "h"), + (0x1D43C, "M", "i"), + (0x1D43D, "M", "j"), + (0x1D43E, "M", "k"), + (0x1D43F, "M", "l"), + (0x1D440, "M", "m"), + (0x1D441, "M", "n"), + (0x1D442, "M", "o"), + (0x1D443, "M", "p"), + (0x1D444, "M", "q"), + (0x1D445, "M", "r"), + (0x1D446, "M", "s"), + (0x1D447, "M", "t"), + (0x1D448, "M", "u"), + (0x1D449, "M", "v"), + (0x1D44A, "M", "w"), + (0x1D44B, "M", "x"), + (0x1D44C, "M", "y"), + (0x1D44D, "M", "z"), + (0x1D44E, "M", "a"), + (0x1D44F, "M", "b"), + (0x1D450, "M", "c"), + (0x1D451, "M", "d"), + (0x1D452, "M", "e"), + (0x1D453, "M", "f"), + (0x1D454, "M", "g"), + (0x1D455, "X"), + (0x1D456, "M", "i"), + (0x1D457, "M", "j"), + (0x1D458, "M", "k"), + (0x1D459, "M", "l"), + (0x1D45A, "M", "m"), + (0x1D45B, "M", "n"), + (0x1D45C, "M", "o"), + (0x1D45D, "M", "p"), + (0x1D45E, "M", "q"), + (0x1D45F, "M", "r"), + (0x1D460, "M", "s"), + (0x1D461, "M", "t"), + (0x1D462, "M", "u"), + (0x1D463, "M", "v"), + (0x1D464, "M", "w"), + (0x1D465, "M", "x"), + (0x1D466, "M", "y"), + (0x1D467, "M", "z"), + (0x1D468, "M", "a"), + (0x1D469, "M", "b"), + (0x1D46A, "M", "c"), + (0x1D46B, "M", "d"), + (0x1D46C, "M", "e"), + (0x1D46D, "M", "f"), + (0x1D46E, "M", "g"), + (0x1D46F, "M", "h"), + (0x1D470, "M", "i"), + (0x1D471, "M", "j"), + (0x1D472, "M", "k"), + (0x1D473, "M", "l"), + (0x1D474, "M", "m"), + (0x1D475, "M", "n"), + (0x1D476, "M", "o"), + (0x1D477, "M", "p"), + (0x1D478, "M", "q"), + (0x1D479, "M", "r"), + (0x1D47A, "M", "s"), + (0x1D47B, "M", "t"), + (0x1D47C, "M", "u"), + (0x1D47D, "M", "v"), + (0x1D47E, "M", "w"), + (0x1D47F, "M", "x"), + (0x1D480, "M", "y"), + (0x1D481, "M", "z"), + (0x1D482, "M", "a"), + (0x1D483, "M", "b"), + (0x1D484, "M", "c"), + (0x1D485, "M", "d"), + (0x1D486, "M", "e"), + (0x1D487, "M", "f"), + (0x1D488, "M", "g"), ] + def _seg_62() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D485, 'M', 'd'), - (0x1D486, 'M', 'e'), - (0x1D487, 'M', 'f'), - (0x1D488, 'M', 'g'), - (0x1D489, 'M', 'h'), - (0x1D48A, 'M', 'i'), - (0x1D48B, 'M', 'j'), - (0x1D48C, 'M', 'k'), - (0x1D48D, 'M', 'l'), - (0x1D48E, 'M', 'm'), - (0x1D48F, 'M', 'n'), - (0x1D490, 'M', 'o'), - (0x1D491, 'M', 'p'), - (0x1D492, 'M', 'q'), - (0x1D493, 'M', 'r'), - (0x1D494, 'M', 's'), - (0x1D495, 'M', 't'), - (0x1D496, 'M', 'u'), - (0x1D497, 'M', 'v'), - (0x1D498, 'M', 'w'), - (0x1D499, 'M', 'x'), - (0x1D49A, 'M', 'y'), - (0x1D49B, 'M', 'z'), - (0x1D49C, 'M', 'a'), - (0x1D49D, 'X'), - (0x1D49E, 'M', 'c'), - (0x1D49F, 'M', 'd'), - (0x1D4A0, 'X'), - (0x1D4A2, 'M', 'g'), - (0x1D4A3, 'X'), - (0x1D4A5, 'M', 'j'), - (0x1D4A6, 'M', 'k'), - (0x1D4A7, 'X'), - (0x1D4A9, 'M', 'n'), - (0x1D4AA, 'M', 'o'), - (0x1D4AB, 'M', 'p'), - (0x1D4AC, 'M', 'q'), - (0x1D4AD, 'X'), - (0x1D4AE, 'M', 's'), - (0x1D4AF, 'M', 't'), - (0x1D4B0, 'M', 'u'), - (0x1D4B1, 'M', 'v'), - (0x1D4B2, 'M', 'w'), - (0x1D4B3, 'M', 'x'), - (0x1D4B4, 'M', 'y'), - (0x1D4B5, 'M', 'z'), - (0x1D4B6, 'M', 'a'), - (0x1D4B7, 'M', 'b'), - (0x1D4B8, 'M', 'c'), - (0x1D4B9, 'M', 'd'), - (0x1D4BA, 'X'), - (0x1D4BB, 'M', 'f'), - (0x1D4BC, 'X'), - (0x1D4BD, 'M', 'h'), - (0x1D4BE, 'M', 'i'), - (0x1D4BF, 'M', 'j'), - (0x1D4C0, 'M', 'k'), - (0x1D4C1, 'M', 'l'), - (0x1D4C2, 'M', 'm'), - (0x1D4C3, 'M', 'n'), - (0x1D4C4, 'X'), - (0x1D4C5, 'M', 'p'), - (0x1D4C6, 'M', 'q'), - (0x1D4C7, 'M', 'r'), - (0x1D4C8, 'M', 's'), - (0x1D4C9, 'M', 't'), - (0x1D4CA, 'M', 'u'), - (0x1D4CB, 'M', 'v'), - (0x1D4CC, 'M', 'w'), - (0x1D4CD, 'M', 'x'), - (0x1D4CE, 'M', 'y'), - (0x1D4CF, 'M', 'z'), - (0x1D4D0, 'M', 'a'), - (0x1D4D1, 'M', 'b'), - (0x1D4D2, 'M', 'c'), - (0x1D4D3, 'M', 'd'), - (0x1D4D4, 'M', 'e'), - (0x1D4D5, 'M', 'f'), - (0x1D4D6, 'M', 'g'), - (0x1D4D7, 'M', 'h'), - (0x1D4D8, 'M', 'i'), - (0x1D4D9, 'M', 'j'), - (0x1D4DA, 'M', 'k'), - (0x1D4DB, 'M', 'l'), - (0x1D4DC, 'M', 'm'), - (0x1D4DD, 'M', 'n'), - (0x1D4DE, 'M', 'o'), - (0x1D4DF, 'M', 'p'), - (0x1D4E0, 'M', 'q'), - (0x1D4E1, 'M', 'r'), - (0x1D4E2, 'M', 's'), - (0x1D4E3, 'M', 't'), - (0x1D4E4, 'M', 'u'), - (0x1D4E5, 'M', 'v'), - (0x1D4E6, 'M', 'w'), - (0x1D4E7, 'M', 'x'), - (0x1D4E8, 'M', 'y'), - (0x1D4E9, 'M', 'z'), - (0x1D4EA, 'M', 'a'), - (0x1D4EB, 'M', 'b'), + (0x1D489, "M", "h"), + (0x1D48A, "M", "i"), + (0x1D48B, "M", "j"), + (0x1D48C, "M", "k"), + (0x1D48D, "M", "l"), + (0x1D48E, "M", "m"), + (0x1D48F, "M", "n"), + (0x1D490, "M", "o"), + (0x1D491, "M", "p"), + (0x1D492, "M", "q"), + (0x1D493, "M", "r"), + (0x1D494, "M", "s"), + (0x1D495, "M", "t"), + (0x1D496, "M", "u"), + (0x1D497, "M", "v"), + (0x1D498, "M", "w"), + (0x1D499, "M", "x"), + (0x1D49A, "M", "y"), + (0x1D49B, "M", "z"), + (0x1D49C, "M", "a"), + (0x1D49D, "X"), + (0x1D49E, "M", "c"), + (0x1D49F, "M", "d"), + (0x1D4A0, "X"), + (0x1D4A2, "M", "g"), + (0x1D4A3, "X"), + (0x1D4A5, "M", "j"), + (0x1D4A6, "M", "k"), + (0x1D4A7, "X"), + (0x1D4A9, "M", "n"), + (0x1D4AA, "M", "o"), + (0x1D4AB, "M", "p"), + (0x1D4AC, "M", "q"), + (0x1D4AD, "X"), + (0x1D4AE, "M", "s"), + (0x1D4AF, "M", "t"), + (0x1D4B0, "M", "u"), + (0x1D4B1, "M", "v"), + (0x1D4B2, "M", "w"), + (0x1D4B3, "M", "x"), + (0x1D4B4, "M", "y"), + (0x1D4B5, "M", "z"), + (0x1D4B6, "M", "a"), + (0x1D4B7, "M", "b"), + (0x1D4B8, "M", "c"), + (0x1D4B9, "M", "d"), + (0x1D4BA, "X"), + (0x1D4BB, "M", "f"), + (0x1D4BC, "X"), + (0x1D4BD, "M", "h"), + (0x1D4BE, "M", "i"), + (0x1D4BF, "M", "j"), + (0x1D4C0, "M", "k"), + (0x1D4C1, "M", "l"), + (0x1D4C2, "M", "m"), + (0x1D4C3, "M", "n"), + (0x1D4C4, "X"), + (0x1D4C5, "M", "p"), + (0x1D4C6, "M", "q"), + (0x1D4C7, "M", "r"), + (0x1D4C8, "M", "s"), + (0x1D4C9, "M", "t"), + (0x1D4CA, "M", "u"), + (0x1D4CB, "M", "v"), + (0x1D4CC, "M", "w"), + (0x1D4CD, "M", "x"), + (0x1D4CE, "M", "y"), + (0x1D4CF, "M", "z"), + (0x1D4D0, "M", "a"), + (0x1D4D1, "M", "b"), + (0x1D4D2, "M", "c"), + (0x1D4D3, "M", "d"), + (0x1D4D4, "M", "e"), + (0x1D4D5, "M", "f"), + (0x1D4D6, "M", "g"), + (0x1D4D7, "M", "h"), + (0x1D4D8, "M", "i"), + (0x1D4D9, "M", "j"), + (0x1D4DA, "M", "k"), + (0x1D4DB, "M", "l"), + (0x1D4DC, "M", "m"), + (0x1D4DD, "M", "n"), + (0x1D4DE, "M", "o"), + (0x1D4DF, "M", "p"), + (0x1D4E0, "M", "q"), + (0x1D4E1, "M", "r"), + (0x1D4E2, "M", "s"), + (0x1D4E3, "M", "t"), + (0x1D4E4, "M", "u"), + (0x1D4E5, "M", "v"), + (0x1D4E6, "M", "w"), + (0x1D4E7, "M", "x"), + (0x1D4E8, "M", "y"), + (0x1D4E9, "M", "z"), + (0x1D4EA, "M", "a"), + (0x1D4EB, "M", "b"), + (0x1D4EC, "M", "c"), + (0x1D4ED, "M", "d"), + (0x1D4EE, "M", "e"), + (0x1D4EF, "M", "f"), ] + def _seg_63() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D4EC, 'M', 'c'), - (0x1D4ED, 'M', 'd'), - (0x1D4EE, 'M', 'e'), - (0x1D4EF, 'M', 'f'), - (0x1D4F0, 'M', 'g'), - (0x1D4F1, 'M', 'h'), - (0x1D4F2, 'M', 'i'), - (0x1D4F3, 'M', 'j'), - (0x1D4F4, 'M', 'k'), - (0x1D4F5, 'M', 'l'), - (0x1D4F6, 'M', 'm'), - (0x1D4F7, 'M', 'n'), - (0x1D4F8, 'M', 'o'), - (0x1D4F9, 'M', 'p'), - (0x1D4FA, 'M', 'q'), - (0x1D4FB, 'M', 'r'), - (0x1D4FC, 'M', 's'), - (0x1D4FD, 'M', 't'), - (0x1D4FE, 'M', 'u'), - (0x1D4FF, 'M', 'v'), - (0x1D500, 'M', 'w'), - (0x1D501, 'M', 'x'), - (0x1D502, 'M', 'y'), - (0x1D503, 'M', 'z'), - (0x1D504, 'M', 'a'), - (0x1D505, 'M', 'b'), - (0x1D506, 'X'), - (0x1D507, 'M', 'd'), - (0x1D508, 'M', 'e'), - (0x1D509, 'M', 'f'), - (0x1D50A, 'M', 'g'), - (0x1D50B, 'X'), - (0x1D50D, 'M', 'j'), - (0x1D50E, 'M', 'k'), - (0x1D50F, 'M', 'l'), - (0x1D510, 'M', 'm'), - (0x1D511, 'M', 'n'), - (0x1D512, 'M', 'o'), - (0x1D513, 'M', 'p'), - (0x1D514, 'M', 'q'), - (0x1D515, 'X'), - (0x1D516, 'M', 's'), - (0x1D517, 'M', 't'), - (0x1D518, 'M', 'u'), - (0x1D519, 'M', 'v'), - (0x1D51A, 'M', 'w'), - (0x1D51B, 'M', 'x'), - (0x1D51C, 'M', 'y'), - (0x1D51D, 'X'), - (0x1D51E, 'M', 'a'), - (0x1D51F, 'M', 'b'), - (0x1D520, 'M', 'c'), - (0x1D521, 'M', 'd'), - (0x1D522, 'M', 'e'), - (0x1D523, 'M', 'f'), - (0x1D524, 'M', 'g'), - (0x1D525, 'M', 'h'), - (0x1D526, 'M', 'i'), - (0x1D527, 'M', 'j'), - (0x1D528, 'M', 'k'), - (0x1D529, 'M', 'l'), - (0x1D52A, 'M', 'm'), - (0x1D52B, 'M', 'n'), - (0x1D52C, 'M', 'o'), - (0x1D52D, 'M', 'p'), - (0x1D52E, 'M', 'q'), - (0x1D52F, 'M', 'r'), - (0x1D530, 'M', 's'), - (0x1D531, 'M', 't'), - (0x1D532, 'M', 'u'), - (0x1D533, 'M', 'v'), - (0x1D534, 'M', 'w'), - (0x1D535, 'M', 'x'), - (0x1D536, 'M', 'y'), - (0x1D537, 'M', 'z'), - (0x1D538, 'M', 'a'), - (0x1D539, 'M', 'b'), - (0x1D53A, 'X'), - (0x1D53B, 'M', 'd'), - (0x1D53C, 'M', 'e'), - (0x1D53D, 'M', 'f'), - (0x1D53E, 'M', 'g'), - (0x1D53F, 'X'), - (0x1D540, 'M', 'i'), - (0x1D541, 'M', 'j'), - (0x1D542, 'M', 'k'), - (0x1D543, 'M', 'l'), - (0x1D544, 'M', 'm'), - (0x1D545, 'X'), - (0x1D546, 'M', 'o'), - (0x1D547, 'X'), - (0x1D54A, 'M', 's'), - (0x1D54B, 'M', 't'), - (0x1D54C, 'M', 'u'), - (0x1D54D, 'M', 'v'), - (0x1D54E, 'M', 'w'), - (0x1D54F, 'M', 'x'), - (0x1D550, 'M', 'y'), - (0x1D551, 'X'), - (0x1D552, 'M', 'a'), + (0x1D4F0, "M", "g"), + (0x1D4F1, "M", "h"), + (0x1D4F2, "M", "i"), + (0x1D4F3, "M", "j"), + (0x1D4F4, "M", "k"), + (0x1D4F5, "M", "l"), + (0x1D4F6, "M", "m"), + (0x1D4F7, "M", "n"), + (0x1D4F8, "M", "o"), + (0x1D4F9, "M", "p"), + (0x1D4FA, "M", "q"), + (0x1D4FB, "M", "r"), + (0x1D4FC, "M", "s"), + (0x1D4FD, "M", "t"), + (0x1D4FE, "M", "u"), + (0x1D4FF, "M", "v"), + (0x1D500, "M", "w"), + (0x1D501, "M", "x"), + (0x1D502, "M", "y"), + (0x1D503, "M", "z"), + (0x1D504, "M", "a"), + (0x1D505, "M", "b"), + (0x1D506, "X"), + (0x1D507, "M", "d"), + (0x1D508, "M", "e"), + (0x1D509, "M", "f"), + (0x1D50A, "M", "g"), + (0x1D50B, "X"), + (0x1D50D, "M", "j"), + (0x1D50E, "M", "k"), + (0x1D50F, "M", "l"), + (0x1D510, "M", "m"), + (0x1D511, "M", "n"), + (0x1D512, "M", "o"), + (0x1D513, "M", "p"), + (0x1D514, "M", "q"), + (0x1D515, "X"), + (0x1D516, "M", "s"), + (0x1D517, "M", "t"), + (0x1D518, "M", "u"), + (0x1D519, "M", "v"), + (0x1D51A, "M", "w"), + (0x1D51B, "M", "x"), + (0x1D51C, "M", "y"), + (0x1D51D, "X"), + (0x1D51E, "M", "a"), + (0x1D51F, "M", "b"), + (0x1D520, "M", "c"), + (0x1D521, "M", "d"), + (0x1D522, "M", "e"), + (0x1D523, "M", "f"), + (0x1D524, "M", "g"), + (0x1D525, "M", "h"), + (0x1D526, "M", "i"), + (0x1D527, "M", "j"), + (0x1D528, "M", "k"), + (0x1D529, "M", "l"), + (0x1D52A, "M", "m"), + (0x1D52B, "M", "n"), + (0x1D52C, "M", "o"), + (0x1D52D, "M", "p"), + (0x1D52E, "M", "q"), + (0x1D52F, "M", "r"), + (0x1D530, "M", "s"), + (0x1D531, "M", "t"), + (0x1D532, "M", "u"), + (0x1D533, "M", "v"), + (0x1D534, "M", "w"), + (0x1D535, "M", "x"), + (0x1D536, "M", "y"), + (0x1D537, "M", "z"), + (0x1D538, "M", "a"), + (0x1D539, "M", "b"), + (0x1D53A, "X"), + (0x1D53B, "M", "d"), + (0x1D53C, "M", "e"), + (0x1D53D, "M", "f"), + (0x1D53E, "M", "g"), + (0x1D53F, "X"), + (0x1D540, "M", "i"), + (0x1D541, "M", "j"), + (0x1D542, "M", "k"), + (0x1D543, "M", "l"), + (0x1D544, "M", "m"), + (0x1D545, "X"), + (0x1D546, "M", "o"), + (0x1D547, "X"), + (0x1D54A, "M", "s"), + (0x1D54B, "M", "t"), + (0x1D54C, "M", "u"), + (0x1D54D, "M", "v"), + (0x1D54E, "M", "w"), + (0x1D54F, "M", "x"), + (0x1D550, "M", "y"), + (0x1D551, "X"), + (0x1D552, "M", "a"), + (0x1D553, "M", "b"), + (0x1D554, "M", "c"), + (0x1D555, "M", "d"), + (0x1D556, "M", "e"), ] + def _seg_64() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D553, 'M', 'b'), - (0x1D554, 'M', 'c'), - (0x1D555, 'M', 'd'), - (0x1D556, 'M', 'e'), - (0x1D557, 'M', 'f'), - (0x1D558, 'M', 'g'), - (0x1D559, 'M', 'h'), - (0x1D55A, 'M', 'i'), - (0x1D55B, 'M', 'j'), - (0x1D55C, 'M', 'k'), - (0x1D55D, 'M', 'l'), - (0x1D55E, 'M', 'm'), - (0x1D55F, 'M', 'n'), - (0x1D560, 'M', 'o'), - (0x1D561, 'M', 'p'), - (0x1D562, 'M', 'q'), - (0x1D563, 'M', 'r'), - (0x1D564, 'M', 's'), - (0x1D565, 'M', 't'), - (0x1D566, 'M', 'u'), - (0x1D567, 'M', 'v'), - (0x1D568, 'M', 'w'), - (0x1D569, 'M', 'x'), - (0x1D56A, 'M', 'y'), - (0x1D56B, 'M', 'z'), - (0x1D56C, 'M', 'a'), - (0x1D56D, 'M', 'b'), - (0x1D56E, 'M', 'c'), - (0x1D56F, 'M', 'd'), - (0x1D570, 'M', 'e'), - (0x1D571, 'M', 'f'), - (0x1D572, 'M', 'g'), - (0x1D573, 'M', 'h'), - (0x1D574, 'M', 'i'), - (0x1D575, 'M', 'j'), - (0x1D576, 'M', 'k'), - (0x1D577, 'M', 'l'), - (0x1D578, 'M', 'm'), - (0x1D579, 'M', 'n'), - (0x1D57A, 'M', 'o'), - (0x1D57B, 'M', 'p'), - (0x1D57C, 'M', 'q'), - (0x1D57D, 'M', 'r'), - (0x1D57E, 'M', 's'), - (0x1D57F, 'M', 't'), - (0x1D580, 'M', 'u'), - (0x1D581, 'M', 'v'), - (0x1D582, 'M', 'w'), - (0x1D583, 'M', 'x'), - (0x1D584, 'M', 'y'), - (0x1D585, 'M', 'z'), - (0x1D586, 'M', 'a'), - (0x1D587, 'M', 'b'), - (0x1D588, 'M', 'c'), - (0x1D589, 'M', 'd'), - (0x1D58A, 'M', 'e'), - (0x1D58B, 'M', 'f'), - (0x1D58C, 'M', 'g'), - (0x1D58D, 'M', 'h'), - (0x1D58E, 'M', 'i'), - (0x1D58F, 'M', 'j'), - (0x1D590, 'M', 'k'), - (0x1D591, 'M', 'l'), - (0x1D592, 'M', 'm'), - (0x1D593, 'M', 'n'), - (0x1D594, 'M', 'o'), - (0x1D595, 'M', 'p'), - (0x1D596, 'M', 'q'), - (0x1D597, 'M', 'r'), - (0x1D598, 'M', 's'), - (0x1D599, 'M', 't'), - (0x1D59A, 'M', 'u'), - (0x1D59B, 'M', 'v'), - (0x1D59C, 'M', 'w'), - (0x1D59D, 'M', 'x'), - (0x1D59E, 'M', 'y'), - (0x1D59F, 'M', 'z'), - (0x1D5A0, 'M', 'a'), - (0x1D5A1, 'M', 'b'), - (0x1D5A2, 'M', 'c'), - (0x1D5A3, 'M', 'd'), - (0x1D5A4, 'M', 'e'), - (0x1D5A5, 'M', 'f'), - (0x1D5A6, 'M', 'g'), - (0x1D5A7, 'M', 'h'), - (0x1D5A8, 'M', 'i'), - (0x1D5A9, 'M', 'j'), - (0x1D5AA, 'M', 'k'), - (0x1D5AB, 'M', 'l'), - (0x1D5AC, 'M', 'm'), - (0x1D5AD, 'M', 'n'), - (0x1D5AE, 'M', 'o'), - (0x1D5AF, 'M', 'p'), - (0x1D5B0, 'M', 'q'), - (0x1D5B1, 'M', 'r'), - (0x1D5B2, 'M', 's'), - (0x1D5B3, 'M', 't'), - (0x1D5B4, 'M', 'u'), - (0x1D5B5, 'M', 'v'), - (0x1D5B6, 'M', 'w'), + (0x1D557, "M", "f"), + (0x1D558, "M", "g"), + (0x1D559, "M", "h"), + (0x1D55A, "M", "i"), + (0x1D55B, "M", "j"), + (0x1D55C, "M", "k"), + (0x1D55D, "M", "l"), + (0x1D55E, "M", "m"), + (0x1D55F, "M", "n"), + (0x1D560, "M", "o"), + (0x1D561, "M", "p"), + (0x1D562, "M", "q"), + (0x1D563, "M", "r"), + (0x1D564, "M", "s"), + (0x1D565, "M", "t"), + (0x1D566, "M", "u"), + (0x1D567, "M", "v"), + (0x1D568, "M", "w"), + (0x1D569, "M", "x"), + (0x1D56A, "M", "y"), + (0x1D56B, "M", "z"), + (0x1D56C, "M", "a"), + (0x1D56D, "M", "b"), + (0x1D56E, "M", "c"), + (0x1D56F, "M", "d"), + (0x1D570, "M", "e"), + (0x1D571, "M", "f"), + (0x1D572, "M", "g"), + (0x1D573, "M", "h"), + (0x1D574, "M", "i"), + (0x1D575, "M", "j"), + (0x1D576, "M", "k"), + (0x1D577, "M", "l"), + (0x1D578, "M", "m"), + (0x1D579, "M", "n"), + (0x1D57A, "M", "o"), + (0x1D57B, "M", "p"), + (0x1D57C, "M", "q"), + (0x1D57D, "M", "r"), + (0x1D57E, "M", "s"), + (0x1D57F, "M", "t"), + (0x1D580, "M", "u"), + (0x1D581, "M", "v"), + (0x1D582, "M", "w"), + (0x1D583, "M", "x"), + (0x1D584, "M", "y"), + (0x1D585, "M", "z"), + (0x1D586, "M", "a"), + (0x1D587, "M", "b"), + (0x1D588, "M", "c"), + (0x1D589, "M", "d"), + (0x1D58A, "M", "e"), + (0x1D58B, "M", "f"), + (0x1D58C, "M", "g"), + (0x1D58D, "M", "h"), + (0x1D58E, "M", "i"), + (0x1D58F, "M", "j"), + (0x1D590, "M", "k"), + (0x1D591, "M", "l"), + (0x1D592, "M", "m"), + (0x1D593, "M", "n"), + (0x1D594, "M", "o"), + (0x1D595, "M", "p"), + (0x1D596, "M", "q"), + (0x1D597, "M", "r"), + (0x1D598, "M", "s"), + (0x1D599, "M", "t"), + (0x1D59A, "M", "u"), + (0x1D59B, "M", "v"), + (0x1D59C, "M", "w"), + (0x1D59D, "M", "x"), + (0x1D59E, "M", "y"), + (0x1D59F, "M", "z"), + (0x1D5A0, "M", "a"), + (0x1D5A1, "M", "b"), + (0x1D5A2, "M", "c"), + (0x1D5A3, "M", "d"), + (0x1D5A4, "M", "e"), + (0x1D5A5, "M", "f"), + (0x1D5A6, "M", "g"), + (0x1D5A7, "M", "h"), + (0x1D5A8, "M", "i"), + (0x1D5A9, "M", "j"), + (0x1D5AA, "M", "k"), + (0x1D5AB, "M", "l"), + (0x1D5AC, "M", "m"), + (0x1D5AD, "M", "n"), + (0x1D5AE, "M", "o"), + (0x1D5AF, "M", "p"), + (0x1D5B0, "M", "q"), + (0x1D5B1, "M", "r"), + (0x1D5B2, "M", "s"), + (0x1D5B3, "M", "t"), + (0x1D5B4, "M", "u"), + (0x1D5B5, "M", "v"), + (0x1D5B6, "M", "w"), + (0x1D5B7, "M", "x"), + (0x1D5B8, "M", "y"), + (0x1D5B9, "M", "z"), + (0x1D5BA, "M", "a"), ] + def _seg_65() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D5B7, 'M', 'x'), - (0x1D5B8, 'M', 'y'), - (0x1D5B9, 'M', 'z'), - (0x1D5BA, 'M', 'a'), - (0x1D5BB, 'M', 'b'), - (0x1D5BC, 'M', 'c'), - (0x1D5BD, 'M', 'd'), - (0x1D5BE, 'M', 'e'), - (0x1D5BF, 'M', 'f'), - (0x1D5C0, 'M', 'g'), - (0x1D5C1, 'M', 'h'), - (0x1D5C2, 'M', 'i'), - (0x1D5C3, 'M', 'j'), - (0x1D5C4, 'M', 'k'), - (0x1D5C5, 'M', 'l'), - (0x1D5C6, 'M', 'm'), - (0x1D5C7, 'M', 'n'), - (0x1D5C8, 'M', 'o'), - (0x1D5C9, 'M', 'p'), - (0x1D5CA, 'M', 'q'), - (0x1D5CB, 'M', 'r'), - (0x1D5CC, 'M', 's'), - (0x1D5CD, 'M', 't'), - (0x1D5CE, 'M', 'u'), - (0x1D5CF, 'M', 'v'), - (0x1D5D0, 'M', 'w'), - (0x1D5D1, 'M', 'x'), - (0x1D5D2, 'M', 'y'), - (0x1D5D3, 'M', 'z'), - (0x1D5D4, 'M', 'a'), - (0x1D5D5, 'M', 'b'), - (0x1D5D6, 'M', 'c'), - (0x1D5D7, 'M', 'd'), - (0x1D5D8, 'M', 'e'), - (0x1D5D9, 'M', 'f'), - (0x1D5DA, 'M', 'g'), - (0x1D5DB, 'M', 'h'), - (0x1D5DC, 'M', 'i'), - (0x1D5DD, 'M', 'j'), - (0x1D5DE, 'M', 'k'), - (0x1D5DF, 'M', 'l'), - (0x1D5E0, 'M', 'm'), - (0x1D5E1, 'M', 'n'), - (0x1D5E2, 'M', 'o'), - (0x1D5E3, 'M', 'p'), - (0x1D5E4, 'M', 'q'), - (0x1D5E5, 'M', 'r'), - (0x1D5E6, 'M', 's'), - (0x1D5E7, 'M', 't'), - (0x1D5E8, 'M', 'u'), - (0x1D5E9, 'M', 'v'), - (0x1D5EA, 'M', 'w'), - (0x1D5EB, 'M', 'x'), - (0x1D5EC, 'M', 'y'), - (0x1D5ED, 'M', 'z'), - (0x1D5EE, 'M', 'a'), - (0x1D5EF, 'M', 'b'), - (0x1D5F0, 'M', 'c'), - (0x1D5F1, 'M', 'd'), - (0x1D5F2, 'M', 'e'), - (0x1D5F3, 'M', 'f'), - (0x1D5F4, 'M', 'g'), - (0x1D5F5, 'M', 'h'), - (0x1D5F6, 'M', 'i'), - (0x1D5F7, 'M', 'j'), - (0x1D5F8, 'M', 'k'), - (0x1D5F9, 'M', 'l'), - (0x1D5FA, 'M', 'm'), - (0x1D5FB, 'M', 'n'), - (0x1D5FC, 'M', 'o'), - (0x1D5FD, 'M', 'p'), - (0x1D5FE, 'M', 'q'), - (0x1D5FF, 'M', 'r'), - (0x1D600, 'M', 's'), - (0x1D601, 'M', 't'), - (0x1D602, 'M', 'u'), - (0x1D603, 'M', 'v'), - (0x1D604, 'M', 'w'), - (0x1D605, 'M', 'x'), - (0x1D606, 'M', 'y'), - (0x1D607, 'M', 'z'), - (0x1D608, 'M', 'a'), - (0x1D609, 'M', 'b'), - (0x1D60A, 'M', 'c'), - (0x1D60B, 'M', 'd'), - (0x1D60C, 'M', 'e'), - (0x1D60D, 'M', 'f'), - (0x1D60E, 'M', 'g'), - (0x1D60F, 'M', 'h'), - (0x1D610, 'M', 'i'), - (0x1D611, 'M', 'j'), - (0x1D612, 'M', 'k'), - (0x1D613, 'M', 'l'), - (0x1D614, 'M', 'm'), - (0x1D615, 'M', 'n'), - (0x1D616, 'M', 'o'), - (0x1D617, 'M', 'p'), - (0x1D618, 'M', 'q'), - (0x1D619, 'M', 'r'), - (0x1D61A, 'M', 's'), + (0x1D5BB, "M", "b"), + (0x1D5BC, "M", "c"), + (0x1D5BD, "M", "d"), + (0x1D5BE, "M", "e"), + (0x1D5BF, "M", "f"), + (0x1D5C0, "M", "g"), + (0x1D5C1, "M", "h"), + (0x1D5C2, "M", "i"), + (0x1D5C3, "M", "j"), + (0x1D5C4, "M", "k"), + (0x1D5C5, "M", "l"), + (0x1D5C6, "M", "m"), + (0x1D5C7, "M", "n"), + (0x1D5C8, "M", "o"), + (0x1D5C9, "M", "p"), + (0x1D5CA, "M", "q"), + (0x1D5CB, "M", "r"), + (0x1D5CC, "M", "s"), + (0x1D5CD, "M", "t"), + (0x1D5CE, "M", "u"), + (0x1D5CF, "M", "v"), + (0x1D5D0, "M", "w"), + (0x1D5D1, "M", "x"), + (0x1D5D2, "M", "y"), + (0x1D5D3, "M", "z"), + (0x1D5D4, "M", "a"), + (0x1D5D5, "M", "b"), + (0x1D5D6, "M", "c"), + (0x1D5D7, "M", "d"), + (0x1D5D8, "M", "e"), + (0x1D5D9, "M", "f"), + (0x1D5DA, "M", "g"), + (0x1D5DB, "M", "h"), + (0x1D5DC, "M", "i"), + (0x1D5DD, "M", "j"), + (0x1D5DE, "M", "k"), + (0x1D5DF, "M", "l"), + (0x1D5E0, "M", "m"), + (0x1D5E1, "M", "n"), + (0x1D5E2, "M", "o"), + (0x1D5E3, "M", "p"), + (0x1D5E4, "M", "q"), + (0x1D5E5, "M", "r"), + (0x1D5E6, "M", "s"), + (0x1D5E7, "M", "t"), + (0x1D5E8, "M", "u"), + (0x1D5E9, "M", "v"), + (0x1D5EA, "M", "w"), + (0x1D5EB, "M", "x"), + (0x1D5EC, "M", "y"), + (0x1D5ED, "M", "z"), + (0x1D5EE, "M", "a"), + (0x1D5EF, "M", "b"), + (0x1D5F0, "M", "c"), + (0x1D5F1, "M", "d"), + (0x1D5F2, "M", "e"), + (0x1D5F3, "M", "f"), + (0x1D5F4, "M", "g"), + (0x1D5F5, "M", "h"), + (0x1D5F6, "M", "i"), + (0x1D5F7, "M", "j"), + (0x1D5F8, "M", "k"), + (0x1D5F9, "M", "l"), + (0x1D5FA, "M", "m"), + (0x1D5FB, "M", "n"), + (0x1D5FC, "M", "o"), + (0x1D5FD, "M", "p"), + (0x1D5FE, "M", "q"), + (0x1D5FF, "M", "r"), + (0x1D600, "M", "s"), + (0x1D601, "M", "t"), + (0x1D602, "M", "u"), + (0x1D603, "M", "v"), + (0x1D604, "M", "w"), + (0x1D605, "M", "x"), + (0x1D606, "M", "y"), + (0x1D607, "M", "z"), + (0x1D608, "M", "a"), + (0x1D609, "M", "b"), + (0x1D60A, "M", "c"), + (0x1D60B, "M", "d"), + (0x1D60C, "M", "e"), + (0x1D60D, "M", "f"), + (0x1D60E, "M", "g"), + (0x1D60F, "M", "h"), + (0x1D610, "M", "i"), + (0x1D611, "M", "j"), + (0x1D612, "M", "k"), + (0x1D613, "M", "l"), + (0x1D614, "M", "m"), + (0x1D615, "M", "n"), + (0x1D616, "M", "o"), + (0x1D617, "M", "p"), + (0x1D618, "M", "q"), + (0x1D619, "M", "r"), + (0x1D61A, "M", "s"), + (0x1D61B, "M", "t"), + (0x1D61C, "M", "u"), + (0x1D61D, "M", "v"), + (0x1D61E, "M", "w"), ] + def _seg_66() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D61B, 'M', 't'), - (0x1D61C, 'M', 'u'), - (0x1D61D, 'M', 'v'), - (0x1D61E, 'M', 'w'), - (0x1D61F, 'M', 'x'), - (0x1D620, 'M', 'y'), - (0x1D621, 'M', 'z'), - (0x1D622, 'M', 'a'), - (0x1D623, 'M', 'b'), - (0x1D624, 'M', 'c'), - (0x1D625, 'M', 'd'), - (0x1D626, 'M', 'e'), - (0x1D627, 'M', 'f'), - (0x1D628, 'M', 'g'), - (0x1D629, 'M', 'h'), - (0x1D62A, 'M', 'i'), - (0x1D62B, 'M', 'j'), - (0x1D62C, 'M', 'k'), - (0x1D62D, 'M', 'l'), - (0x1D62E, 'M', 'm'), - (0x1D62F, 'M', 'n'), - (0x1D630, 'M', 'o'), - (0x1D631, 'M', 'p'), - (0x1D632, 'M', 'q'), - (0x1D633, 'M', 'r'), - (0x1D634, 'M', 's'), - (0x1D635, 'M', 't'), - (0x1D636, 'M', 'u'), - (0x1D637, 'M', 'v'), - (0x1D638, 'M', 'w'), - (0x1D639, 'M', 'x'), - (0x1D63A, 'M', 'y'), - (0x1D63B, 'M', 'z'), - (0x1D63C, 'M', 'a'), - (0x1D63D, 'M', 'b'), - (0x1D63E, 'M', 'c'), - (0x1D63F, 'M', 'd'), - (0x1D640, 'M', 'e'), - (0x1D641, 'M', 'f'), - (0x1D642, 'M', 'g'), - (0x1D643, 'M', 'h'), - (0x1D644, 'M', 'i'), - (0x1D645, 'M', 'j'), - (0x1D646, 'M', 'k'), - (0x1D647, 'M', 'l'), - (0x1D648, 'M', 'm'), - (0x1D649, 'M', 'n'), - (0x1D64A, 'M', 'o'), - (0x1D64B, 'M', 'p'), - (0x1D64C, 'M', 'q'), - (0x1D64D, 'M', 'r'), - (0x1D64E, 'M', 's'), - (0x1D64F, 'M', 't'), - (0x1D650, 'M', 'u'), - (0x1D651, 'M', 'v'), - (0x1D652, 'M', 'w'), - (0x1D653, 'M', 'x'), - (0x1D654, 'M', 'y'), - (0x1D655, 'M', 'z'), - (0x1D656, 'M', 'a'), - (0x1D657, 'M', 'b'), - (0x1D658, 'M', 'c'), - (0x1D659, 'M', 'd'), - (0x1D65A, 'M', 'e'), - (0x1D65B, 'M', 'f'), - (0x1D65C, 'M', 'g'), - (0x1D65D, 'M', 'h'), - (0x1D65E, 'M', 'i'), - (0x1D65F, 'M', 'j'), - (0x1D660, 'M', 'k'), - (0x1D661, 'M', 'l'), - (0x1D662, 'M', 'm'), - (0x1D663, 'M', 'n'), - (0x1D664, 'M', 'o'), - (0x1D665, 'M', 'p'), - (0x1D666, 'M', 'q'), - (0x1D667, 'M', 'r'), - (0x1D668, 'M', 's'), - (0x1D669, 'M', 't'), - (0x1D66A, 'M', 'u'), - (0x1D66B, 'M', 'v'), - (0x1D66C, 'M', 'w'), - (0x1D66D, 'M', 'x'), - (0x1D66E, 'M', 'y'), - (0x1D66F, 'M', 'z'), - (0x1D670, 'M', 'a'), - (0x1D671, 'M', 'b'), - (0x1D672, 'M', 'c'), - (0x1D673, 'M', 'd'), - (0x1D674, 'M', 'e'), - (0x1D675, 'M', 'f'), - (0x1D676, 'M', 'g'), - (0x1D677, 'M', 'h'), - (0x1D678, 'M', 'i'), - (0x1D679, 'M', 'j'), - (0x1D67A, 'M', 'k'), - (0x1D67B, 'M', 'l'), - (0x1D67C, 'M', 'm'), - (0x1D67D, 'M', 'n'), - (0x1D67E, 'M', 'o'), + (0x1D61F, "M", "x"), + (0x1D620, "M", "y"), + (0x1D621, "M", "z"), + (0x1D622, "M", "a"), + (0x1D623, "M", "b"), + (0x1D624, "M", "c"), + (0x1D625, "M", "d"), + (0x1D626, "M", "e"), + (0x1D627, "M", "f"), + (0x1D628, "M", "g"), + (0x1D629, "M", "h"), + (0x1D62A, "M", "i"), + (0x1D62B, "M", "j"), + (0x1D62C, "M", "k"), + (0x1D62D, "M", "l"), + (0x1D62E, "M", "m"), + (0x1D62F, "M", "n"), + (0x1D630, "M", "o"), + (0x1D631, "M", "p"), + (0x1D632, "M", "q"), + (0x1D633, "M", "r"), + (0x1D634, "M", "s"), + (0x1D635, "M", "t"), + (0x1D636, "M", "u"), + (0x1D637, "M", "v"), + (0x1D638, "M", "w"), + (0x1D639, "M", "x"), + (0x1D63A, "M", "y"), + (0x1D63B, "M", "z"), + (0x1D63C, "M", "a"), + (0x1D63D, "M", "b"), + (0x1D63E, "M", "c"), + (0x1D63F, "M", "d"), + (0x1D640, "M", "e"), + (0x1D641, "M", "f"), + (0x1D642, "M", "g"), + (0x1D643, "M", "h"), + (0x1D644, "M", "i"), + (0x1D645, "M", "j"), + (0x1D646, "M", "k"), + (0x1D647, "M", "l"), + (0x1D648, "M", "m"), + (0x1D649, "M", "n"), + (0x1D64A, "M", "o"), + (0x1D64B, "M", "p"), + (0x1D64C, "M", "q"), + (0x1D64D, "M", "r"), + (0x1D64E, "M", "s"), + (0x1D64F, "M", "t"), + (0x1D650, "M", "u"), + (0x1D651, "M", "v"), + (0x1D652, "M", "w"), + (0x1D653, "M", "x"), + (0x1D654, "M", "y"), + (0x1D655, "M", "z"), + (0x1D656, "M", "a"), + (0x1D657, "M", "b"), + (0x1D658, "M", "c"), + (0x1D659, "M", "d"), + (0x1D65A, "M", "e"), + (0x1D65B, "M", "f"), + (0x1D65C, "M", "g"), + (0x1D65D, "M", "h"), + (0x1D65E, "M", "i"), + (0x1D65F, "M", "j"), + (0x1D660, "M", "k"), + (0x1D661, "M", "l"), + (0x1D662, "M", "m"), + (0x1D663, "M", "n"), + (0x1D664, "M", "o"), + (0x1D665, "M", "p"), + (0x1D666, "M", "q"), + (0x1D667, "M", "r"), + (0x1D668, "M", "s"), + (0x1D669, "M", "t"), + (0x1D66A, "M", "u"), + (0x1D66B, "M", "v"), + (0x1D66C, "M", "w"), + (0x1D66D, "M", "x"), + (0x1D66E, "M", "y"), + (0x1D66F, "M", "z"), + (0x1D670, "M", "a"), + (0x1D671, "M", "b"), + (0x1D672, "M", "c"), + (0x1D673, "M", "d"), + (0x1D674, "M", "e"), + (0x1D675, "M", "f"), + (0x1D676, "M", "g"), + (0x1D677, "M", "h"), + (0x1D678, "M", "i"), + (0x1D679, "M", "j"), + (0x1D67A, "M", "k"), + (0x1D67B, "M", "l"), + (0x1D67C, "M", "m"), + (0x1D67D, "M", "n"), + (0x1D67E, "M", "o"), + (0x1D67F, "M", "p"), + (0x1D680, "M", "q"), + (0x1D681, "M", "r"), + (0x1D682, "M", "s"), ] + def _seg_67() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D67F, 'M', 'p'), - (0x1D680, 'M', 'q'), - (0x1D681, 'M', 'r'), - (0x1D682, 'M', 's'), - (0x1D683, 'M', 't'), - (0x1D684, 'M', 'u'), - (0x1D685, 'M', 'v'), - (0x1D686, 'M', 'w'), - (0x1D687, 'M', 'x'), - (0x1D688, 'M', 'y'), - (0x1D689, 'M', 'z'), - (0x1D68A, 'M', 'a'), - (0x1D68B, 'M', 'b'), - (0x1D68C, 'M', 'c'), - (0x1D68D, 'M', 'd'), - (0x1D68E, 'M', 'e'), - (0x1D68F, 'M', 'f'), - (0x1D690, 'M', 'g'), - (0x1D691, 'M', 'h'), - (0x1D692, 'M', 'i'), - (0x1D693, 'M', 'j'), - (0x1D694, 'M', 'k'), - (0x1D695, 'M', 'l'), - (0x1D696, 'M', 'm'), - (0x1D697, 'M', 'n'), - (0x1D698, 'M', 'o'), - (0x1D699, 'M', 'p'), - (0x1D69A, 'M', 'q'), - (0x1D69B, 'M', 'r'), - (0x1D69C, 'M', 's'), - (0x1D69D, 'M', 't'), - (0x1D69E, 'M', 'u'), - (0x1D69F, 'M', 'v'), - (0x1D6A0, 'M', 'w'), - (0x1D6A1, 'M', 'x'), - (0x1D6A2, 'M', 'y'), - (0x1D6A3, 'M', 'z'), - (0x1D6A4, 'M', 'ı'), - (0x1D6A5, 'M', 'Č·'), - (0x1D6A6, 'X'), - (0x1D6A8, 'M', 'α'), - (0x1D6A9, 'M', 'β'), - (0x1D6AA, 'M', 'γ'), - (0x1D6AB, 'M', 'Ī“'), - (0x1D6AC, 'M', 'ε'), - (0x1D6AD, 'M', 'ζ'), - (0x1D6AE, 'M', 'Ī·'), - (0x1D6AF, 'M', 'Īø'), - (0x1D6B0, 'M', 'ι'), - (0x1D6B1, 'M', 'Īŗ'), - (0x1D6B2, 'M', 'Ī»'), - (0x1D6B3, 'M', 'μ'), - (0x1D6B4, 'M', 'ν'), - (0x1D6B5, 'M', 'ξ'), - (0x1D6B6, 'M', 'Īæ'), - (0x1D6B7, 'M', 'Ļ€'), - (0x1D6B8, 'M', 'ρ'), - (0x1D6B9, 'M', 'Īø'), - (0x1D6BA, 'M', 'σ'), - (0x1D6BB, 'M', 'Ļ„'), - (0x1D6BC, 'M', 'Ļ…'), - (0x1D6BD, 'M', 'φ'), - (0x1D6BE, 'M', 'χ'), - (0x1D6BF, 'M', 'ψ'), - (0x1D6C0, 'M', 'ω'), - (0x1D6C1, 'M', 'āˆ‡'), - (0x1D6C2, 'M', 'α'), - (0x1D6C3, 'M', 'β'), - (0x1D6C4, 'M', 'γ'), - (0x1D6C5, 'M', 'Ī“'), - (0x1D6C6, 'M', 'ε'), - (0x1D6C7, 'M', 'ζ'), - (0x1D6C8, 'M', 'Ī·'), - (0x1D6C9, 'M', 'Īø'), - (0x1D6CA, 'M', 'ι'), - (0x1D6CB, 'M', 'Īŗ'), - (0x1D6CC, 'M', 'Ī»'), - (0x1D6CD, 'M', 'μ'), - (0x1D6CE, 'M', 'ν'), - (0x1D6CF, 'M', 'ξ'), - (0x1D6D0, 'M', 'Īæ'), - (0x1D6D1, 'M', 'Ļ€'), - (0x1D6D2, 'M', 'ρ'), - (0x1D6D3, 'M', 'σ'), - (0x1D6D5, 'M', 'Ļ„'), - (0x1D6D6, 'M', 'Ļ…'), - (0x1D6D7, 'M', 'φ'), - (0x1D6D8, 'M', 'χ'), - (0x1D6D9, 'M', 'ψ'), - (0x1D6DA, 'M', 'ω'), - (0x1D6DB, 'M', 'āˆ‚'), - (0x1D6DC, 'M', 'ε'), - (0x1D6DD, 'M', 'Īø'), - (0x1D6DE, 'M', 'Īŗ'), - (0x1D6DF, 'M', 'φ'), - (0x1D6E0, 'M', 'ρ'), - (0x1D6E1, 'M', 'Ļ€'), - (0x1D6E2, 'M', 'α'), - (0x1D6E3, 'M', 'β'), - (0x1D6E4, 'M', 'γ'), + (0x1D683, "M", "t"), + (0x1D684, "M", "u"), + (0x1D685, "M", "v"), + (0x1D686, "M", "w"), + (0x1D687, "M", "x"), + (0x1D688, "M", "y"), + (0x1D689, "M", "z"), + (0x1D68A, "M", "a"), + (0x1D68B, "M", "b"), + (0x1D68C, "M", "c"), + (0x1D68D, "M", "d"), + (0x1D68E, "M", "e"), + (0x1D68F, "M", "f"), + (0x1D690, "M", "g"), + (0x1D691, "M", "h"), + (0x1D692, "M", "i"), + (0x1D693, "M", "j"), + (0x1D694, "M", "k"), + (0x1D695, "M", "l"), + (0x1D696, "M", "m"), + (0x1D697, "M", "n"), + (0x1D698, "M", "o"), + (0x1D699, "M", "p"), + (0x1D69A, "M", "q"), + (0x1D69B, "M", "r"), + (0x1D69C, "M", "s"), + (0x1D69D, "M", "t"), + (0x1D69E, "M", "u"), + (0x1D69F, "M", "v"), + (0x1D6A0, "M", "w"), + (0x1D6A1, "M", "x"), + (0x1D6A2, "M", "y"), + (0x1D6A3, "M", "z"), + (0x1D6A4, "M", "ı"), + (0x1D6A5, "M", "Č·"), + (0x1D6A6, "X"), + (0x1D6A8, "M", "α"), + (0x1D6A9, "M", "β"), + (0x1D6AA, "M", "γ"), + (0x1D6AB, "M", "Ī“"), + (0x1D6AC, "M", "ε"), + (0x1D6AD, "M", "ζ"), + (0x1D6AE, "M", "Ī·"), + (0x1D6AF, "M", "Īø"), + (0x1D6B0, "M", "ι"), + (0x1D6B1, "M", "Īŗ"), + (0x1D6B2, "M", "Ī»"), + (0x1D6B3, "M", "μ"), + (0x1D6B4, "M", "ν"), + (0x1D6B5, "M", "ξ"), + (0x1D6B6, "M", "Īæ"), + (0x1D6B7, "M", "Ļ€"), + (0x1D6B8, "M", "ρ"), + (0x1D6B9, "M", "Īø"), + (0x1D6BA, "M", "σ"), + (0x1D6BB, "M", "Ļ„"), + (0x1D6BC, "M", "Ļ…"), + (0x1D6BD, "M", "φ"), + (0x1D6BE, "M", "χ"), + (0x1D6BF, "M", "ψ"), + (0x1D6C0, "M", "ω"), + (0x1D6C1, "M", "āˆ‡"), + (0x1D6C2, "M", "α"), + (0x1D6C3, "M", "β"), + (0x1D6C4, "M", "γ"), + (0x1D6C5, "M", "Ī“"), + (0x1D6C6, "M", "ε"), + (0x1D6C7, "M", "ζ"), + (0x1D6C8, "M", "Ī·"), + (0x1D6C9, "M", "Īø"), + (0x1D6CA, "M", "ι"), + (0x1D6CB, "M", "Īŗ"), + (0x1D6CC, "M", "Ī»"), + (0x1D6CD, "M", "μ"), + (0x1D6CE, "M", "ν"), + (0x1D6CF, "M", "ξ"), + (0x1D6D0, "M", "Īæ"), + (0x1D6D1, "M", "Ļ€"), + (0x1D6D2, "M", "ρ"), + (0x1D6D3, "M", "σ"), + (0x1D6D5, "M", "Ļ„"), + (0x1D6D6, "M", "Ļ…"), + (0x1D6D7, "M", "φ"), + (0x1D6D8, "M", "χ"), + (0x1D6D9, "M", "ψ"), + (0x1D6DA, "M", "ω"), + (0x1D6DB, "M", "āˆ‚"), + (0x1D6DC, "M", "ε"), + (0x1D6DD, "M", "Īø"), + (0x1D6DE, "M", "Īŗ"), + (0x1D6DF, "M", "φ"), + (0x1D6E0, "M", "ρ"), + (0x1D6E1, "M", "Ļ€"), + (0x1D6E2, "M", "α"), + (0x1D6E3, "M", "β"), + (0x1D6E4, "M", "γ"), + (0x1D6E5, "M", "Ī“"), + (0x1D6E6, "M", "ε"), + (0x1D6E7, "M", "ζ"), + (0x1D6E8, "M", "Ī·"), ] + def _seg_68() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D6E5, 'M', 'Ī“'), - (0x1D6E6, 'M', 'ε'), - (0x1D6E7, 'M', 'ζ'), - (0x1D6E8, 'M', 'Ī·'), - (0x1D6E9, 'M', 'Īø'), - (0x1D6EA, 'M', 'ι'), - (0x1D6EB, 'M', 'Īŗ'), - (0x1D6EC, 'M', 'Ī»'), - (0x1D6ED, 'M', 'μ'), - (0x1D6EE, 'M', 'ν'), - (0x1D6EF, 'M', 'ξ'), - (0x1D6F0, 'M', 'Īæ'), - (0x1D6F1, 'M', 'Ļ€'), - (0x1D6F2, 'M', 'ρ'), - (0x1D6F3, 'M', 'Īø'), - (0x1D6F4, 'M', 'σ'), - (0x1D6F5, 'M', 'Ļ„'), - (0x1D6F6, 'M', 'Ļ…'), - (0x1D6F7, 'M', 'φ'), - (0x1D6F8, 'M', 'χ'), - (0x1D6F9, 'M', 'ψ'), - (0x1D6FA, 'M', 'ω'), - (0x1D6FB, 'M', 'āˆ‡'), - (0x1D6FC, 'M', 'α'), - (0x1D6FD, 'M', 'β'), - (0x1D6FE, 'M', 'γ'), - (0x1D6FF, 'M', 'Ī“'), - (0x1D700, 'M', 'ε'), - (0x1D701, 'M', 'ζ'), - (0x1D702, 'M', 'Ī·'), - (0x1D703, 'M', 'Īø'), - (0x1D704, 'M', 'ι'), - (0x1D705, 'M', 'Īŗ'), - (0x1D706, 'M', 'Ī»'), - (0x1D707, 'M', 'μ'), - (0x1D708, 'M', 'ν'), - (0x1D709, 'M', 'ξ'), - (0x1D70A, 'M', 'Īæ'), - (0x1D70B, 'M', 'Ļ€'), - (0x1D70C, 'M', 'ρ'), - (0x1D70D, 'M', 'σ'), - (0x1D70F, 'M', 'Ļ„'), - (0x1D710, 'M', 'Ļ…'), - (0x1D711, 'M', 'φ'), - (0x1D712, 'M', 'χ'), - (0x1D713, 'M', 'ψ'), - (0x1D714, 'M', 'ω'), - (0x1D715, 'M', 'āˆ‚'), - (0x1D716, 'M', 'ε'), - (0x1D717, 'M', 'Īø'), - (0x1D718, 'M', 'Īŗ'), - (0x1D719, 'M', 'φ'), - (0x1D71A, 'M', 'ρ'), - (0x1D71B, 'M', 'Ļ€'), - (0x1D71C, 'M', 'α'), - (0x1D71D, 'M', 'β'), - (0x1D71E, 'M', 'γ'), - (0x1D71F, 'M', 'Ī“'), - (0x1D720, 'M', 'ε'), - (0x1D721, 'M', 'ζ'), - (0x1D722, 'M', 'Ī·'), - (0x1D723, 'M', 'Īø'), - (0x1D724, 'M', 'ι'), - (0x1D725, 'M', 'Īŗ'), - (0x1D726, 'M', 'Ī»'), - (0x1D727, 'M', 'μ'), - (0x1D728, 'M', 'ν'), - (0x1D729, 'M', 'ξ'), - (0x1D72A, 'M', 'Īæ'), - (0x1D72B, 'M', 'Ļ€'), - (0x1D72C, 'M', 'ρ'), - (0x1D72D, 'M', 'Īø'), - (0x1D72E, 'M', 'σ'), - (0x1D72F, 'M', 'Ļ„'), - (0x1D730, 'M', 'Ļ…'), - (0x1D731, 'M', 'φ'), - (0x1D732, 'M', 'χ'), - (0x1D733, 'M', 'ψ'), - (0x1D734, 'M', 'ω'), - (0x1D735, 'M', 'āˆ‡'), - (0x1D736, 'M', 'α'), - (0x1D737, 'M', 'β'), - (0x1D738, 'M', 'γ'), - (0x1D739, 'M', 'Ī“'), - (0x1D73A, 'M', 'ε'), - (0x1D73B, 'M', 'ζ'), - (0x1D73C, 'M', 'Ī·'), - (0x1D73D, 'M', 'Īø'), - (0x1D73E, 'M', 'ι'), - (0x1D73F, 'M', 'Īŗ'), - (0x1D740, 'M', 'Ī»'), - (0x1D741, 'M', 'μ'), - (0x1D742, 'M', 'ν'), - (0x1D743, 'M', 'ξ'), - (0x1D744, 'M', 'Īæ'), - (0x1D745, 'M', 'Ļ€'), - (0x1D746, 'M', 'ρ'), - (0x1D747, 'M', 'σ'), - (0x1D749, 'M', 'Ļ„'), - (0x1D74A, 'M', 'Ļ…'), + (0x1D6E9, "M", "Īø"), + (0x1D6EA, "M", "ι"), + (0x1D6EB, "M", "Īŗ"), + (0x1D6EC, "M", "Ī»"), + (0x1D6ED, "M", "μ"), + (0x1D6EE, "M", "ν"), + (0x1D6EF, "M", "ξ"), + (0x1D6F0, "M", "Īæ"), + (0x1D6F1, "M", "Ļ€"), + (0x1D6F2, "M", "ρ"), + (0x1D6F3, "M", "Īø"), + (0x1D6F4, "M", "σ"), + (0x1D6F5, "M", "Ļ„"), + (0x1D6F6, "M", "Ļ…"), + (0x1D6F7, "M", "φ"), + (0x1D6F8, "M", "χ"), + (0x1D6F9, "M", "ψ"), + (0x1D6FA, "M", "ω"), + (0x1D6FB, "M", "āˆ‡"), + (0x1D6FC, "M", "α"), + (0x1D6FD, "M", "β"), + (0x1D6FE, "M", "γ"), + (0x1D6FF, "M", "Ī“"), + (0x1D700, "M", "ε"), + (0x1D701, "M", "ζ"), + (0x1D702, "M", "Ī·"), + (0x1D703, "M", "Īø"), + (0x1D704, "M", "ι"), + (0x1D705, "M", "Īŗ"), + (0x1D706, "M", "Ī»"), + (0x1D707, "M", "μ"), + (0x1D708, "M", "ν"), + (0x1D709, "M", "ξ"), + (0x1D70A, "M", "Īæ"), + (0x1D70B, "M", "Ļ€"), + (0x1D70C, "M", "ρ"), + (0x1D70D, "M", "σ"), + (0x1D70F, "M", "Ļ„"), + (0x1D710, "M", "Ļ…"), + (0x1D711, "M", "φ"), + (0x1D712, "M", "χ"), + (0x1D713, "M", "ψ"), + (0x1D714, "M", "ω"), + (0x1D715, "M", "āˆ‚"), + (0x1D716, "M", "ε"), + (0x1D717, "M", "Īø"), + (0x1D718, "M", "Īŗ"), + (0x1D719, "M", "φ"), + (0x1D71A, "M", "ρ"), + (0x1D71B, "M", "Ļ€"), + (0x1D71C, "M", "α"), + (0x1D71D, "M", "β"), + (0x1D71E, "M", "γ"), + (0x1D71F, "M", "Ī“"), + (0x1D720, "M", "ε"), + (0x1D721, "M", "ζ"), + (0x1D722, "M", "Ī·"), + (0x1D723, "M", "Īø"), + (0x1D724, "M", "ι"), + (0x1D725, "M", "Īŗ"), + (0x1D726, "M", "Ī»"), + (0x1D727, "M", "μ"), + (0x1D728, "M", "ν"), + (0x1D729, "M", "ξ"), + (0x1D72A, "M", "Īæ"), + (0x1D72B, "M", "Ļ€"), + (0x1D72C, "M", "ρ"), + (0x1D72D, "M", "Īø"), + (0x1D72E, "M", "σ"), + (0x1D72F, "M", "Ļ„"), + (0x1D730, "M", "Ļ…"), + (0x1D731, "M", "φ"), + (0x1D732, "M", "χ"), + (0x1D733, "M", "ψ"), + (0x1D734, "M", "ω"), + (0x1D735, "M", "āˆ‡"), + (0x1D736, "M", "α"), + (0x1D737, "M", "β"), + (0x1D738, "M", "γ"), + (0x1D739, "M", "Ī“"), + (0x1D73A, "M", "ε"), + (0x1D73B, "M", "ζ"), + (0x1D73C, "M", "Ī·"), + (0x1D73D, "M", "Īø"), + (0x1D73E, "M", "ι"), + (0x1D73F, "M", "Īŗ"), + (0x1D740, "M", "Ī»"), + (0x1D741, "M", "μ"), + (0x1D742, "M", "ν"), + (0x1D743, "M", "ξ"), + (0x1D744, "M", "Īæ"), + (0x1D745, "M", "Ļ€"), + (0x1D746, "M", "ρ"), + (0x1D747, "M", "σ"), + (0x1D749, "M", "Ļ„"), + (0x1D74A, "M", "Ļ…"), + (0x1D74B, "M", "φ"), + (0x1D74C, "M", "χ"), + (0x1D74D, "M", "ψ"), + (0x1D74E, "M", "ω"), ] + def _seg_69() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D74B, 'M', 'φ'), - (0x1D74C, 'M', 'χ'), - (0x1D74D, 'M', 'ψ'), - (0x1D74E, 'M', 'ω'), - (0x1D74F, 'M', 'āˆ‚'), - (0x1D750, 'M', 'ε'), - (0x1D751, 'M', 'Īø'), - (0x1D752, 'M', 'Īŗ'), - (0x1D753, 'M', 'φ'), - (0x1D754, 'M', 'ρ'), - (0x1D755, 'M', 'Ļ€'), - (0x1D756, 'M', 'α'), - (0x1D757, 'M', 'β'), - (0x1D758, 'M', 'γ'), - (0x1D759, 'M', 'Ī“'), - (0x1D75A, 'M', 'ε'), - (0x1D75B, 'M', 'ζ'), - (0x1D75C, 'M', 'Ī·'), - (0x1D75D, 'M', 'Īø'), - (0x1D75E, 'M', 'ι'), - (0x1D75F, 'M', 'Īŗ'), - (0x1D760, 'M', 'Ī»'), - (0x1D761, 'M', 'μ'), - (0x1D762, 'M', 'ν'), - (0x1D763, 'M', 'ξ'), - (0x1D764, 'M', 'Īæ'), - (0x1D765, 'M', 'Ļ€'), - (0x1D766, 'M', 'ρ'), - (0x1D767, 'M', 'Īø'), - (0x1D768, 'M', 'σ'), - (0x1D769, 'M', 'Ļ„'), - (0x1D76A, 'M', 'Ļ…'), - (0x1D76B, 'M', 'φ'), - (0x1D76C, 'M', 'χ'), - (0x1D76D, 'M', 'ψ'), - (0x1D76E, 'M', 'ω'), - (0x1D76F, 'M', 'āˆ‡'), - (0x1D770, 'M', 'α'), - (0x1D771, 'M', 'β'), - (0x1D772, 'M', 'γ'), - (0x1D773, 'M', 'Ī“'), - (0x1D774, 'M', 'ε'), - (0x1D775, 'M', 'ζ'), - (0x1D776, 'M', 'Ī·'), - (0x1D777, 'M', 'Īø'), - (0x1D778, 'M', 'ι'), - (0x1D779, 'M', 'Īŗ'), - (0x1D77A, 'M', 'Ī»'), - (0x1D77B, 'M', 'μ'), - (0x1D77C, 'M', 'ν'), - (0x1D77D, 'M', 'ξ'), - (0x1D77E, 'M', 'Īæ'), - (0x1D77F, 'M', 'Ļ€'), - (0x1D780, 'M', 'ρ'), - (0x1D781, 'M', 'σ'), - (0x1D783, 'M', 'Ļ„'), - (0x1D784, 'M', 'Ļ…'), - (0x1D785, 'M', 'φ'), - (0x1D786, 'M', 'χ'), - (0x1D787, 'M', 'ψ'), - (0x1D788, 'M', 'ω'), - (0x1D789, 'M', 'āˆ‚'), - (0x1D78A, 'M', 'ε'), - (0x1D78B, 'M', 'Īø'), - (0x1D78C, 'M', 'Īŗ'), - (0x1D78D, 'M', 'φ'), - (0x1D78E, 'M', 'ρ'), - (0x1D78F, 'M', 'Ļ€'), - (0x1D790, 'M', 'α'), - (0x1D791, 'M', 'β'), - (0x1D792, 'M', 'γ'), - (0x1D793, 'M', 'Ī“'), - (0x1D794, 'M', 'ε'), - (0x1D795, 'M', 'ζ'), - (0x1D796, 'M', 'Ī·'), - (0x1D797, 'M', 'Īø'), - (0x1D798, 'M', 'ι'), - (0x1D799, 'M', 'Īŗ'), - (0x1D79A, 'M', 'Ī»'), - (0x1D79B, 'M', 'μ'), - (0x1D79C, 'M', 'ν'), - (0x1D79D, 'M', 'ξ'), - (0x1D79E, 'M', 'Īæ'), - (0x1D79F, 'M', 'Ļ€'), - (0x1D7A0, 'M', 'ρ'), - (0x1D7A1, 'M', 'Īø'), - (0x1D7A2, 'M', 'σ'), - (0x1D7A3, 'M', 'Ļ„'), - (0x1D7A4, 'M', 'Ļ…'), - (0x1D7A5, 'M', 'φ'), - (0x1D7A6, 'M', 'χ'), - (0x1D7A7, 'M', 'ψ'), - (0x1D7A8, 'M', 'ω'), - (0x1D7A9, 'M', 'āˆ‡'), - (0x1D7AA, 'M', 'α'), - (0x1D7AB, 'M', 'β'), - (0x1D7AC, 'M', 'γ'), - (0x1D7AD, 'M', 'Ī“'), - (0x1D7AE, 'M', 'ε'), - (0x1D7AF, 'M', 'ζ'), + (0x1D74F, "M", "āˆ‚"), + (0x1D750, "M", "ε"), + (0x1D751, "M", "Īø"), + (0x1D752, "M", "Īŗ"), + (0x1D753, "M", "φ"), + (0x1D754, "M", "ρ"), + (0x1D755, "M", "Ļ€"), + (0x1D756, "M", "α"), + (0x1D757, "M", "β"), + (0x1D758, "M", "γ"), + (0x1D759, "M", "Ī“"), + (0x1D75A, "M", "ε"), + (0x1D75B, "M", "ζ"), + (0x1D75C, "M", "Ī·"), + (0x1D75D, "M", "Īø"), + (0x1D75E, "M", "ι"), + (0x1D75F, "M", "Īŗ"), + (0x1D760, "M", "Ī»"), + (0x1D761, "M", "μ"), + (0x1D762, "M", "ν"), + (0x1D763, "M", "ξ"), + (0x1D764, "M", "Īæ"), + (0x1D765, "M", "Ļ€"), + (0x1D766, "M", "ρ"), + (0x1D767, "M", "Īø"), + (0x1D768, "M", "σ"), + (0x1D769, "M", "Ļ„"), + (0x1D76A, "M", "Ļ…"), + (0x1D76B, "M", "φ"), + (0x1D76C, "M", "χ"), + (0x1D76D, "M", "ψ"), + (0x1D76E, "M", "ω"), + (0x1D76F, "M", "āˆ‡"), + (0x1D770, "M", "α"), + (0x1D771, "M", "β"), + (0x1D772, "M", "γ"), + (0x1D773, "M", "Ī“"), + (0x1D774, "M", "ε"), + (0x1D775, "M", "ζ"), + (0x1D776, "M", "Ī·"), + (0x1D777, "M", "Īø"), + (0x1D778, "M", "ι"), + (0x1D779, "M", "Īŗ"), + (0x1D77A, "M", "Ī»"), + (0x1D77B, "M", "μ"), + (0x1D77C, "M", "ν"), + (0x1D77D, "M", "ξ"), + (0x1D77E, "M", "Īæ"), + (0x1D77F, "M", "Ļ€"), + (0x1D780, "M", "ρ"), + (0x1D781, "M", "σ"), + (0x1D783, "M", "Ļ„"), + (0x1D784, "M", "Ļ…"), + (0x1D785, "M", "φ"), + (0x1D786, "M", "χ"), + (0x1D787, "M", "ψ"), + (0x1D788, "M", "ω"), + (0x1D789, "M", "āˆ‚"), + (0x1D78A, "M", "ε"), + (0x1D78B, "M", "Īø"), + (0x1D78C, "M", "Īŗ"), + (0x1D78D, "M", "φ"), + (0x1D78E, "M", "ρ"), + (0x1D78F, "M", "Ļ€"), + (0x1D790, "M", "α"), + (0x1D791, "M", "β"), + (0x1D792, "M", "γ"), + (0x1D793, "M", "Ī“"), + (0x1D794, "M", "ε"), + (0x1D795, "M", "ζ"), + (0x1D796, "M", "Ī·"), + (0x1D797, "M", "Īø"), + (0x1D798, "M", "ι"), + (0x1D799, "M", "Īŗ"), + (0x1D79A, "M", "Ī»"), + (0x1D79B, "M", "μ"), + (0x1D79C, "M", "ν"), + (0x1D79D, "M", "ξ"), + (0x1D79E, "M", "Īæ"), + (0x1D79F, "M", "Ļ€"), + (0x1D7A0, "M", "ρ"), + (0x1D7A1, "M", "Īø"), + (0x1D7A2, "M", "σ"), + (0x1D7A3, "M", "Ļ„"), + (0x1D7A4, "M", "Ļ…"), + (0x1D7A5, "M", "φ"), + (0x1D7A6, "M", "χ"), + (0x1D7A7, "M", "ψ"), + (0x1D7A8, "M", "ω"), + (0x1D7A9, "M", "āˆ‡"), + (0x1D7AA, "M", "α"), + (0x1D7AB, "M", "β"), + (0x1D7AC, "M", "γ"), + (0x1D7AD, "M", "Ī“"), + (0x1D7AE, "M", "ε"), + (0x1D7AF, "M", "ζ"), + (0x1D7B0, "M", "Ī·"), + (0x1D7B1, "M", "Īø"), + (0x1D7B2, "M", "ι"), + (0x1D7B3, "M", "Īŗ"), ] + def _seg_70() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1D7B0, 'M', 'Ī·'), - (0x1D7B1, 'M', 'Īø'), - (0x1D7B2, 'M', 'ι'), - (0x1D7B3, 'M', 'Īŗ'), - (0x1D7B4, 'M', 'Ī»'), - (0x1D7B5, 'M', 'μ'), - (0x1D7B6, 'M', 'ν'), - (0x1D7B7, 'M', 'ξ'), - (0x1D7B8, 'M', 'Īæ'), - (0x1D7B9, 'M', 'Ļ€'), - (0x1D7BA, 'M', 'ρ'), - (0x1D7BB, 'M', 'σ'), - (0x1D7BD, 'M', 'Ļ„'), - (0x1D7BE, 'M', 'Ļ…'), - (0x1D7BF, 'M', 'φ'), - (0x1D7C0, 'M', 'χ'), - (0x1D7C1, 'M', 'ψ'), - (0x1D7C2, 'M', 'ω'), - (0x1D7C3, 'M', 'āˆ‚'), - (0x1D7C4, 'M', 'ε'), - (0x1D7C5, 'M', 'Īø'), - (0x1D7C6, 'M', 'Īŗ'), - (0x1D7C7, 'M', 'φ'), - (0x1D7C8, 'M', 'ρ'), - (0x1D7C9, 'M', 'Ļ€'), - (0x1D7CA, 'M', 'Ļ'), - (0x1D7CC, 'X'), - (0x1D7CE, 'M', '0'), - (0x1D7CF, 'M', '1'), - (0x1D7D0, 'M', '2'), - (0x1D7D1, 'M', '3'), - (0x1D7D2, 'M', '4'), - (0x1D7D3, 'M', '5'), - (0x1D7D4, 'M', '6'), - (0x1D7D5, 'M', '7'), - (0x1D7D6, 'M', '8'), - (0x1D7D7, 'M', '9'), - (0x1D7D8, 'M', '0'), - (0x1D7D9, 'M', '1'), - (0x1D7DA, 'M', '2'), - (0x1D7DB, 'M', '3'), - (0x1D7DC, 'M', '4'), - (0x1D7DD, 'M', '5'), - (0x1D7DE, 'M', '6'), - (0x1D7DF, 'M', '7'), - (0x1D7E0, 'M', '8'), - (0x1D7E1, 'M', '9'), - (0x1D7E2, 'M', '0'), - (0x1D7E3, 'M', '1'), - (0x1D7E4, 'M', '2'), - (0x1D7E5, 'M', '3'), - (0x1D7E6, 'M', '4'), - (0x1D7E7, 'M', '5'), - (0x1D7E8, 'M', '6'), - (0x1D7E9, 'M', '7'), - (0x1D7EA, 'M', '8'), - (0x1D7EB, 'M', '9'), - (0x1D7EC, 'M', '0'), - (0x1D7ED, 'M', '1'), - (0x1D7EE, 'M', '2'), - (0x1D7EF, 'M', '3'), - (0x1D7F0, 'M', '4'), - (0x1D7F1, 'M', '5'), - (0x1D7F2, 'M', '6'), - (0x1D7F3, 'M', '7'), - (0x1D7F4, 'M', '8'), - (0x1D7F5, 'M', '9'), - (0x1D7F6, 'M', '0'), - (0x1D7F7, 'M', '1'), - (0x1D7F8, 'M', '2'), - (0x1D7F9, 'M', '3'), - (0x1D7FA, 'M', '4'), - (0x1D7FB, 'M', '5'), - (0x1D7FC, 'M', '6'), - (0x1D7FD, 'M', '7'), - (0x1D7FE, 'M', '8'), - (0x1D7FF, 'M', '9'), - (0x1D800, 'V'), - (0x1DA8C, 'X'), - (0x1DA9B, 'V'), - (0x1DAA0, 'X'), - (0x1DAA1, 'V'), - (0x1DAB0, 'X'), - (0x1DF00, 'V'), - (0x1DF1F, 'X'), - (0x1DF25, 'V'), - (0x1DF2B, 'X'), - (0x1E000, 'V'), - (0x1E007, 'X'), - (0x1E008, 'V'), - (0x1E019, 'X'), - (0x1E01B, 'V'), - (0x1E022, 'X'), - (0x1E023, 'V'), - (0x1E025, 'X'), - (0x1E026, 'V'), - (0x1E02B, 'X'), - (0x1E030, 'M', 'а'), - (0x1E031, 'M', 'б'), - (0x1E032, 'M', 'в'), + (0x1D7B4, "M", "Ī»"), + (0x1D7B5, "M", "μ"), + (0x1D7B6, "M", "ν"), + (0x1D7B7, "M", "ξ"), + (0x1D7B8, "M", "Īæ"), + (0x1D7B9, "M", "Ļ€"), + (0x1D7BA, "M", "ρ"), + (0x1D7BB, "M", "σ"), + (0x1D7BD, "M", "Ļ„"), + (0x1D7BE, "M", "Ļ…"), + (0x1D7BF, "M", "φ"), + (0x1D7C0, "M", "χ"), + (0x1D7C1, "M", "ψ"), + (0x1D7C2, "M", "ω"), + (0x1D7C3, "M", "āˆ‚"), + (0x1D7C4, "M", "ε"), + (0x1D7C5, "M", "Īø"), + (0x1D7C6, "M", "Īŗ"), + (0x1D7C7, "M", "φ"), + (0x1D7C8, "M", "ρ"), + (0x1D7C9, "M", "Ļ€"), + (0x1D7CA, "M", "Ļ"), + (0x1D7CC, "X"), + (0x1D7CE, "M", "0"), + (0x1D7CF, "M", "1"), + (0x1D7D0, "M", "2"), + (0x1D7D1, "M", "3"), + (0x1D7D2, "M", "4"), + (0x1D7D3, "M", "5"), + (0x1D7D4, "M", "6"), + (0x1D7D5, "M", "7"), + (0x1D7D6, "M", "8"), + (0x1D7D7, "M", "9"), + (0x1D7D8, "M", "0"), + (0x1D7D9, "M", "1"), + (0x1D7DA, "M", "2"), + (0x1D7DB, "M", "3"), + (0x1D7DC, "M", "4"), + (0x1D7DD, "M", "5"), + (0x1D7DE, "M", "6"), + (0x1D7DF, "M", "7"), + (0x1D7E0, "M", "8"), + (0x1D7E1, "M", "9"), + (0x1D7E2, "M", "0"), + (0x1D7E3, "M", "1"), + (0x1D7E4, "M", "2"), + (0x1D7E5, "M", "3"), + (0x1D7E6, "M", "4"), + (0x1D7E7, "M", "5"), + (0x1D7E8, "M", "6"), + (0x1D7E9, "M", "7"), + (0x1D7EA, "M", "8"), + (0x1D7EB, "M", "9"), + (0x1D7EC, "M", "0"), + (0x1D7ED, "M", "1"), + (0x1D7EE, "M", "2"), + (0x1D7EF, "M", "3"), + (0x1D7F0, "M", "4"), + (0x1D7F1, "M", "5"), + (0x1D7F2, "M", "6"), + (0x1D7F3, "M", "7"), + (0x1D7F4, "M", "8"), + (0x1D7F5, "M", "9"), + (0x1D7F6, "M", "0"), + (0x1D7F7, "M", "1"), + (0x1D7F8, "M", "2"), + (0x1D7F9, "M", "3"), + (0x1D7FA, "M", "4"), + (0x1D7FB, "M", "5"), + (0x1D7FC, "M", "6"), + (0x1D7FD, "M", "7"), + (0x1D7FE, "M", "8"), + (0x1D7FF, "M", "9"), + (0x1D800, "V"), + (0x1DA8C, "X"), + (0x1DA9B, "V"), + (0x1DAA0, "X"), + (0x1DAA1, "V"), + (0x1DAB0, "X"), + (0x1DF00, "V"), + (0x1DF1F, "X"), + (0x1DF25, "V"), + (0x1DF2B, "X"), + (0x1E000, "V"), + (0x1E007, "X"), + (0x1E008, "V"), + (0x1E019, "X"), + (0x1E01B, "V"), + (0x1E022, "X"), + (0x1E023, "V"), + (0x1E025, "X"), + (0x1E026, "V"), + (0x1E02B, "X"), + (0x1E030, "M", "а"), + (0x1E031, "M", "б"), + (0x1E032, "M", "в"), + (0x1E033, "M", "г"), + (0x1E034, "M", "Š“"), + (0x1E035, "M", "е"), + (0x1E036, "M", "ж"), ] + def _seg_71() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1E033, 'M', 'г'), - (0x1E034, 'M', 'Š“'), - (0x1E035, 'M', 'е'), - (0x1E036, 'M', 'ж'), - (0x1E037, 'M', 'Š·'), - (0x1E038, 'M', 'Šø'), - (0x1E039, 'M', 'Šŗ'), - (0x1E03A, 'M', 'Š»'), - (0x1E03B, 'M', 'м'), - (0x1E03C, 'M', 'о'), - (0x1E03D, 'M', 'Šæ'), - (0x1E03E, 'M', 'р'), - (0x1E03F, 'M', 'с'), - (0x1E040, 'M', 'т'), - (0x1E041, 'M', 'у'), - (0x1E042, 'M', 'ф'), - (0x1E043, 'M', 'х'), - (0x1E044, 'M', 'ц'), - (0x1E045, 'M', 'ч'), - (0x1E046, 'M', 'ш'), - (0x1E047, 'M', 'ы'), - (0x1E048, 'M', 'э'), - (0x1E049, 'M', 'ю'), - (0x1E04A, 'M', 'źš‰'), - (0x1E04B, 'M', 'ә'), - (0x1E04C, 'M', 'і'), - (0x1E04D, 'M', 'ј'), - (0x1E04E, 'M', 'Ó©'), - (0x1E04F, 'M', 'ŅÆ'), - (0x1E050, 'M', 'ӏ'), - (0x1E051, 'M', 'а'), - (0x1E052, 'M', 'б'), - (0x1E053, 'M', 'в'), - (0x1E054, 'M', 'г'), - (0x1E055, 'M', 'Š“'), - (0x1E056, 'M', 'е'), - (0x1E057, 'M', 'ж'), - (0x1E058, 'M', 'Š·'), - (0x1E059, 'M', 'Šø'), - (0x1E05A, 'M', 'Šŗ'), - (0x1E05B, 'M', 'Š»'), - (0x1E05C, 'M', 'о'), - (0x1E05D, 'M', 'Šæ'), - (0x1E05E, 'M', 'с'), - (0x1E05F, 'M', 'у'), - (0x1E060, 'M', 'ф'), - (0x1E061, 'M', 'х'), - (0x1E062, 'M', 'ц'), - (0x1E063, 'M', 'ч'), - (0x1E064, 'M', 'ш'), - (0x1E065, 'M', 'ъ'), - (0x1E066, 'M', 'ы'), - (0x1E067, 'M', 'Ņ‘'), - (0x1E068, 'M', 'і'), - (0x1E069, 'M', 'ѕ'), - (0x1E06A, 'M', 'џ'), - (0x1E06B, 'M', 'Ņ«'), - (0x1E06C, 'M', 'ꙑ'), - (0x1E06D, 'M', 'ұ'), - (0x1E06E, 'X'), - (0x1E08F, 'V'), - (0x1E090, 'X'), - (0x1E100, 'V'), - (0x1E12D, 'X'), - (0x1E130, 'V'), - (0x1E13E, 'X'), - (0x1E140, 'V'), - (0x1E14A, 'X'), - (0x1E14E, 'V'), - (0x1E150, 'X'), - (0x1E290, 'V'), - (0x1E2AF, 'X'), - (0x1E2C0, 'V'), - (0x1E2FA, 'X'), - (0x1E2FF, 'V'), - (0x1E300, 'X'), - (0x1E4D0, 'V'), - (0x1E4FA, 'X'), - (0x1E7E0, 'V'), - (0x1E7E7, 'X'), - (0x1E7E8, 'V'), - (0x1E7EC, 'X'), - (0x1E7ED, 'V'), - (0x1E7EF, 'X'), - (0x1E7F0, 'V'), - (0x1E7FF, 'X'), - (0x1E800, 'V'), - (0x1E8C5, 'X'), - (0x1E8C7, 'V'), - (0x1E8D7, 'X'), - (0x1E900, 'M', 'šž¤¢'), - (0x1E901, 'M', 'šž¤£'), - (0x1E902, 'M', 'šž¤¤'), - (0x1E903, 'M', 'šž¤„'), - (0x1E904, 'M', 'šž¤¦'), - (0x1E905, 'M', 'šž¤§'), - (0x1E906, 'M', 'šž¤Ø'), - (0x1E907, 'M', 'šž¤©'), - (0x1E908, 'M', 'šž¤Ŗ'), - (0x1E909, 'M', 'šž¤«'), + (0x1E037, "M", "Š·"), + (0x1E038, "M", "Šø"), + (0x1E039, "M", "Šŗ"), + (0x1E03A, "M", "Š»"), + (0x1E03B, "M", "м"), + (0x1E03C, "M", "о"), + (0x1E03D, "M", "Šæ"), + (0x1E03E, "M", "р"), + (0x1E03F, "M", "с"), + (0x1E040, "M", "т"), + (0x1E041, "M", "у"), + (0x1E042, "M", "ф"), + (0x1E043, "M", "х"), + (0x1E044, "M", "ц"), + (0x1E045, "M", "ч"), + (0x1E046, "M", "ш"), + (0x1E047, "M", "ы"), + (0x1E048, "M", "э"), + (0x1E049, "M", "ю"), + (0x1E04A, "M", "źš‰"), + (0x1E04B, "M", "ә"), + (0x1E04C, "M", "і"), + (0x1E04D, "M", "ј"), + (0x1E04E, "M", "Ó©"), + (0x1E04F, "M", "ŅÆ"), + (0x1E050, "M", "ӏ"), + (0x1E051, "M", "а"), + (0x1E052, "M", "б"), + (0x1E053, "M", "в"), + (0x1E054, "M", "г"), + (0x1E055, "M", "Š“"), + (0x1E056, "M", "е"), + (0x1E057, "M", "ж"), + (0x1E058, "M", "Š·"), + (0x1E059, "M", "Šø"), + (0x1E05A, "M", "Šŗ"), + (0x1E05B, "M", "Š»"), + (0x1E05C, "M", "о"), + (0x1E05D, "M", "Šæ"), + (0x1E05E, "M", "с"), + (0x1E05F, "M", "у"), + (0x1E060, "M", "ф"), + (0x1E061, "M", "х"), + (0x1E062, "M", "ц"), + (0x1E063, "M", "ч"), + (0x1E064, "M", "ш"), + (0x1E065, "M", "ъ"), + (0x1E066, "M", "ы"), + (0x1E067, "M", "Ņ‘"), + (0x1E068, "M", "і"), + (0x1E069, "M", "ѕ"), + (0x1E06A, "M", "џ"), + (0x1E06B, "M", "Ņ«"), + (0x1E06C, "M", "ꙑ"), + (0x1E06D, "M", "ұ"), + (0x1E06E, "X"), + (0x1E08F, "V"), + (0x1E090, "X"), + (0x1E100, "V"), + (0x1E12D, "X"), + (0x1E130, "V"), + (0x1E13E, "X"), + (0x1E140, "V"), + (0x1E14A, "X"), + (0x1E14E, "V"), + (0x1E150, "X"), + (0x1E290, "V"), + (0x1E2AF, "X"), + (0x1E2C0, "V"), + (0x1E2FA, "X"), + (0x1E2FF, "V"), + (0x1E300, "X"), + (0x1E4D0, "V"), + (0x1E4FA, "X"), + (0x1E7E0, "V"), + (0x1E7E7, "X"), + (0x1E7E8, "V"), + (0x1E7EC, "X"), + (0x1E7ED, "V"), + (0x1E7EF, "X"), + (0x1E7F0, "V"), + (0x1E7FF, "X"), + (0x1E800, "V"), + (0x1E8C5, "X"), + (0x1E8C7, "V"), + (0x1E8D7, "X"), + (0x1E900, "M", "šž¤¢"), + (0x1E901, "M", "šž¤£"), + (0x1E902, "M", "šž¤¤"), + (0x1E903, "M", "šž¤„"), + (0x1E904, "M", "šž¤¦"), + (0x1E905, "M", "šž¤§"), + (0x1E906, "M", "šž¤Ø"), + (0x1E907, "M", "šž¤©"), + (0x1E908, "M", "šž¤Ŗ"), + (0x1E909, "M", "šž¤«"), + (0x1E90A, "M", "šž¤¬"), + (0x1E90B, "M", "šž¤­"), + (0x1E90C, "M", "šž¤®"), + (0x1E90D, "M", "šž¤Æ"), ] + def _seg_72() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1E90A, 'M', 'šž¤¬'), - (0x1E90B, 'M', 'šž¤­'), - (0x1E90C, 'M', 'šž¤®'), - (0x1E90D, 'M', 'šž¤Æ'), - (0x1E90E, 'M', 'šž¤°'), - (0x1E90F, 'M', 'šž¤±'), - (0x1E910, 'M', 'šž¤²'), - (0x1E911, 'M', 'šž¤³'), - (0x1E912, 'M', 'šž¤“'), - (0x1E913, 'M', 'šž¤µ'), - (0x1E914, 'M', 'šž¤¶'), - (0x1E915, 'M', 'šž¤·'), - (0x1E916, 'M', 'šž¤ø'), - (0x1E917, 'M', 'šž¤¹'), - (0x1E918, 'M', 'šž¤ŗ'), - (0x1E919, 'M', 'šž¤»'), - (0x1E91A, 'M', 'šž¤¼'), - (0x1E91B, 'M', 'šž¤½'), - (0x1E91C, 'M', 'šž¤¾'), - (0x1E91D, 'M', 'šž¤æ'), - (0x1E91E, 'M', 'šž„€'), - (0x1E91F, 'M', 'šž„'), - (0x1E920, 'M', 'šž„‚'), - (0x1E921, 'M', 'šž„ƒ'), - (0x1E922, 'V'), - (0x1E94C, 'X'), - (0x1E950, 'V'), - (0x1E95A, 'X'), - (0x1E95E, 'V'), - (0x1E960, 'X'), - (0x1EC71, 'V'), - (0x1ECB5, 'X'), - (0x1ED01, 'V'), - (0x1ED3E, 'X'), - (0x1EE00, 'M', 'Ų§'), - (0x1EE01, 'M', 'ŲØ'), - (0x1EE02, 'M', 'Ų¬'), - (0x1EE03, 'M', 'ŲÆ'), - (0x1EE04, 'X'), - (0x1EE05, 'M', 'و'), - (0x1EE06, 'M', 'Ų²'), - (0x1EE07, 'M', 'Ų­'), - (0x1EE08, 'M', 'Ų·'), - (0x1EE09, 'M', 'ي'), - (0x1EE0A, 'M', 'ك'), - (0x1EE0B, 'M', 'Ł„'), - (0x1EE0C, 'M', 'Ł…'), - (0x1EE0D, 'M', 'ن'), - (0x1EE0E, 'M', 'Ų³'), - (0x1EE0F, 'M', 'Ų¹'), - (0x1EE10, 'M', 'ف'), - (0x1EE11, 'M', 'Ųµ'), - (0x1EE12, 'M', 'Ł‚'), - (0x1EE13, 'M', 'Ų±'), - (0x1EE14, 'M', 'Ų“'), - (0x1EE15, 'M', 'ŲŖ'), - (0x1EE16, 'M', 'Ų«'), - (0x1EE17, 'M', 'Ų®'), - (0x1EE18, 'M', 'Ų°'), - (0x1EE19, 'M', 'Ų¶'), - (0x1EE1A, 'M', 'Ųø'), - (0x1EE1B, 'M', 'Ųŗ'), - (0x1EE1C, 'M', 'Ł®'), - (0x1EE1D, 'M', 'Śŗ'), - (0x1EE1E, 'M', 'Ś”'), - (0x1EE1F, 'M', 'ŁÆ'), - (0x1EE20, 'X'), - (0x1EE21, 'M', 'ŲØ'), - (0x1EE22, 'M', 'Ų¬'), - (0x1EE23, 'X'), - (0x1EE24, 'M', 'ه'), - (0x1EE25, 'X'), - (0x1EE27, 'M', 'Ų­'), - (0x1EE28, 'X'), - (0x1EE29, 'M', 'ي'), - (0x1EE2A, 'M', 'ك'), - (0x1EE2B, 'M', 'Ł„'), - (0x1EE2C, 'M', 'Ł…'), - (0x1EE2D, 'M', 'ن'), - (0x1EE2E, 'M', 'Ų³'), - (0x1EE2F, 'M', 'Ų¹'), - (0x1EE30, 'M', 'ف'), - (0x1EE31, 'M', 'Ųµ'), - (0x1EE32, 'M', 'Ł‚'), - (0x1EE33, 'X'), - (0x1EE34, 'M', 'Ų“'), - (0x1EE35, 'M', 'ŲŖ'), - (0x1EE36, 'M', 'Ų«'), - (0x1EE37, 'M', 'Ų®'), - (0x1EE38, 'X'), - (0x1EE39, 'M', 'Ų¶'), - (0x1EE3A, 'X'), - (0x1EE3B, 'M', 'Ųŗ'), - (0x1EE3C, 'X'), - (0x1EE42, 'M', 'Ų¬'), - (0x1EE43, 'X'), - (0x1EE47, 'M', 'Ų­'), - (0x1EE48, 'X'), - (0x1EE49, 'M', 'ي'), - (0x1EE4A, 'X'), + (0x1E90E, "M", "šž¤°"), + (0x1E90F, "M", "šž¤±"), + (0x1E910, "M", "šž¤²"), + (0x1E911, "M", "šž¤³"), + (0x1E912, "M", "šž¤“"), + (0x1E913, "M", "šž¤µ"), + (0x1E914, "M", "šž¤¶"), + (0x1E915, "M", "šž¤·"), + (0x1E916, "M", "šž¤ø"), + (0x1E917, "M", "šž¤¹"), + (0x1E918, "M", "šž¤ŗ"), + (0x1E919, "M", "šž¤»"), + (0x1E91A, "M", "šž¤¼"), + (0x1E91B, "M", "šž¤½"), + (0x1E91C, "M", "šž¤¾"), + (0x1E91D, "M", "šž¤æ"), + (0x1E91E, "M", "šž„€"), + (0x1E91F, "M", "šž„"), + (0x1E920, "M", "šž„‚"), + (0x1E921, "M", "šž„ƒ"), + (0x1E922, "V"), + (0x1E94C, "X"), + (0x1E950, "V"), + (0x1E95A, "X"), + (0x1E95E, "V"), + (0x1E960, "X"), + (0x1EC71, "V"), + (0x1ECB5, "X"), + (0x1ED01, "V"), + (0x1ED3E, "X"), + (0x1EE00, "M", "Ų§"), + (0x1EE01, "M", "ŲØ"), + (0x1EE02, "M", "Ų¬"), + (0x1EE03, "M", "ŲÆ"), + (0x1EE04, "X"), + (0x1EE05, "M", "و"), + (0x1EE06, "M", "Ų²"), + (0x1EE07, "M", "Ų­"), + (0x1EE08, "M", "Ų·"), + (0x1EE09, "M", "ي"), + (0x1EE0A, "M", "ك"), + (0x1EE0B, "M", "Ł„"), + (0x1EE0C, "M", "Ł…"), + (0x1EE0D, "M", "ن"), + (0x1EE0E, "M", "Ų³"), + (0x1EE0F, "M", "Ų¹"), + (0x1EE10, "M", "ف"), + (0x1EE11, "M", "Ųµ"), + (0x1EE12, "M", "Ł‚"), + (0x1EE13, "M", "Ų±"), + (0x1EE14, "M", "Ų“"), + (0x1EE15, "M", "ŲŖ"), + (0x1EE16, "M", "Ų«"), + (0x1EE17, "M", "Ų®"), + (0x1EE18, "M", "Ų°"), + (0x1EE19, "M", "Ų¶"), + (0x1EE1A, "M", "Ųø"), + (0x1EE1B, "M", "Ųŗ"), + (0x1EE1C, "M", "Ł®"), + (0x1EE1D, "M", "Śŗ"), + (0x1EE1E, "M", "Ś”"), + (0x1EE1F, "M", "ŁÆ"), + (0x1EE20, "X"), + (0x1EE21, "M", "ŲØ"), + (0x1EE22, "M", "Ų¬"), + (0x1EE23, "X"), + (0x1EE24, "M", "ه"), + (0x1EE25, "X"), + (0x1EE27, "M", "Ų­"), + (0x1EE28, "X"), + (0x1EE29, "M", "ي"), + (0x1EE2A, "M", "ك"), + (0x1EE2B, "M", "Ł„"), + (0x1EE2C, "M", "Ł…"), + (0x1EE2D, "M", "ن"), + (0x1EE2E, "M", "Ų³"), + (0x1EE2F, "M", "Ų¹"), + (0x1EE30, "M", "ف"), + (0x1EE31, "M", "Ųµ"), + (0x1EE32, "M", "Ł‚"), + (0x1EE33, "X"), + (0x1EE34, "M", "Ų“"), + (0x1EE35, "M", "ŲŖ"), + (0x1EE36, "M", "Ų«"), + (0x1EE37, "M", "Ų®"), + (0x1EE38, "X"), + (0x1EE39, "M", "Ų¶"), + (0x1EE3A, "X"), + (0x1EE3B, "M", "Ųŗ"), + (0x1EE3C, "X"), + (0x1EE42, "M", "Ų¬"), + (0x1EE43, "X"), + (0x1EE47, "M", "Ų­"), + (0x1EE48, "X"), + (0x1EE49, "M", "ي"), + (0x1EE4A, "X"), + (0x1EE4B, "M", "Ł„"), + (0x1EE4C, "X"), + (0x1EE4D, "M", "ن"), + (0x1EE4E, "M", "Ų³"), ] + def _seg_73() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1EE4B, 'M', 'Ł„'), - (0x1EE4C, 'X'), - (0x1EE4D, 'M', 'ن'), - (0x1EE4E, 'M', 'Ų³'), - (0x1EE4F, 'M', 'Ų¹'), - (0x1EE50, 'X'), - (0x1EE51, 'M', 'Ųµ'), - (0x1EE52, 'M', 'Ł‚'), - (0x1EE53, 'X'), - (0x1EE54, 'M', 'Ų“'), - (0x1EE55, 'X'), - (0x1EE57, 'M', 'Ų®'), - (0x1EE58, 'X'), - (0x1EE59, 'M', 'Ų¶'), - (0x1EE5A, 'X'), - (0x1EE5B, 'M', 'Ųŗ'), - (0x1EE5C, 'X'), - (0x1EE5D, 'M', 'Śŗ'), - (0x1EE5E, 'X'), - (0x1EE5F, 'M', 'ŁÆ'), - (0x1EE60, 'X'), - (0x1EE61, 'M', 'ŲØ'), - (0x1EE62, 'M', 'Ų¬'), - (0x1EE63, 'X'), - (0x1EE64, 'M', 'ه'), - (0x1EE65, 'X'), - (0x1EE67, 'M', 'Ų­'), - (0x1EE68, 'M', 'Ų·'), - (0x1EE69, 'M', 'ي'), - (0x1EE6A, 'M', 'ك'), - (0x1EE6B, 'X'), - (0x1EE6C, 'M', 'Ł…'), - (0x1EE6D, 'M', 'ن'), - (0x1EE6E, 'M', 'Ų³'), - (0x1EE6F, 'M', 'Ų¹'), - (0x1EE70, 'M', 'ف'), - (0x1EE71, 'M', 'Ųµ'), - (0x1EE72, 'M', 'Ł‚'), - (0x1EE73, 'X'), - (0x1EE74, 'M', 'Ų“'), - (0x1EE75, 'M', 'ŲŖ'), - (0x1EE76, 'M', 'Ų«'), - (0x1EE77, 'M', 'Ų®'), - (0x1EE78, 'X'), - (0x1EE79, 'M', 'Ų¶'), - (0x1EE7A, 'M', 'Ųø'), - (0x1EE7B, 'M', 'Ųŗ'), - (0x1EE7C, 'M', 'Ł®'), - (0x1EE7D, 'X'), - (0x1EE7E, 'M', 'Ś”'), - (0x1EE7F, 'X'), - (0x1EE80, 'M', 'Ų§'), - (0x1EE81, 'M', 'ŲØ'), - (0x1EE82, 'M', 'Ų¬'), - (0x1EE83, 'M', 'ŲÆ'), - (0x1EE84, 'M', 'ه'), - (0x1EE85, 'M', 'و'), - (0x1EE86, 'M', 'Ų²'), - (0x1EE87, 'M', 'Ų­'), - (0x1EE88, 'M', 'Ų·'), - (0x1EE89, 'M', 'ي'), - (0x1EE8A, 'X'), - (0x1EE8B, 'M', 'Ł„'), - (0x1EE8C, 'M', 'Ł…'), - (0x1EE8D, 'M', 'ن'), - (0x1EE8E, 'M', 'Ų³'), - (0x1EE8F, 'M', 'Ų¹'), - (0x1EE90, 'M', 'ف'), - (0x1EE91, 'M', 'Ųµ'), - (0x1EE92, 'M', 'Ł‚'), - (0x1EE93, 'M', 'Ų±'), - (0x1EE94, 'M', 'Ų“'), - (0x1EE95, 'M', 'ŲŖ'), - (0x1EE96, 'M', 'Ų«'), - (0x1EE97, 'M', 'Ų®'), - (0x1EE98, 'M', 'Ų°'), - (0x1EE99, 'M', 'Ų¶'), - (0x1EE9A, 'M', 'Ųø'), - (0x1EE9B, 'M', 'Ųŗ'), - (0x1EE9C, 'X'), - (0x1EEA1, 'M', 'ŲØ'), - (0x1EEA2, 'M', 'Ų¬'), - (0x1EEA3, 'M', 'ŲÆ'), - (0x1EEA4, 'X'), - (0x1EEA5, 'M', 'و'), - (0x1EEA6, 'M', 'Ų²'), - (0x1EEA7, 'M', 'Ų­'), - (0x1EEA8, 'M', 'Ų·'), - (0x1EEA9, 'M', 'ي'), - (0x1EEAA, 'X'), - (0x1EEAB, 'M', 'Ł„'), - (0x1EEAC, 'M', 'Ł…'), - (0x1EEAD, 'M', 'ن'), - (0x1EEAE, 'M', 'Ų³'), - (0x1EEAF, 'M', 'Ų¹'), - (0x1EEB0, 'M', 'ف'), - (0x1EEB1, 'M', 'Ųµ'), - (0x1EEB2, 'M', 'Ł‚'), - (0x1EEB3, 'M', 'Ų±'), - (0x1EEB4, 'M', 'Ų“'), + (0x1EE4F, "M", "Ų¹"), + (0x1EE50, "X"), + (0x1EE51, "M", "Ųµ"), + (0x1EE52, "M", "Ł‚"), + (0x1EE53, "X"), + (0x1EE54, "M", "Ų“"), + (0x1EE55, "X"), + (0x1EE57, "M", "Ų®"), + (0x1EE58, "X"), + (0x1EE59, "M", "Ų¶"), + (0x1EE5A, "X"), + (0x1EE5B, "M", "Ųŗ"), + (0x1EE5C, "X"), + (0x1EE5D, "M", "Śŗ"), + (0x1EE5E, "X"), + (0x1EE5F, "M", "ŁÆ"), + (0x1EE60, "X"), + (0x1EE61, "M", "ŲØ"), + (0x1EE62, "M", "Ų¬"), + (0x1EE63, "X"), + (0x1EE64, "M", "ه"), + (0x1EE65, "X"), + (0x1EE67, "M", "Ų­"), + (0x1EE68, "M", "Ų·"), + (0x1EE69, "M", "ي"), + (0x1EE6A, "M", "ك"), + (0x1EE6B, "X"), + (0x1EE6C, "M", "Ł…"), + (0x1EE6D, "M", "ن"), + (0x1EE6E, "M", "Ų³"), + (0x1EE6F, "M", "Ų¹"), + (0x1EE70, "M", "ف"), + (0x1EE71, "M", "Ųµ"), + (0x1EE72, "M", "Ł‚"), + (0x1EE73, "X"), + (0x1EE74, "M", "Ų“"), + (0x1EE75, "M", "ŲŖ"), + (0x1EE76, "M", "Ų«"), + (0x1EE77, "M", "Ų®"), + (0x1EE78, "X"), + (0x1EE79, "M", "Ų¶"), + (0x1EE7A, "M", "Ųø"), + (0x1EE7B, "M", "Ųŗ"), + (0x1EE7C, "M", "Ł®"), + (0x1EE7D, "X"), + (0x1EE7E, "M", "Ś”"), + (0x1EE7F, "X"), + (0x1EE80, "M", "Ų§"), + (0x1EE81, "M", "ŲØ"), + (0x1EE82, "M", "Ų¬"), + (0x1EE83, "M", "ŲÆ"), + (0x1EE84, "M", "ه"), + (0x1EE85, "M", "و"), + (0x1EE86, "M", "Ų²"), + (0x1EE87, "M", "Ų­"), + (0x1EE88, "M", "Ų·"), + (0x1EE89, "M", "ي"), + (0x1EE8A, "X"), + (0x1EE8B, "M", "Ł„"), + (0x1EE8C, "M", "Ł…"), + (0x1EE8D, "M", "ن"), + (0x1EE8E, "M", "Ų³"), + (0x1EE8F, "M", "Ų¹"), + (0x1EE90, "M", "ف"), + (0x1EE91, "M", "Ųµ"), + (0x1EE92, "M", "Ł‚"), + (0x1EE93, "M", "Ų±"), + (0x1EE94, "M", "Ų“"), + (0x1EE95, "M", "ŲŖ"), + (0x1EE96, "M", "Ų«"), + (0x1EE97, "M", "Ų®"), + (0x1EE98, "M", "Ų°"), + (0x1EE99, "M", "Ų¶"), + (0x1EE9A, "M", "Ųø"), + (0x1EE9B, "M", "Ųŗ"), + (0x1EE9C, "X"), + (0x1EEA1, "M", "ŲØ"), + (0x1EEA2, "M", "Ų¬"), + (0x1EEA3, "M", "ŲÆ"), + (0x1EEA4, "X"), + (0x1EEA5, "M", "و"), + (0x1EEA6, "M", "Ų²"), + (0x1EEA7, "M", "Ų­"), + (0x1EEA8, "M", "Ų·"), + (0x1EEA9, "M", "ي"), + (0x1EEAA, "X"), + (0x1EEAB, "M", "Ł„"), + (0x1EEAC, "M", "Ł…"), + (0x1EEAD, "M", "ن"), + (0x1EEAE, "M", "Ų³"), + (0x1EEAF, "M", "Ų¹"), + (0x1EEB0, "M", "ف"), + (0x1EEB1, "M", "Ųµ"), + (0x1EEB2, "M", "Ł‚"), + (0x1EEB3, "M", "Ų±"), + (0x1EEB4, "M", "Ų“"), + (0x1EEB5, "M", "ŲŖ"), + (0x1EEB6, "M", "Ų«"), + (0x1EEB7, "M", "Ų®"), + (0x1EEB8, "M", "Ų°"), ] + def _seg_74() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1EEB5, 'M', 'ŲŖ'), - (0x1EEB6, 'M', 'Ų«'), - (0x1EEB7, 'M', 'Ų®'), - (0x1EEB8, 'M', 'Ų°'), - (0x1EEB9, 'M', 'Ų¶'), - (0x1EEBA, 'M', 'Ųø'), - (0x1EEBB, 'M', 'Ųŗ'), - (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', '0,'), - (0x1F102, '3', '1,'), - (0x1F103, '3', '2,'), - (0x1F104, '3', '3,'), - (0x1F105, '3', '4,'), - (0x1F106, '3', '5,'), - (0x1F107, '3', '6,'), - (0x1F108, '3', '7,'), - (0x1F109, '3', '8,'), - (0x1F10A, '3', '9,'), - (0x1F10B, 'V'), - (0x1F110, '3', '(a)'), - (0x1F111, '3', '(b)'), - (0x1F112, '3', '(c)'), - (0x1F113, '3', '(d)'), - (0x1F114, '3', '(e)'), - (0x1F115, '3', '(f)'), - (0x1F116, '3', '(g)'), - (0x1F117, '3', '(h)'), - (0x1F118, '3', '(i)'), - (0x1F119, '3', '(j)'), - (0x1F11A, '3', '(k)'), - (0x1F11B, '3', '(l)'), - (0x1F11C, '3', '(m)'), - (0x1F11D, '3', '(n)'), - (0x1F11E, '3', '(o)'), - (0x1F11F, '3', '(p)'), - (0x1F120, '3', '(q)'), - (0x1F121, '3', '(r)'), - (0x1F122, '3', '(s)'), - (0x1F123, '3', '(t)'), - (0x1F124, '3', '(u)'), - (0x1F125, '3', '(v)'), - (0x1F126, '3', '(w)'), - (0x1F127, '3', '(x)'), - (0x1F128, '3', '(y)'), - (0x1F129, '3', '(z)'), - (0x1F12A, 'M', '怔s怕'), - (0x1F12B, 'M', 'c'), - (0x1F12C, 'M', 'r'), - (0x1F12D, 'M', 'cd'), - (0x1F12E, 'M', 'wz'), - (0x1F12F, 'V'), - (0x1F130, 'M', 'a'), - (0x1F131, 'M', 'b'), - (0x1F132, 'M', 'c'), - (0x1F133, 'M', 'd'), - (0x1F134, 'M', 'e'), - (0x1F135, 'M', 'f'), - (0x1F136, 'M', 'g'), - (0x1F137, 'M', 'h'), - (0x1F138, 'M', 'i'), - (0x1F139, 'M', 'j'), - (0x1F13A, 'M', 'k'), - (0x1F13B, 'M', 'l'), - (0x1F13C, 'M', 'm'), - (0x1F13D, 'M', 'n'), - (0x1F13E, 'M', 'o'), - (0x1F13F, 'M', 'p'), - (0x1F140, 'M', 'q'), - (0x1F141, 'M', 'r'), - (0x1F142, 'M', 's'), - (0x1F143, 'M', 't'), - (0x1F144, 'M', 'u'), - (0x1F145, 'M', 'v'), - (0x1F146, 'M', 'w'), - (0x1F147, 'M', 'x'), - (0x1F148, 'M', 'y'), - (0x1F149, 'M', 'z'), - (0x1F14A, 'M', 'hv'), - (0x1F14B, 'M', 'mv'), - (0x1F14C, 'M', 'sd'), - (0x1F14D, 'M', 'ss'), - (0x1F14E, 'M', 'ppv'), - (0x1F14F, 'M', 'wc'), - (0x1F150, 'V'), - (0x1F16A, 'M', 'mc'), - (0x1F16B, 'M', 'md'), + (0x1EEB9, "M", "Ų¶"), + (0x1EEBA, "M", "Ųø"), + (0x1EEBB, "M", "Ųŗ"), + (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", "0,"), + (0x1F102, "3", "1,"), + (0x1F103, "3", "2,"), + (0x1F104, "3", "3,"), + (0x1F105, "3", "4,"), + (0x1F106, "3", "5,"), + (0x1F107, "3", "6,"), + (0x1F108, "3", "7,"), + (0x1F109, "3", "8,"), + (0x1F10A, "3", "9,"), + (0x1F10B, "V"), + (0x1F110, "3", "(a)"), + (0x1F111, "3", "(b)"), + (0x1F112, "3", "(c)"), + (0x1F113, "3", "(d)"), + (0x1F114, "3", "(e)"), + (0x1F115, "3", "(f)"), + (0x1F116, "3", "(g)"), + (0x1F117, "3", "(h)"), + (0x1F118, "3", "(i)"), + (0x1F119, "3", "(j)"), + (0x1F11A, "3", "(k)"), + (0x1F11B, "3", "(l)"), + (0x1F11C, "3", "(m)"), + (0x1F11D, "3", "(n)"), + (0x1F11E, "3", "(o)"), + (0x1F11F, "3", "(p)"), + (0x1F120, "3", "(q)"), + (0x1F121, "3", "(r)"), + (0x1F122, "3", "(s)"), + (0x1F123, "3", "(t)"), + (0x1F124, "3", "(u)"), + (0x1F125, "3", "(v)"), + (0x1F126, "3", "(w)"), + (0x1F127, "3", "(x)"), + (0x1F128, "3", "(y)"), + (0x1F129, "3", "(z)"), + (0x1F12A, "M", "怔s怕"), + (0x1F12B, "M", "c"), + (0x1F12C, "M", "r"), + (0x1F12D, "M", "cd"), + (0x1F12E, "M", "wz"), + (0x1F12F, "V"), + (0x1F130, "M", "a"), + (0x1F131, "M", "b"), + (0x1F132, "M", "c"), + (0x1F133, "M", "d"), + (0x1F134, "M", "e"), + (0x1F135, "M", "f"), + (0x1F136, "M", "g"), + (0x1F137, "M", "h"), + (0x1F138, "M", "i"), + (0x1F139, "M", "j"), + (0x1F13A, "M", "k"), + (0x1F13B, "M", "l"), + (0x1F13C, "M", "m"), + (0x1F13D, "M", "n"), + (0x1F13E, "M", "o"), + (0x1F13F, "M", "p"), + (0x1F140, "M", "q"), + (0x1F141, "M", "r"), + (0x1F142, "M", "s"), + (0x1F143, "M", "t"), + (0x1F144, "M", "u"), + (0x1F145, "M", "v"), + (0x1F146, "M", "w"), + (0x1F147, "M", "x"), + (0x1F148, "M", "y"), + (0x1F149, "M", "z"), + (0x1F14A, "M", "hv"), + (0x1F14B, "M", "mv"), + (0x1F14C, "M", "sd"), + (0x1F14D, "M", "ss"), + (0x1F14E, "M", "ppv"), + (0x1F14F, "M", "wc"), + (0x1F150, "V"), + (0x1F16A, "M", "mc"), + (0x1F16B, "M", "md"), + (0x1F16C, "M", "mr"), + (0x1F16D, "V"), + (0x1F190, "M", "dj"), + (0x1F191, "V"), ] + def _seg_75() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1F16C, 'M', 'mr'), - (0x1F16D, 'V'), - (0x1F190, 'M', 'dj'), - (0x1F191, 'V'), - (0x1F1AE, 'X'), - (0x1F1E6, 'V'), - (0x1F200, 'M', '恻恋'), - (0x1F201, 'M', 'ココ'), - (0x1F202, 'M', '悵'), - (0x1F203, 'X'), - (0x1F210, 'M', 'ꉋ'), - (0x1F211, 'M', '字'), - (0x1F212, 'M', '双'), - (0x1F213, 'M', '惇'), - (0x1F214, 'M', '二'), - (0x1F215, 'M', '多'), - (0x1F216, 'M', 'č§£'), - (0x1F217, 'M', '天'), - (0x1F218, 'M', 'äŗ¤'), - (0x1F219, 'M', '꘠'), - (0x1F21A, 'M', 'ē„”'), - (0x1F21B, 'M', 'ꖙ'), - (0x1F21C, 'M', '前'), - (0x1F21D, 'M', '後'), - (0x1F21E, 'M', '再'), - (0x1F21F, 'M', 'ꖰ'), - (0x1F220, 'M', '初'), - (0x1F221, 'M', '終'), - (0x1F222, 'M', 'ē”Ÿ'), - (0x1F223, 'M', '販'), - (0x1F224, 'M', '声'), - (0x1F225, 'M', '吹'), - (0x1F226, 'M', 'ę¼”'), - (0x1F227, 'M', 'ꊕ'), - (0x1F228, 'M', 'ꍕ'), - (0x1F229, 'M', 'äø€'), - (0x1F22A, 'M', 'äø‰'), - (0x1F22B, 'M', '遊'), - (0x1F22C, 'M', 'å·¦'), - (0x1F22D, 'M', 'äø­'), - (0x1F22E, 'M', '右'), - (0x1F22F, 'M', 'ꌇ'), - (0x1F230, 'M', 'čµ°'), - (0x1F231, 'M', 'ꉓ'), - (0x1F232, 'M', '禁'), - (0x1F233, 'M', '空'), - (0x1F234, 'M', '合'), - (0x1F235, 'M', 'ęŗ€'), - (0x1F236, 'M', '꜉'), - (0x1F237, 'M', '月'), - (0x1F238, 'M', '申'), - (0x1F239, 'M', '割'), - (0x1F23A, 'M', '営'), - (0x1F23B, 'M', '配'), - (0x1F23C, 'X'), - (0x1F240, 'M', 'ć€”ęœ¬ć€•'), - (0x1F241, 'M', '〔三〕'), - (0x1F242, 'M', 'ć€”äŗŒć€•'), - (0x1F243, 'M', '〔安〕'), - (0x1F244, 'M', '〔点〕'), - (0x1F245, 'M', '怔ꉓ怕'), - (0x1F246, 'M', '〔盗〕'), - (0x1F247, 'M', 'ć€”å‹ć€•'), - (0x1F248, 'M', '怔ꕗ怕'), - (0x1F249, 'X'), - (0x1F250, 'M', '得'), - (0x1F251, 'M', 'åÆ'), - (0x1F252, 'X'), - (0x1F260, 'V'), - (0x1F266, 'X'), - (0x1F300, 'V'), - (0x1F6D8, 'X'), - (0x1F6DC, 'V'), - (0x1F6ED, 'X'), - (0x1F6F0, 'V'), - (0x1F6FD, 'X'), - (0x1F700, 'V'), - (0x1F777, 'X'), - (0x1F77B, 'V'), - (0x1F7DA, 'X'), - (0x1F7E0, 'V'), - (0x1F7EC, 'X'), - (0x1F7F0, 'V'), - (0x1F7F1, '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'), - (0x1FA54, 'X'), - (0x1FA60, 'V'), - (0x1FA6E, 'X'), + (0x1F1AE, "X"), + (0x1F1E6, "V"), + (0x1F200, "M", "恻恋"), + (0x1F201, "M", "ココ"), + (0x1F202, "M", "悵"), + (0x1F203, "X"), + (0x1F210, "M", "ꉋ"), + (0x1F211, "M", "字"), + (0x1F212, "M", "双"), + (0x1F213, "M", "惇"), + (0x1F214, "M", "二"), + (0x1F215, "M", "多"), + (0x1F216, "M", "č§£"), + (0x1F217, "M", "天"), + (0x1F218, "M", "äŗ¤"), + (0x1F219, "M", "꘠"), + (0x1F21A, "M", "ē„”"), + (0x1F21B, "M", "ꖙ"), + (0x1F21C, "M", "前"), + (0x1F21D, "M", "後"), + (0x1F21E, "M", "再"), + (0x1F21F, "M", "ꖰ"), + (0x1F220, "M", "初"), + (0x1F221, "M", "終"), + (0x1F222, "M", "ē”Ÿ"), + (0x1F223, "M", "販"), + (0x1F224, "M", "声"), + (0x1F225, "M", "吹"), + (0x1F226, "M", "ę¼”"), + (0x1F227, "M", "ꊕ"), + (0x1F228, "M", "ꍕ"), + (0x1F229, "M", "äø€"), + (0x1F22A, "M", "äø‰"), + (0x1F22B, "M", "遊"), + (0x1F22C, "M", "å·¦"), + (0x1F22D, "M", "äø­"), + (0x1F22E, "M", "右"), + (0x1F22F, "M", "ꌇ"), + (0x1F230, "M", "čµ°"), + (0x1F231, "M", "ꉓ"), + (0x1F232, "M", "禁"), + (0x1F233, "M", "空"), + (0x1F234, "M", "合"), + (0x1F235, "M", "ęŗ€"), + (0x1F236, "M", "꜉"), + (0x1F237, "M", "月"), + (0x1F238, "M", "申"), + (0x1F239, "M", "割"), + (0x1F23A, "M", "営"), + (0x1F23B, "M", "配"), + (0x1F23C, "X"), + (0x1F240, "M", "ć€”ęœ¬ć€•"), + (0x1F241, "M", "〔三〕"), + (0x1F242, "M", "ć€”äŗŒć€•"), + (0x1F243, "M", "〔安〕"), + (0x1F244, "M", "〔点〕"), + (0x1F245, "M", "怔ꉓ怕"), + (0x1F246, "M", "〔盗〕"), + (0x1F247, "M", "ć€”å‹ć€•"), + (0x1F248, "M", "怔ꕗ怕"), + (0x1F249, "X"), + (0x1F250, "M", "得"), + (0x1F251, "M", "åÆ"), + (0x1F252, "X"), + (0x1F260, "V"), + (0x1F266, "X"), + (0x1F300, "V"), + (0x1F6D8, "X"), + (0x1F6DC, "V"), + (0x1F6ED, "X"), + (0x1F6F0, "V"), + (0x1F6FD, "X"), + (0x1F700, "V"), + (0x1F777, "X"), + (0x1F77B, "V"), + (0x1F7DA, "X"), + (0x1F7E0, "V"), + (0x1F7EC, "X"), + (0x1F7F0, "V"), + (0x1F7F1, "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"), + (0x1FA54, "X"), + (0x1FA60, "V"), + (0x1FA6E, "X"), + (0x1FA70, "V"), + (0x1FA7D, "X"), + (0x1FA80, "V"), + (0x1FA89, "X"), ] + def _seg_76() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x1FA70, 'V'), - (0x1FA7D, 'X'), - (0x1FA80, 'V'), - (0x1FA89, 'X'), - (0x1FA90, 'V'), - (0x1FABE, 'X'), - (0x1FABF, 'V'), - (0x1FAC6, 'X'), - (0x1FACE, 'V'), - (0x1FADC, 'X'), - (0x1FAE0, 'V'), - (0x1FAE9, 'X'), - (0x1FAF0, 'V'), - (0x1FAF9, 'X'), - (0x1FB00, 'V'), - (0x1FB93, 'X'), - (0x1FB94, 'V'), - (0x1FBCB, 'X'), - (0x1FBF0, 'M', '0'), - (0x1FBF1, 'M', '1'), - (0x1FBF2, 'M', '2'), - (0x1FBF3, 'M', '3'), - (0x1FBF4, 'M', '4'), - (0x1FBF5, 'M', '5'), - (0x1FBF6, 'M', '6'), - (0x1FBF7, 'M', '7'), - (0x1FBF8, 'M', '8'), - (0x1FBF9, 'M', '9'), - (0x1FBFA, 'X'), - (0x20000, 'V'), - (0x2A6E0, 'X'), - (0x2A700, 'V'), - (0x2B73A, 'X'), - (0x2B740, 'V'), - (0x2B81E, 'X'), - (0x2B820, 'V'), - (0x2CEA2, 'X'), - (0x2CEB0, 'V'), - (0x2EBE1, 'X'), - (0x2F800, 'M', 'äø½'), - (0x2F801, 'M', 'äøø'), - (0x2F802, 'M', '乁'), - (0x2F803, 'M', 'š „¢'), - (0x2F804, 'M', 'ä½ '), - (0x2F805, 'M', 'ä¾®'), - (0x2F806, 'M', 'ä¾»'), - (0x2F807, 'M', '倂'), - (0x2F808, 'M', '偺'), - (0x2F809, 'M', '備'), - (0x2F80A, 'M', '僧'), - (0x2F80B, 'M', '像'), - (0x2F80C, 'M', '撞'), - (0x2F80D, 'M', '𠘺'), - (0x2F80E, 'M', '免'), - (0x2F80F, 'M', '兔'), - (0x2F810, 'M', '兤'), - (0x2F811, 'M', '具'), - (0x2F812, 'M', 'š ”œ'), - (0x2F813, 'M', 'ć’¹'), - (0x2F814, 'M', '內'), - (0x2F815, 'M', '再'), - (0x2F816, 'M', 'š •‹'), - (0x2F817, 'M', '冗'), - (0x2F818, 'M', '冤'), - (0x2F819, 'M', '仌'), - (0x2F81A, 'M', '冬'), - (0x2F81B, 'M', '况'), - (0x2F81C, 'M', 'š©‡Ÿ'), - (0x2F81D, 'M', '凵'), - (0x2F81E, 'M', '刃'), - (0x2F81F, 'M', '擟'), - (0x2F820, 'M', '刻'), - (0x2F821, 'M', '剆'), - (0x2F822, 'M', '割'), - (0x2F823, 'M', '剷'), - (0x2F824, 'M', '攕'), - (0x2F825, 'M', '勇'), - (0x2F826, 'M', '勉'), - (0x2F827, 'M', '勤'), - (0x2F828, 'M', '勺'), - (0x2F829, 'M', '包'), - (0x2F82A, 'M', '匆'), - (0x2F82B, 'M', '北'), - (0x2F82C, 'M', '卉'), - (0x2F82D, 'M', '卑'), - (0x2F82E, 'M', '博'), - (0x2F82F, 'M', '即'), - (0x2F830, 'M', '卽'), - (0x2F831, 'M', 'åæ'), - (0x2F834, 'M', '𠨬'), - (0x2F835, 'M', '灰'), - (0x2F836, 'M', '及'), - (0x2F837, 'M', '叟'), - (0x2F838, 'M', 'š ­£'), - (0x2F839, 'M', '叫'), - (0x2F83A, 'M', '叱'), - (0x2F83B, 'M', '吆'), - (0x2F83C, 'M', '咞'), - (0x2F83D, 'M', '吸'), - (0x2F83E, 'M', '呈'), + (0x1FA90, "V"), + (0x1FABE, "X"), + (0x1FABF, "V"), + (0x1FAC6, "X"), + (0x1FACE, "V"), + (0x1FADC, "X"), + (0x1FAE0, "V"), + (0x1FAE9, "X"), + (0x1FAF0, "V"), + (0x1FAF9, "X"), + (0x1FB00, "V"), + (0x1FB93, "X"), + (0x1FB94, "V"), + (0x1FBCB, "X"), + (0x1FBF0, "M", "0"), + (0x1FBF1, "M", "1"), + (0x1FBF2, "M", "2"), + (0x1FBF3, "M", "3"), + (0x1FBF4, "M", "4"), + (0x1FBF5, "M", "5"), + (0x1FBF6, "M", "6"), + (0x1FBF7, "M", "7"), + (0x1FBF8, "M", "8"), + (0x1FBF9, "M", "9"), + (0x1FBFA, "X"), + (0x20000, "V"), + (0x2A6E0, "X"), + (0x2A700, "V"), + (0x2B73A, "X"), + (0x2B740, "V"), + (0x2B81E, "X"), + (0x2B820, "V"), + (0x2CEA2, "X"), + (0x2CEB0, "V"), + (0x2EBE1, "X"), + (0x2EBF0, "V"), + (0x2EE5E, "X"), + (0x2F800, "M", "äø½"), + (0x2F801, "M", "äøø"), + (0x2F802, "M", "乁"), + (0x2F803, "M", "š „¢"), + (0x2F804, "M", "ä½ "), + (0x2F805, "M", "ä¾®"), + (0x2F806, "M", "ä¾»"), + (0x2F807, "M", "倂"), + (0x2F808, "M", "偺"), + (0x2F809, "M", "備"), + (0x2F80A, "M", "僧"), + (0x2F80B, "M", "像"), + (0x2F80C, "M", "撞"), + (0x2F80D, "M", "𠘺"), + (0x2F80E, "M", "免"), + (0x2F80F, "M", "兔"), + (0x2F810, "M", "兤"), + (0x2F811, "M", "具"), + (0x2F812, "M", "š ”œ"), + (0x2F813, "M", "ć’¹"), + (0x2F814, "M", "內"), + (0x2F815, "M", "再"), + (0x2F816, "M", "š •‹"), + (0x2F817, "M", "冗"), + (0x2F818, "M", "冤"), + (0x2F819, "M", "仌"), + (0x2F81A, "M", "冬"), + (0x2F81B, "M", "况"), + (0x2F81C, "M", "š©‡Ÿ"), + (0x2F81D, "M", "凵"), + (0x2F81E, "M", "刃"), + (0x2F81F, "M", "擟"), + (0x2F820, "M", "刻"), + (0x2F821, "M", "剆"), + (0x2F822, "M", "割"), + (0x2F823, "M", "剷"), + (0x2F824, "M", "攕"), + (0x2F825, "M", "勇"), + (0x2F826, "M", "勉"), + (0x2F827, "M", "勤"), + (0x2F828, "M", "勺"), + (0x2F829, "M", "包"), + (0x2F82A, "M", "匆"), + (0x2F82B, "M", "北"), + (0x2F82C, "M", "卉"), + (0x2F82D, "M", "卑"), + (0x2F82E, "M", "博"), + (0x2F82F, "M", "即"), + (0x2F830, "M", "卽"), + (0x2F831, "M", "åæ"), + (0x2F834, "M", "𠨬"), + (0x2F835, "M", "灰"), + (0x2F836, "M", "及"), + (0x2F837, "M", "叟"), + (0x2F838, "M", "š ­£"), + (0x2F839, "M", "叫"), + (0x2F83A, "M", "叱"), + (0x2F83B, "M", "吆"), + (0x2F83C, "M", "咞"), + (0x2F83D, "M", "吸"), + (0x2F83E, "M", "呈"), + (0x2F83F, "M", "周"), + (0x2F840, "M", "咢"), ] + def _seg_77() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F83F, 'M', '周'), - (0x2F840, 'M', '咢'), - (0x2F841, 'M', '哶'), - (0x2F842, 'M', '唐'), - (0x2F843, 'M', '啓'), - (0x2F844, 'M', '啣'), - (0x2F845, 'M', '善'), - (0x2F847, 'M', '喙'), - (0x2F848, 'M', '喫'), - (0x2F849, 'M', '喳'), - (0x2F84A, 'M', '嗂'), - (0x2F84B, 'M', '圖'), - (0x2F84C, 'M', '嘆'), - (0x2F84D, 'M', '圗'), - (0x2F84E, 'M', '噑'), - (0x2F84F, 'M', '噓'), - (0x2F850, 'M', '切'), - (0x2F851, 'M', '壮'), - (0x2F852, 'M', '城'), - (0x2F853, 'M', '埓'), - (0x2F854, 'M', '堍'), - (0x2F855, 'M', '型'), - (0x2F856, 'M', 'å ²'), - (0x2F857, 'M', 'å ±'), - (0x2F858, 'M', '墬'), - (0x2F859, 'M', '𔓤'), - (0x2F85A, 'M', '売'), - (0x2F85B, 'M', '壷'), - (0x2F85C, 'M', '夆'), - (0x2F85D, 'M', '多'), - (0x2F85E, 'M', '夢'), - (0x2F85F, 'M', 'å„¢'), - (0x2F860, 'M', '𔚨'), - (0x2F861, 'M', 'š”›Ŗ'), - (0x2F862, 'M', '姬'), - (0x2F863, 'M', '娛'), - (0x2F864, 'M', '娧'), - (0x2F865, 'M', '姘'), - (0x2F866, 'M', '婦'), - (0x2F867, 'M', 'ć›®'), - (0x2F868, 'X'), - (0x2F869, 'M', '嬈'), - (0x2F86A, 'M', '嬾'), - (0x2F86C, 'M', '𔧈'), - (0x2F86D, 'M', '寃'), - (0x2F86E, 'M', '寘'), - (0x2F86F, 'M', '寧'), - (0x2F870, 'M', '寳'), - (0x2F871, 'M', '𔬘'), - (0x2F872, 'M', '寿'), - (0x2F873, 'M', '将'), - (0x2F874, 'X'), - (0x2F875, 'M', 'å°¢'), - (0x2F876, 'M', '极'), - (0x2F877, 'M', 'å± '), - (0x2F878, 'M', 'å±®'), - (0x2F879, 'M', '峀'), - (0x2F87A, 'M', '岍'), - (0x2F87B, 'M', 'š”·¤'), - (0x2F87C, 'M', '嵃'), - (0x2F87D, 'M', 'š”·¦'), - (0x2F87E, 'M', 'åµ®'), - (0x2F87F, 'M', '嵫'), - (0x2F880, 'M', 'åµ¼'), - (0x2F881, 'M', 'å·”'), - (0x2F882, 'M', 'å·¢'), - (0x2F883, 'M', 'ć Æ'), - (0x2F884, 'M', 'å·½'), - (0x2F885, 'M', 'åøØ'), - (0x2F886, 'M', 'åø½'), - (0x2F887, 'M', '幩'), - (0x2F888, 'M', '㔢'), - (0x2F889, 'M', 'š¢†ƒ'), - (0x2F88A, 'M', '㔼'), - (0x2F88B, 'M', 'åŗ°'), - (0x2F88C, 'M', 'åŗ³'), - (0x2F88D, 'M', 'åŗ¶'), - (0x2F88E, 'M', '廊'), - (0x2F88F, 'M', 'šŖŽ’'), - (0x2F890, 'M', '廾'), - (0x2F891, 'M', '𢌱'), - (0x2F893, 'M', '舁'), - (0x2F894, 'M', 'å¼¢'), - (0x2F896, 'M', '㣇'), - (0x2F897, 'M', '𣊸'), - (0x2F898, 'M', 'š¦‡š'), - (0x2F899, 'M', 'å½¢'), - (0x2F89A, 'M', '彫'), - (0x2F89B, 'M', '㣣'), - (0x2F89C, 'M', '徚'), - (0x2F89D, 'M', 'åæ'), - (0x2F89E, 'M', 'åæ—'), - (0x2F89F, 'M', 'åæ¹'), - (0x2F8A0, 'M', 'ꂁ'), - (0x2F8A1, 'M', '㤺'), - (0x2F8A2, 'M', '㤜'), - (0x2F8A3, 'M', 'ꂔ'), - (0x2F8A4, 'M', '𢛔'), - (0x2F8A5, 'M', 'ꃇ'), - (0x2F8A6, 'M', 'ꅈ'), + (0x2F841, "M", "哶"), + (0x2F842, "M", "唐"), + (0x2F843, "M", "啓"), + (0x2F844, "M", "啣"), + (0x2F845, "M", "善"), + (0x2F847, "M", "喙"), + (0x2F848, "M", "喫"), + (0x2F849, "M", "喳"), + (0x2F84A, "M", "嗂"), + (0x2F84B, "M", "圖"), + (0x2F84C, "M", "嘆"), + (0x2F84D, "M", "圗"), + (0x2F84E, "M", "噑"), + (0x2F84F, "M", "噓"), + (0x2F850, "M", "切"), + (0x2F851, "M", "壮"), + (0x2F852, "M", "城"), + (0x2F853, "M", "埓"), + (0x2F854, "M", "堍"), + (0x2F855, "M", "型"), + (0x2F856, "M", "å ²"), + (0x2F857, "M", "å ±"), + (0x2F858, "M", "墬"), + (0x2F859, "M", "𔓤"), + (0x2F85A, "M", "売"), + (0x2F85B, "M", "壷"), + (0x2F85C, "M", "夆"), + (0x2F85D, "M", "多"), + (0x2F85E, "M", "夢"), + (0x2F85F, "M", "å„¢"), + (0x2F860, "M", "𔚨"), + (0x2F861, "M", "š”›Ŗ"), + (0x2F862, "M", "姬"), + (0x2F863, "M", "娛"), + (0x2F864, "M", "娧"), + (0x2F865, "M", "姘"), + (0x2F866, "M", "婦"), + (0x2F867, "M", "ć›®"), + (0x2F868, "X"), + (0x2F869, "M", "嬈"), + (0x2F86A, "M", "嬾"), + (0x2F86C, "M", "𔧈"), + (0x2F86D, "M", "寃"), + (0x2F86E, "M", "寘"), + (0x2F86F, "M", "寧"), + (0x2F870, "M", "寳"), + (0x2F871, "M", "𔬘"), + (0x2F872, "M", "寿"), + (0x2F873, "M", "将"), + (0x2F874, "X"), + (0x2F875, "M", "å°¢"), + (0x2F876, "M", "极"), + (0x2F877, "M", "å± "), + (0x2F878, "M", "å±®"), + (0x2F879, "M", "峀"), + (0x2F87A, "M", "岍"), + (0x2F87B, "M", "š”·¤"), + (0x2F87C, "M", "嵃"), + (0x2F87D, "M", "š”·¦"), + (0x2F87E, "M", "åµ®"), + (0x2F87F, "M", "嵫"), + (0x2F880, "M", "åµ¼"), + (0x2F881, "M", "å·”"), + (0x2F882, "M", "å·¢"), + (0x2F883, "M", "ć Æ"), + (0x2F884, "M", "å·½"), + (0x2F885, "M", "åøØ"), + (0x2F886, "M", "åø½"), + (0x2F887, "M", "幩"), + (0x2F888, "M", "㔢"), + (0x2F889, "M", "š¢†ƒ"), + (0x2F88A, "M", "㔼"), + (0x2F88B, "M", "åŗ°"), + (0x2F88C, "M", "åŗ³"), + (0x2F88D, "M", "åŗ¶"), + (0x2F88E, "M", "廊"), + (0x2F88F, "M", "šŖŽ’"), + (0x2F890, "M", "廾"), + (0x2F891, "M", "𢌱"), + (0x2F893, "M", "舁"), + (0x2F894, "M", "å¼¢"), + (0x2F896, "M", "㣇"), + (0x2F897, "M", "𣊸"), + (0x2F898, "M", "š¦‡š"), + (0x2F899, "M", "å½¢"), + (0x2F89A, "M", "彫"), + (0x2F89B, "M", "㣣"), + (0x2F89C, "M", "徚"), + (0x2F89D, "M", "åæ"), + (0x2F89E, "M", "åæ—"), + (0x2F89F, "M", "åæ¹"), + (0x2F8A0, "M", "ꂁ"), + (0x2F8A1, "M", "㤺"), + (0x2F8A2, "M", "㤜"), + (0x2F8A3, "M", "ꂔ"), + (0x2F8A4, "M", "𢛔"), + (0x2F8A5, "M", "ꃇ"), + (0x2F8A6, "M", "ꅈ"), + (0x2F8A7, "M", "ꅌ"), + (0x2F8A8, "M", "ꅎ"), ] + def _seg_78() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F8A7, 'M', 'ꅌ'), - (0x2F8A8, 'M', 'ꅎ'), - (0x2F8A9, 'M', 'ꅌ'), - (0x2F8AA, 'M', 'ę…ŗ'), - (0x2F8AB, 'M', 'ꆎ'), - (0x2F8AC, 'M', '憲'), - (0x2F8AD, 'M', 'ꆤ'), - (0x2F8AE, 'M', '憯'), - (0x2F8AF, 'M', 'ꇞ'), - (0x2F8B0, 'M', '懲'), - (0x2F8B1, 'M', 'ꇶ'), - (0x2F8B2, 'M', 'ꈐ'), - (0x2F8B3, 'M', 'ꈛ'), - (0x2F8B4, 'M', 'ꉝ'), - (0x2F8B5, 'M', '抱'), - (0x2F8B6, 'M', 'ꋔ'), - (0x2F8B7, 'M', 'ꍐ'), - (0x2F8B8, 'M', '𢬌'), - (0x2F8B9, 'M', '挽'), - (0x2F8BA, 'M', '拼'), - (0x2F8BB, 'M', 'ęØ'), - (0x2F8BC, 'M', 'ꎃ'), - (0x2F8BD, 'M', 'ꏤ'), - (0x2F8BE, 'M', '𢯱'), - (0x2F8BF, 'M', '搢'), - (0x2F8C0, 'M', 'ꏅ'), - (0x2F8C1, 'M', 'ꎩ'), - (0x2F8C2, 'M', '㨮'), - (0x2F8C3, 'M', 'ę‘©'), - (0x2F8C4, 'M', '摾'), - (0x2F8C5, 'M', '꒝'), - (0x2F8C6, 'M', 'ę‘·'), - (0x2F8C7, 'M', '橬'), - (0x2F8C8, 'M', 'ꕏ'), - (0x2F8C9, 'M', 'ꕬ'), - (0x2F8CA, 'M', 'š£€Š'), - (0x2F8CB, 'M', 'ę—£'), - (0x2F8CC, 'M', '書'), - (0x2F8CD, 'M', 'ꙉ'), - (0x2F8CE, 'M', '欙'), - (0x2F8CF, 'M', 'ꚑ'), - (0x2F8D0, 'M', '欈'), - (0x2F8D1, 'M', '櫤'), - (0x2F8D2, 'M', '冒'), - (0x2F8D3, 'M', '冕'), - (0x2F8D4, 'M', '꜀'), - (0x2F8D5, 'M', '暜'), - (0x2F8D6, 'M', '肭'), - (0x2F8D7, 'M', '䏙'), - (0x2F8D8, 'M', 'ꜗ'), - (0x2F8D9, 'M', 'ꜛ'), - (0x2F8DA, 'M', '朔'), - (0x2F8DB, 'M', 'Ꝟ'), - (0x2F8DC, 'M', 'ꝓ'), - (0x2F8DD, 'M', 'š£ƒ'), - (0x2F8DE, 'M', '歉'), - (0x2F8DF, 'M', '柺'), - (0x2F8E0, 'M', 'ꞅ'), - (0x2F8E1, 'M', 'ę”’'), - (0x2F8E2, 'M', '梅'), - (0x2F8E3, 'M', '𣑭'), - (0x2F8E4, 'M', 'ę¢Ž'), - (0x2F8E5, 'M', '栟'), - (0x2F8E6, 'M', 'ꤔ'), - (0x2F8E7, 'M', 'ć®'), - (0x2F8E8, 'M', 'ę„‚'), - (0x2F8E9, 'M', '榣'), - (0x2F8EA, 'M', 'ę§Ŗ'), - (0x2F8EB, 'M', 'ęŖØ'), - (0x2F8EC, 'M', '𣚣'), - (0x2F8ED, 'M', 'ę«›'), - (0x2F8EE, 'M', '氘'), - (0x2F8EF, 'M', 'ꬔ'), - (0x2F8F0, 'M', '𣢧'), - (0x2F8F1, 'M', 'ꭔ'), - (0x2F8F2, 'M', '汎'), - (0x2F8F3, 'M', 'ę­²'), - (0x2F8F4, 'M', '殟'), - (0x2F8F5, 'M', '殺'), - (0x2F8F6, 'M', 'ę®»'), - (0x2F8F7, 'M', 'š£Ŗ'), - (0x2F8F8, 'M', '𔓋'), - (0x2F8F9, 'M', '𣫺'), - (0x2F8FA, 'M', '걎'), - (0x2F8FB, 'M', '𣲼'), - (0x2F8FC, 'M', '沿'), - (0x2F8FD, 'M', 'ę³'), - (0x2F8FE, 'M', 'ę±§'), - (0x2F8FF, 'M', 'ę“–'), - (0x2F900, 'M', '擾'), - (0x2F901, 'M', 'ęµ·'), - (0x2F902, 'M', '굁'), - (0x2F903, 'M', '굩'), - (0x2F904, 'M', 'ęµø'), - (0x2F905, 'M', 'ę¶…'), - (0x2F906, 'M', 'š£“ž'), - (0x2F907, 'M', 'ę““'), - (0x2F908, 'M', 'ęøÆ'), - (0x2F909, 'M', 'ę¹®'), - (0x2F90A, 'M', '㓳'), + (0x2F8A9, "M", "ꅌ"), + (0x2F8AA, "M", "ę…ŗ"), + (0x2F8AB, "M", "ꆎ"), + (0x2F8AC, "M", "憲"), + (0x2F8AD, "M", "ꆤ"), + (0x2F8AE, "M", "憯"), + (0x2F8AF, "M", "ꇞ"), + (0x2F8B0, "M", "懲"), + (0x2F8B1, "M", "ꇶ"), + (0x2F8B2, "M", "ꈐ"), + (0x2F8B3, "M", "ꈛ"), + (0x2F8B4, "M", "ꉝ"), + (0x2F8B5, "M", "抱"), + (0x2F8B6, "M", "ꋔ"), + (0x2F8B7, "M", "ꍐ"), + (0x2F8B8, "M", "𢬌"), + (0x2F8B9, "M", "挽"), + (0x2F8BA, "M", "拼"), + (0x2F8BB, "M", "ęØ"), + (0x2F8BC, "M", "ꎃ"), + (0x2F8BD, "M", "ꏤ"), + (0x2F8BE, "M", "𢯱"), + (0x2F8BF, "M", "搢"), + (0x2F8C0, "M", "ꏅ"), + (0x2F8C1, "M", "ꎩ"), + (0x2F8C2, "M", "㨮"), + (0x2F8C3, "M", "ę‘©"), + (0x2F8C4, "M", "摾"), + (0x2F8C5, "M", "꒝"), + (0x2F8C6, "M", "ę‘·"), + (0x2F8C7, "M", "橬"), + (0x2F8C8, "M", "ꕏ"), + (0x2F8C9, "M", "ꕬ"), + (0x2F8CA, "M", "š£€Š"), + (0x2F8CB, "M", "ę—£"), + (0x2F8CC, "M", "書"), + (0x2F8CD, "M", "ꙉ"), + (0x2F8CE, "M", "欙"), + (0x2F8CF, "M", "ꚑ"), + (0x2F8D0, "M", "欈"), + (0x2F8D1, "M", "櫤"), + (0x2F8D2, "M", "冒"), + (0x2F8D3, "M", "冕"), + (0x2F8D4, "M", "꜀"), + (0x2F8D5, "M", "暜"), + (0x2F8D6, "M", "肭"), + (0x2F8D7, "M", "䏙"), + (0x2F8D8, "M", "ꜗ"), + (0x2F8D9, "M", "ꜛ"), + (0x2F8DA, "M", "朔"), + (0x2F8DB, "M", "Ꝟ"), + (0x2F8DC, "M", "ꝓ"), + (0x2F8DD, "M", "š£ƒ"), + (0x2F8DE, "M", "歉"), + (0x2F8DF, "M", "柺"), + (0x2F8E0, "M", "ꞅ"), + (0x2F8E1, "M", "ę”’"), + (0x2F8E2, "M", "梅"), + (0x2F8E3, "M", "𣑭"), + (0x2F8E4, "M", "ę¢Ž"), + (0x2F8E5, "M", "栟"), + (0x2F8E6, "M", "ꤔ"), + (0x2F8E7, "M", "ć®"), + (0x2F8E8, "M", "ę„‚"), + (0x2F8E9, "M", "榣"), + (0x2F8EA, "M", "ę§Ŗ"), + (0x2F8EB, "M", "ęŖØ"), + (0x2F8EC, "M", "𣚣"), + (0x2F8ED, "M", "ę«›"), + (0x2F8EE, "M", "氘"), + (0x2F8EF, "M", "ꬔ"), + (0x2F8F0, "M", "𣢧"), + (0x2F8F1, "M", "ꭔ"), + (0x2F8F2, "M", "汎"), + (0x2F8F3, "M", "ę­²"), + (0x2F8F4, "M", "殟"), + (0x2F8F5, "M", "殺"), + (0x2F8F6, "M", "ę®»"), + (0x2F8F7, "M", "š£Ŗ"), + (0x2F8F8, "M", "𔓋"), + (0x2F8F9, "M", "𣫺"), + (0x2F8FA, "M", "걎"), + (0x2F8FB, "M", "𣲼"), + (0x2F8FC, "M", "沿"), + (0x2F8FD, "M", "ę³"), + (0x2F8FE, "M", "ę±§"), + (0x2F8FF, "M", "ę“–"), + (0x2F900, "M", "擾"), + (0x2F901, "M", "ęµ·"), + (0x2F902, "M", "굁"), + (0x2F903, "M", "굩"), + (0x2F904, "M", "ęµø"), + (0x2F905, "M", "ę¶…"), + (0x2F906, "M", "š£“ž"), + (0x2F907, "M", "ę““"), + (0x2F908, "M", "ęøÆ"), + (0x2F909, "M", "ę¹®"), + (0x2F90A, "M", "㓳"), + (0x2F90B, "M", "껋"), + (0x2F90C, "M", "껇"), ] + def _seg_79() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F90B, 'M', '껋'), - (0x2F90C, 'M', '껇'), - (0x2F90D, 'M', '𣻑'), - (0x2F90E, 'M', 'ę·¹'), - (0x2F90F, 'M', 'ę½®'), - (0x2F910, 'M', 'š£½ž'), - (0x2F911, 'M', 'š£¾Ž'), - (0x2F912, 'M', '濆'), - (0x2F913, 'M', '瀹'), - (0x2F914, 'M', 'ē€ž'), - (0x2F915, 'M', '瀛'), - (0x2F916, 'M', 'ć¶–'), - (0x2F917, 'M', '灊'), - (0x2F918, 'M', '災'), - (0x2F919, 'M', '灷'), - (0x2F91A, 'M', 'ē‚­'), - (0x2F91B, 'M', 'š ”„'), - (0x2F91C, 'M', 'ē……'), - (0x2F91D, 'M', '𤉣'), - (0x2F91E, 'M', 'ē†œ'), - (0x2F91F, 'X'), - (0x2F920, 'M', '爨'), - (0x2F921, 'M', '爵'), - (0x2F922, 'M', '牐'), - (0x2F923, 'M', '𤘈'), - (0x2F924, 'M', 'ēŠ€'), - (0x2F925, 'M', 'ēŠ•'), - (0x2F926, 'M', '𤜵'), - (0x2F927, 'M', '𤠔'), - (0x2F928, 'M', 'ēŗ'), - (0x2F929, 'M', 'ēŽ‹'), - (0x2F92A, 'M', 'ćŗ¬'), - (0x2F92B, 'M', 'ēŽ„'), - (0x2F92C, 'M', 'ćŗø'), - (0x2F92E, 'M', '瑇'), - (0x2F92F, 'M', 'ē‘œ'), - (0x2F930, 'M', '瑱'), - (0x2F931, 'M', 'ē’…'), - (0x2F932, 'M', 'ē“Š'), - (0x2F933, 'M', 'ć¼›'), - (0x2F934, 'M', '甤'), - (0x2F935, 'M', '𤰶'), - (0x2F936, 'M', '甾'), - (0x2F937, 'M', '𤲒'), - (0x2F938, 'M', 'ē•°'), - (0x2F939, 'M', 'š¢†Ÿ'), - (0x2F93A, 'M', '瘐'), - (0x2F93B, 'M', '𤾔'), - (0x2F93C, 'M', '𤾸'), - (0x2F93D, 'M', 'š„„'), - (0x2F93E, 'M', 'ćæ¼'), - (0x2F93F, 'M', '䀈'), - (0x2F940, 'M', '盓'), - (0x2F941, 'M', 'š„ƒ³'), - (0x2F942, 'M', 'š„ƒ²'), - (0x2F943, 'M', 'š„„™'), - (0x2F944, 'M', 'š„„³'), - (0x2F945, 'M', 'ēœž'), - (0x2F946, 'M', '真'), - (0x2F948, 'M', 'ēŠ'), - (0x2F949, 'M', '䀹'), - (0x2F94A, 'M', 'ēž‹'), - (0x2F94B, 'M', '䁆'), - (0x2F94C, 'M', '䂖'), - (0x2F94D, 'M', 'š„'), - (0x2F94E, 'M', 'ē”Ž'), - (0x2F94F, 'M', '碌'), - (0x2F950, 'M', '磌'), - (0x2F951, 'M', '䃣'), - (0x2F952, 'M', 'š„˜¦'), - (0x2F953, 'M', 'ē„–'), - (0x2F954, 'M', 'š„šš'), - (0x2F955, 'M', 'š„›…'), - (0x2F956, 'M', 'ē¦'), - (0x2F957, 'M', 'ē§«'), - (0x2F958, 'M', '䄯'), - (0x2F959, 'M', 'ē©€'), - (0x2F95A, 'M', '穊'), - (0x2F95B, 'M', 'ē©'), - (0x2F95C, 'M', 'š„„¼'), - (0x2F95D, 'M', 'š„Ŗ§'), - (0x2F95F, 'X'), - (0x2F960, 'M', '䈂'), - (0x2F961, 'M', 'š„®«'), - (0x2F962, 'M', '篆'), - (0x2F963, 'M', '築'), - (0x2F964, 'M', '䈧'), - (0x2F965, 'M', 'š„²€'), - (0x2F966, 'M', 'ē³’'), - (0x2F967, 'M', '䊠'), - (0x2F968, 'M', '糨'), - (0x2F969, 'M', 'ē³£'), - (0x2F96A, 'M', 'ē“€'), - (0x2F96B, 'M', 'š„¾†'), - (0x2F96C, 'M', 'ēµ£'), - (0x2F96D, 'M', '䌁'), - (0x2F96E, 'M', 'ē·‡'), - (0x2F96F, 'M', 'ēø‚'), - (0x2F970, 'M', 'ē¹…'), - (0x2F971, 'M', '䌓'), + (0x2F90D, "M", "𣻑"), + (0x2F90E, "M", "ę·¹"), + (0x2F90F, "M", "ę½®"), + (0x2F910, "M", "š£½ž"), + (0x2F911, "M", "š£¾Ž"), + (0x2F912, "M", "濆"), + (0x2F913, "M", "瀹"), + (0x2F914, "M", "ē€ž"), + (0x2F915, "M", "瀛"), + (0x2F916, "M", "ć¶–"), + (0x2F917, "M", "灊"), + (0x2F918, "M", "災"), + (0x2F919, "M", "灷"), + (0x2F91A, "M", "ē‚­"), + (0x2F91B, "M", "š ”„"), + (0x2F91C, "M", "ē……"), + (0x2F91D, "M", "𤉣"), + (0x2F91E, "M", "ē†œ"), + (0x2F91F, "X"), + (0x2F920, "M", "爨"), + (0x2F921, "M", "爵"), + (0x2F922, "M", "牐"), + (0x2F923, "M", "𤘈"), + (0x2F924, "M", "ēŠ€"), + (0x2F925, "M", "ēŠ•"), + (0x2F926, "M", "𤜵"), + (0x2F927, "M", "𤠔"), + (0x2F928, "M", "ēŗ"), + (0x2F929, "M", "ēŽ‹"), + (0x2F92A, "M", "ćŗ¬"), + (0x2F92B, "M", "ēŽ„"), + (0x2F92C, "M", "ćŗø"), + (0x2F92E, "M", "瑇"), + (0x2F92F, "M", "ē‘œ"), + (0x2F930, "M", "瑱"), + (0x2F931, "M", "ē’…"), + (0x2F932, "M", "ē“Š"), + (0x2F933, "M", "ć¼›"), + (0x2F934, "M", "甤"), + (0x2F935, "M", "𤰶"), + (0x2F936, "M", "甾"), + (0x2F937, "M", "𤲒"), + (0x2F938, "M", "ē•°"), + (0x2F939, "M", "š¢†Ÿ"), + (0x2F93A, "M", "瘐"), + (0x2F93B, "M", "𤾔"), + (0x2F93C, "M", "𤾸"), + (0x2F93D, "M", "š„„"), + (0x2F93E, "M", "ćæ¼"), + (0x2F93F, "M", "䀈"), + (0x2F940, "M", "盓"), + (0x2F941, "M", "š„ƒ³"), + (0x2F942, "M", "š„ƒ²"), + (0x2F943, "M", "š„„™"), + (0x2F944, "M", "š„„³"), + (0x2F945, "M", "ēœž"), + (0x2F946, "M", "真"), + (0x2F948, "M", "ēŠ"), + (0x2F949, "M", "䀹"), + (0x2F94A, "M", "ēž‹"), + (0x2F94B, "M", "䁆"), + (0x2F94C, "M", "䂖"), + (0x2F94D, "M", "š„"), + (0x2F94E, "M", "ē”Ž"), + (0x2F94F, "M", "碌"), + (0x2F950, "M", "磌"), + (0x2F951, "M", "䃣"), + (0x2F952, "M", "š„˜¦"), + (0x2F953, "M", "ē„–"), + (0x2F954, "M", "š„šš"), + (0x2F955, "M", "š„›…"), + (0x2F956, "M", "ē¦"), + (0x2F957, "M", "ē§«"), + (0x2F958, "M", "䄯"), + (0x2F959, "M", "ē©€"), + (0x2F95A, "M", "穊"), + (0x2F95B, "M", "ē©"), + (0x2F95C, "M", "š„„¼"), + (0x2F95D, "M", "š„Ŗ§"), + (0x2F95F, "X"), + (0x2F960, "M", "䈂"), + (0x2F961, "M", "š„®«"), + (0x2F962, "M", "篆"), + (0x2F963, "M", "築"), + (0x2F964, "M", "䈧"), + (0x2F965, "M", "š„²€"), + (0x2F966, "M", "ē³’"), + (0x2F967, "M", "䊠"), + (0x2F968, "M", "糨"), + (0x2F969, "M", "ē³£"), + (0x2F96A, "M", "ē“€"), + (0x2F96B, "M", "š„¾†"), + (0x2F96C, "M", "ēµ£"), + (0x2F96D, "M", "䌁"), + (0x2F96E, "M", "ē·‡"), + (0x2F96F, "M", "ēø‚"), + (0x2F970, "M", "ē¹…"), + (0x2F971, "M", "䌓"), + (0x2F972, "M", "𦈨"), + (0x2F973, "M", "𦉇"), ] + def _seg_80() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F972, 'M', '𦈨'), - (0x2F973, 'M', '𦉇'), - (0x2F974, 'M', '䍙'), - (0x2F975, 'M', '𦋙'), - (0x2F976, 'M', 'ē½ŗ'), - (0x2F977, 'M', '𦌾'), - (0x2F978, 'M', '羕'), - (0x2F979, 'M', 'ēæŗ'), - (0x2F97A, 'M', '者'), - (0x2F97B, 'M', 'š¦“š'), - (0x2F97C, 'M', '𦔣'), - (0x2F97D, 'M', '聠'), - (0x2F97E, 'M', '𦖨'), - (0x2F97F, 'M', '聰'), - (0x2F980, 'M', 'š£Ÿ'), - (0x2F981, 'M', '䏕'), - (0x2F982, 'M', '育'), - (0x2F983, 'M', '脃'), - (0x2F984, 'M', '䐋'), - (0x2F985, 'M', '脾'), - (0x2F986, 'M', 'åŖµ'), - (0x2F987, 'M', 'š¦ž§'), - (0x2F988, 'M', 'š¦žµ'), - (0x2F989, 'M', 'š£Ž“'), - (0x2F98A, 'M', 'š£Žœ'), - (0x2F98B, 'M', '舁'), - (0x2F98C, 'M', '舄'), - (0x2F98D, 'M', 'č¾ž'), - (0x2F98E, 'M', '䑫'), - (0x2F98F, 'M', '芑'), - (0x2F990, 'M', '芋'), - (0x2F991, 'M', '芝'), - (0x2F992, 'M', '劳'), - (0x2F993, 'M', '花'), - (0x2F994, 'M', '芳'), - (0x2F995, 'M', '芽'), - (0x2F996, 'M', '苦'), - (0x2F997, 'M', '𦬼'), - (0x2F998, 'M', 'č‹„'), - (0x2F999, 'M', '茝'), - (0x2F99A, 'M', 'č£'), - (0x2F99B, 'M', '莭'), - (0x2F99C, 'M', '茣'), - (0x2F99D, 'M', 'čŽ½'), - (0x2F99E, 'M', '菧'), - (0x2F99F, 'M', '著'), - (0x2F9A0, 'M', '荓'), - (0x2F9A1, 'M', '菊'), - (0x2F9A2, 'M', '菌'), - (0x2F9A3, 'M', '菜'), - (0x2F9A4, 'M', '𦰶'), - (0x2F9A5, 'M', '𦵫'), - (0x2F9A6, 'M', '𦳕'), - (0x2F9A7, 'M', '䔫'), - (0x2F9A8, 'M', '蓱'), - (0x2F9A9, 'M', '蓳'), - (0x2F9AA, 'M', '蔖'), - (0x2F9AB, 'M', 'š§Š'), - (0x2F9AC, 'M', '蕤'), - (0x2F9AD, 'M', '𦼬'), - (0x2F9AE, 'M', '䕝'), - (0x2F9AF, 'M', 'ä•”'), - (0x2F9B0, 'M', '𦾱'), - (0x2F9B1, 'M', 'š§ƒ’'), - (0x2F9B2, 'M', '䕫'), - (0x2F9B3, 'M', '虐'), - (0x2F9B4, 'M', '虜'), - (0x2F9B5, 'M', '虧'), - (0x2F9B6, 'M', '虩'), - (0x2F9B7, 'M', '蚩'), - (0x2F9B8, 'M', '蚈'), - (0x2F9B9, 'M', '蜎'), - (0x2F9BA, 'M', '蛢'), - (0x2F9BB, 'M', 'č¹'), - (0x2F9BC, 'M', '蜨'), - (0x2F9BD, 'M', 'č«'), - (0x2F9BE, 'M', '螆'), - (0x2F9BF, 'X'), - (0x2F9C0, 'M', '蟔'), - (0x2F9C1, 'M', '蠁'), - (0x2F9C2, 'M', '䗹'), - (0x2F9C3, 'M', 'č” '), - (0x2F9C4, 'M', '蔣'), - (0x2F9C5, 'M', 'š§™§'), - (0x2F9C6, 'M', '裗'), - (0x2F9C7, 'M', 'č£ž'), - (0x2F9C8, 'M', '䘵'), - (0x2F9C9, 'M', '裺'), - (0x2F9CA, 'M', 'ć’»'), - (0x2F9CB, 'M', 'š§¢®'), - (0x2F9CC, 'M', '𧄦'), - (0x2F9CD, 'M', '䚾'), - (0x2F9CE, 'M', '䛇'), - (0x2F9CF, 'M', 'čŖ '), - (0x2F9D0, 'M', 'č«­'), - (0x2F9D1, 'M', '變'), - (0x2F9D2, 'M', '豕'), - (0x2F9D3, 'M', '𧲨'), - (0x2F9D4, 'M', '貫'), - (0x2F9D5, 'M', '賁'), + (0x2F974, "M", "䍙"), + (0x2F975, "M", "𦋙"), + (0x2F976, "M", "ē½ŗ"), + (0x2F977, "M", "𦌾"), + (0x2F978, "M", "羕"), + (0x2F979, "M", "ēæŗ"), + (0x2F97A, "M", "者"), + (0x2F97B, "M", "š¦“š"), + (0x2F97C, "M", "𦔣"), + (0x2F97D, "M", "聠"), + (0x2F97E, "M", "𦖨"), + (0x2F97F, "M", "聰"), + (0x2F980, "M", "š£Ÿ"), + (0x2F981, "M", "䏕"), + (0x2F982, "M", "育"), + (0x2F983, "M", "脃"), + (0x2F984, "M", "䐋"), + (0x2F985, "M", "脾"), + (0x2F986, "M", "åŖµ"), + (0x2F987, "M", "š¦ž§"), + (0x2F988, "M", "š¦žµ"), + (0x2F989, "M", "š£Ž“"), + (0x2F98A, "M", "š£Žœ"), + (0x2F98B, "M", "舁"), + (0x2F98C, "M", "舄"), + (0x2F98D, "M", "č¾ž"), + (0x2F98E, "M", "䑫"), + (0x2F98F, "M", "芑"), + (0x2F990, "M", "芋"), + (0x2F991, "M", "芝"), + (0x2F992, "M", "劳"), + (0x2F993, "M", "花"), + (0x2F994, "M", "芳"), + (0x2F995, "M", "芽"), + (0x2F996, "M", "苦"), + (0x2F997, "M", "𦬼"), + (0x2F998, "M", "č‹„"), + (0x2F999, "M", "茝"), + (0x2F99A, "M", "č£"), + (0x2F99B, "M", "莭"), + (0x2F99C, "M", "茣"), + (0x2F99D, "M", "čŽ½"), + (0x2F99E, "M", "菧"), + (0x2F99F, "M", "著"), + (0x2F9A0, "M", "荓"), + (0x2F9A1, "M", "菊"), + (0x2F9A2, "M", "菌"), + (0x2F9A3, "M", "菜"), + (0x2F9A4, "M", "𦰶"), + (0x2F9A5, "M", "𦵫"), + (0x2F9A6, "M", "𦳕"), + (0x2F9A7, "M", "䔫"), + (0x2F9A8, "M", "蓱"), + (0x2F9A9, "M", "蓳"), + (0x2F9AA, "M", "蔖"), + (0x2F9AB, "M", "š§Š"), + (0x2F9AC, "M", "蕤"), + (0x2F9AD, "M", "𦼬"), + (0x2F9AE, "M", "䕝"), + (0x2F9AF, "M", "ä•”"), + (0x2F9B0, "M", "𦾱"), + (0x2F9B1, "M", "š§ƒ’"), + (0x2F9B2, "M", "䕫"), + (0x2F9B3, "M", "虐"), + (0x2F9B4, "M", "虜"), + (0x2F9B5, "M", "虧"), + (0x2F9B6, "M", "虩"), + (0x2F9B7, "M", "蚩"), + (0x2F9B8, "M", "蚈"), + (0x2F9B9, "M", "蜎"), + (0x2F9BA, "M", "蛢"), + (0x2F9BB, "M", "č¹"), + (0x2F9BC, "M", "蜨"), + (0x2F9BD, "M", "č«"), + (0x2F9BE, "M", "螆"), + (0x2F9BF, "X"), + (0x2F9C0, "M", "蟔"), + (0x2F9C1, "M", "蠁"), + (0x2F9C2, "M", "䗹"), + (0x2F9C3, "M", "č” "), + (0x2F9C4, "M", "蔣"), + (0x2F9C5, "M", "š§™§"), + (0x2F9C6, "M", "裗"), + (0x2F9C7, "M", "č£ž"), + (0x2F9C8, "M", "䘵"), + (0x2F9C9, "M", "裺"), + (0x2F9CA, "M", "ć’»"), + (0x2F9CB, "M", "š§¢®"), + (0x2F9CC, "M", "𧄦"), + (0x2F9CD, "M", "䚾"), + (0x2F9CE, "M", "䛇"), + (0x2F9CF, "M", "čŖ "), + (0x2F9D0, "M", "č«­"), + (0x2F9D1, "M", "變"), + (0x2F9D2, "M", "豕"), + (0x2F9D3, "M", "𧲨"), + (0x2F9D4, "M", "貫"), + (0x2F9D5, "M", "賁"), + (0x2F9D6, "M", "č“›"), + (0x2F9D7, "M", "čµ·"), ] + def _seg_81() -> List[Union[Tuple[int, str], Tuple[int, str, str]]]: return [ - (0x2F9D6, 'M', 'č“›'), - (0x2F9D7, 'M', 'čµ·'), - (0x2F9D8, 'M', '𧼯'), - (0x2F9D9, 'M', 'š  „'), - (0x2F9DA, 'M', 'č·‹'), - (0x2F9DB, 'M', 'č¶¼'), - (0x2F9DC, 'M', 'č·°'), - (0x2F9DD, 'M', 'š £ž'), - (0x2F9DE, 'M', 'č»”'), - (0x2F9DF, 'M', 'č¼ø'), - (0x2F9E0, 'M', '𨗒'), - (0x2F9E1, 'M', '𨗭'), - (0x2F9E2, 'M', '邔'), - (0x2F9E3, 'M', '郱'), - (0x2F9E4, 'M', '鄑'), - (0x2F9E5, 'M', '𨜮'), - (0x2F9E6, 'M', '鄛'), - (0x2F9E7, 'M', '鈸'), - (0x2F9E8, 'M', '鋗'), - (0x2F9E9, 'M', '鋘'), - (0x2F9EA, 'M', '鉼'), - (0x2F9EB, 'M', '鏹'), - (0x2F9EC, 'M', '鐕'), - (0x2F9ED, 'M', '𨯺'), - (0x2F9EE, 'M', '開'), - (0x2F9EF, 'M', '䦕'), - (0x2F9F0, 'M', '閷'), - (0x2F9F1, 'M', '𨵷'), - (0x2F9F2, 'M', '䧦'), - (0x2F9F3, 'M', '雃'), - (0x2F9F4, 'M', 'å¶²'), - (0x2F9F5, 'M', '霣'), - (0x2F9F6, 'M', 'š©……'), - (0x2F9F7, 'M', '𩈚'), - (0x2F9F8, 'M', 'ä©®'), - (0x2F9F9, 'M', 'ä©¶'), - (0x2F9FA, 'M', '韠'), - (0x2F9FB, 'M', '𩐊'), - (0x2F9FC, 'M', 'äŖ²'), - (0x2F9FD, 'M', 'š©’–'), - (0x2F9FE, 'M', '頋'), - (0x2FA00, 'M', 'é ©'), - (0x2FA01, 'M', 'š©–¶'), - (0x2FA02, 'M', '飢'), - (0x2FA03, 'M', '䬳'), - (0x2FA04, 'M', '餩'), - (0x2FA05, 'M', '馧'), - (0x2FA06, 'M', '駂'), - (0x2FA07, 'M', 'é§¾'), - (0x2FA08, 'M', 'äÆŽ'), - (0x2FA09, 'M', '𩬰'), - (0x2FA0A, 'M', '鬒'), - (0x2FA0B, 'M', '鱀'), - (0x2FA0C, 'M', 'é³½'), - (0x2FA0D, 'M', '䳎'), - (0x2FA0E, 'M', 'ä³­'), - (0x2FA0F, 'M', 'éµ§'), - (0x2FA10, 'M', 'šŖƒŽ'), - (0x2FA11, 'M', 'ä³ø'), - (0x2FA12, 'M', 'šŖ„…'), - (0x2FA13, 'M', 'šŖˆŽ'), - (0x2FA14, 'M', 'šŖŠ‘'), - (0x2FA15, 'M', 'éŗ»'), - (0x2FA16, 'M', '䵖'), - (0x2FA17, 'M', '黹'), - (0x2FA18, 'M', '黾'), - (0x2FA19, 'M', '鼅'), - (0x2FA1A, 'M', '鼏'), - (0x2FA1B, 'M', '鼖'), - (0x2FA1C, 'M', 'é¼»'), - (0x2FA1D, 'M', 'šŖ˜€'), - (0x2FA1E, 'X'), - (0x30000, 'V'), - (0x3134B, 'X'), - (0x31350, 'V'), - (0x323B0, 'X'), - (0xE0100, 'I'), - (0xE01F0, 'X'), + (0x2F9D8, "M", "𧼯"), + (0x2F9D9, "M", "š  „"), + (0x2F9DA, "M", "č·‹"), + (0x2F9DB, "M", "č¶¼"), + (0x2F9DC, "M", "č·°"), + (0x2F9DD, "M", "š £ž"), + (0x2F9DE, "M", "č»”"), + (0x2F9DF, "M", "č¼ø"), + (0x2F9E0, "M", "𨗒"), + (0x2F9E1, "M", "𨗭"), + (0x2F9E2, "M", "邔"), + (0x2F9E3, "M", "郱"), + (0x2F9E4, "M", "鄑"), + (0x2F9E5, "M", "𨜮"), + (0x2F9E6, "M", "鄛"), + (0x2F9E7, "M", "鈸"), + (0x2F9E8, "M", "鋗"), + (0x2F9E9, "M", "鋘"), + (0x2F9EA, "M", "鉼"), + (0x2F9EB, "M", "鏹"), + (0x2F9EC, "M", "鐕"), + (0x2F9ED, "M", "𨯺"), + (0x2F9EE, "M", "開"), + (0x2F9EF, "M", "䦕"), + (0x2F9F0, "M", "閷"), + (0x2F9F1, "M", "𨵷"), + (0x2F9F2, "M", "䧦"), + (0x2F9F3, "M", "雃"), + (0x2F9F4, "M", "å¶²"), + (0x2F9F5, "M", "霣"), + (0x2F9F6, "M", "š©……"), + (0x2F9F7, "M", "𩈚"), + (0x2F9F8, "M", "ä©®"), + (0x2F9F9, "M", "ä©¶"), + (0x2F9FA, "M", "韠"), + (0x2F9FB, "M", "𩐊"), + (0x2F9FC, "M", "äŖ²"), + (0x2F9FD, "M", "š©’–"), + (0x2F9FE, "M", "頋"), + (0x2FA00, "M", "é ©"), + (0x2FA01, "M", "š©–¶"), + (0x2FA02, "M", "飢"), + (0x2FA03, "M", "䬳"), + (0x2FA04, "M", "餩"), + (0x2FA05, "M", "馧"), + (0x2FA06, "M", "駂"), + (0x2FA07, "M", "é§¾"), + (0x2FA08, "M", "äÆŽ"), + (0x2FA09, "M", "𩬰"), + (0x2FA0A, "M", "鬒"), + (0x2FA0B, "M", "鱀"), + (0x2FA0C, "M", "é³½"), + (0x2FA0D, "M", "䳎"), + (0x2FA0E, "M", "ä³­"), + (0x2FA0F, "M", "éµ§"), + (0x2FA10, "M", "šŖƒŽ"), + (0x2FA11, "M", "ä³ø"), + (0x2FA12, "M", "šŖ„…"), + (0x2FA13, "M", "šŖˆŽ"), + (0x2FA14, "M", "šŖŠ‘"), + (0x2FA15, "M", "éŗ»"), + (0x2FA16, "M", "䵖"), + (0x2FA17, "M", "黹"), + (0x2FA18, "M", "黾"), + (0x2FA19, "M", "鼅"), + (0x2FA1A, "M", "鼏"), + (0x2FA1B, "M", "鼖"), + (0x2FA1C, "M", "é¼»"), + (0x2FA1D, "M", "šŖ˜€"), + (0x2FA1E, "X"), + (0x30000, "V"), + (0x3134B, "X"), + (0x31350, "V"), + (0x323B0, "X"), + (0xE0100, "I"), + (0xE01F0, "X"), ] + uts46data = tuple( _seg_0() + _seg_1() diff --git a/vendor/requests/__init__.py b/vendor/requests/__init__.py index 300a16c..051cda1 100644 --- a/vendor/requests/__init__.py +++ b/vendor/requests/__init__.py @@ -83,7 +83,11 @@ def check_compatibility(urllib3_version, chardet_version, charset_normalizer_ver # charset_normalizer >= 2.0.0 < 4.0.0 assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0) else: - raise Exception("You need either charset_normalizer or chardet installed") + warnings.warn( + "Unable to find acceptable character detection dependency " + "(chardet or charset_normalizer).", + RequestsDependencyWarning, + ) def _check_cryptography(cryptography_version): diff --git a/vendor/requests/__version__.py b/vendor/requests/__version__.py index e0f3373..2c105ac 100644 --- a/vendor/requests/__version__.py +++ b/vendor/requests/__version__.py @@ -5,10 +5,10 @@ __title__ = "requests" __description__ = "Python HTTP for Humans." __url__ = "https://requests.readthedocs.io" -__version__ = "2.30.0" -__build__ = 0x023000 +__version__ = "2.32.3" +__build__ = 0x023203 __author__ = "Kenneth Reitz" __author_email__ = "me@kennethreitz.org" -__license__ = "Apache 2.0" +__license__ = "Apache-2.0" __copyright__ = "Copyright Kenneth Reitz" __cake__ = "\u2728 \U0001f370 \u2728" diff --git a/vendor/requests/adapters.py b/vendor/requests/adapters.py index 78e3bb6..9a58b16 100644 --- a/vendor/requests/adapters.py +++ b/vendor/requests/adapters.py @@ -8,6 +8,8 @@ import os.path import socket # noqa: F401 +import typing +import warnings from urllib3.exceptions import ClosedPoolError, ConnectTimeoutError from urllib3.exceptions import HTTPError as _HTTPError @@ -25,6 +27,7 @@ from urllib3.util import Timeout as TimeoutSauce from urllib3.util import parse_url from urllib3.util.retry import Retry +from urllib3.util.ssl_ import create_urllib3_context from .auth import _basic_auth_str from .compat import basestring, urlparse @@ -61,12 +64,76 @@ def SOCKSProxyManager(*args, **kwargs): raise InvalidSchema("Missing dependencies for SOCKS support.") +if typing.TYPE_CHECKING: + from .models import PreparedRequest + + DEFAULT_POOLBLOCK = False DEFAULT_POOLSIZE = 10 DEFAULT_RETRIES = 0 DEFAULT_POOL_TIMEOUT = None +try: + import ssl # noqa: F401 + + _preloaded_ssl_context = create_urllib3_context() + _preloaded_ssl_context.load_verify_locations( + extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + ) +except ImportError: + # Bypass default SSLContext creation when Python + # interpreter isn't built with the ssl module. + _preloaded_ssl_context = None + + +def _urllib3_request_context( + request: "PreparedRequest", + verify: "bool | str | None", + client_cert: "typing.Tuple[str, str] | str | None", + poolmanager: "PoolManager", +) -> "(typing.Dict[str, typing.Any], typing.Dict[str, typing.Any])": + host_params = {} + pool_kwargs = {} + parsed_request_url = urlparse(request.url) + scheme = parsed_request_url.scheme.lower() + port = parsed_request_url.port + + # Determine if we have and should use our default SSLContext + # to optimize performance on standard requests. + poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {}) + has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context") + should_use_default_ssl_context = ( + _preloaded_ssl_context is not None and not has_poolmanager_ssl_context + ) + + cert_reqs = "CERT_REQUIRED" + if verify is False: + cert_reqs = "CERT_NONE" + elif verify is True and should_use_default_ssl_context: + pool_kwargs["ssl_context"] = _preloaded_ssl_context + elif isinstance(verify, str): + if not os.path.isdir(verify): + pool_kwargs["ca_certs"] = verify + else: + pool_kwargs["ca_cert_dir"] = verify + pool_kwargs["cert_reqs"] = cert_reqs + if client_cert is not None: + if isinstance(client_cert, tuple) and len(client_cert) == 2: + pool_kwargs["cert_file"] = client_cert[0] + pool_kwargs["key_file"] = client_cert[1] + else: + # According to our docs, we allow users to specify just the client + # cert path + pool_kwargs["cert_file"] = client_cert + host_params = { + "scheme": scheme, + "host": parsed_request_url.hostname, + "port": port, + } + return host_params, pool_kwargs + + class BaseAdapter: """The Base Transport Adapter""" @@ -247,28 +314,26 @@ def cert_verify(self, conn, url, verify, cert): :param cert: The SSL certificate to verify. """ if url.lower().startswith("https") and verify: + conn.cert_reqs = "CERT_REQUIRED" - cert_loc = None - - # Allow self-specified cert location. + # Only load the CA certificates if 'verify' is a string indicating the CA bundle to use. + # Otherwise, if verify is a boolean, we don't load anything since + # the connection will be using a context with the default certificates already loaded, + # and this avoids a call to the slow load_verify_locations() if verify is not True: + # `verify` must be a str with a path then cert_loc = verify - if not cert_loc: - cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + if not os.path.exists(cert_loc): + raise OSError( + f"Could not find a suitable TLS CA certificate bundle, " + f"invalid path: {cert_loc}" + ) - if not cert_loc or not os.path.exists(cert_loc): - raise OSError( - f"Could not find a suitable TLS CA certificate bundle, " - f"invalid path: {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 + 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 @@ -328,8 +393,110 @@ def build_response(self, req, resp): return response + def build_connection_pool_key_attributes(self, request, verify, cert=None): + """Build the PoolKey attributes used by urllib3 to return a connection. + + This looks at the PreparedRequest, the user-specified verify value, + and the value of the cert parameter to determine what PoolKey values + to use to select a connection from a given urllib3 Connection Pool. + + The SSL related pool key arguments are not consistently set. As of + this writing, use the following to determine what keys may be in that + dictionary: + + * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the + default Requests SSL Context + * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but + ``"cert_reqs"`` will be set + * If ``verify`` is a string, (i.e., it is a user-specified trust bundle) + ``"ca_certs"`` will be set if the string is not a directory recognized + by :py:func:`os.path.isdir`, otherwise ``"ca_certs_dir"`` will be + set. + * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If + ``"cert"`` is a tuple with a second item, ``"key_file"`` will also + be present + + To override these settings, one may subclass this class, call this + method and use the above logic to change parameters as desired. For + example, if one wishes to use a custom :py:class:`ssl.SSLContext` one + must both set ``"ssl_context"`` and based on what else they require, + alter the other keys to ensure the desired behaviour. + + :param request: + The PreparedReqest being sent over the connection. + :type request: + :class:`~requests.models.PreparedRequest` + :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: + (optional) Any user-provided SSL certificate for client + authentication (a.k.a., mTLS). This may be a string (i.e., just + the path to a file which holds both certificate and key) or a + tuple of length 2 with the certificate file path and key file + path. + :returns: + A tuple of two dictionaries. The first is the "host parameters" + portion of the Pool Key including scheme, hostname, and port. The + second is a dictionary of SSLContext related parameters. + """ + return _urllib3_request_context(request, verify, cert, self.poolmanager) + + def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None): + """Returns a urllib3 connection for the given request and TLS settings. + This should not be called from user code, and is only exposed for use + when subclassing the :class:`HTTPAdapter `. + + :param request: + The :class:`PreparedRequest ` object to be sent + over the connection. + :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 proxies: + (optional) The proxies dictionary to apply to the request. + :param cert: + (optional) Any user-provided SSL certificate to be used for client + authentication (a.k.a., mTLS). + :rtype: + urllib3.ConnectionPool + """ + proxy = select_proxy(request.url, proxies) + try: + host_params, pool_kwargs = self.build_connection_pool_key_attributes( + request, + verify, + cert, + ) + except ValueError as e: + raise InvalidURL(e, request=request) + 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_host( + **host_params, pool_kwargs=pool_kwargs + ) + else: + # Only scheme should be lower case + conn = self.poolmanager.connection_from_host( + **host_params, pool_kwargs=pool_kwargs + ) + + return conn + def get_connection(self, url, proxies=None): - """Returns a urllib3 connection for the given URL. This should not be + """DEPRECATED: Users should move to `get_connection_with_tls_context` + for all subclasses of HTTPAdapter using Requests>=2.32.2. + + 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 `. @@ -337,6 +504,15 @@ def get_connection(self, url, proxies=None): :param proxies: (optional) A Requests-style dictionary of proxies used on this request. :rtype: urllib3.ConnectionPool """ + warnings.warn( + ( + "`get_connection` has been deprecated in favor of " + "`get_connection_with_tls_context`. Custom HTTPAdapter subclasses " + "will need to migrate for Requests>=2.32.2. Please see " + "https://github.com/psf/requests/pull/6710 for more details." + ), + DeprecationWarning, + ) proxy = select_proxy(url, proxies) if proxy: @@ -391,6 +567,9 @@ def request_url(self, request, proxies): using_socks_proxy = proxy_scheme.startswith("socks") url = request.path_url + if url.startswith("//"): # Don't confuse urllib3 + url = f"/{url.lstrip('/')}" + if is_proxied_http_request and not using_socks_proxy: url = urldefragauth(request.url) @@ -451,7 +630,9 @@ def send( """ try: - conn = self.get_connection(request.url, proxies) + conn = self.get_connection_with_tls_context( + request, verify, proxies=proxies, cert=cert + ) except LocationValueError as e: raise InvalidURL(e, request=request) diff --git a/vendor/requests/api.py b/vendor/requests/api.py index cd0b3ee..5960744 100644 --- a/vendor/requests/api.py +++ b/vendor/requests/api.py @@ -25,7 +25,7 @@ def request(method, url, **kwargs): :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 + 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. diff --git a/vendor/requests/auth.py b/vendor/requests/auth.py index 9733686..4a7ce6d 100644 --- a/vendor/requests/auth.py +++ b/vendor/requests/auth.py @@ -258,7 +258,6 @@ def handle_401(self, r, **kwargs): 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)) diff --git a/vendor/requests/compat.py b/vendor/requests/compat.py index 6776163..095de1b 100644 --- a/vendor/requests/compat.py +++ b/vendor/requests/compat.py @@ -7,13 +7,28 @@ compatibility until the next major version. """ -try: - import chardet -except ImportError: - import charset_normalizer as chardet - +import importlib import sys +# ------------------- +# Character Detection +# ------------------- + + +def _resolve_char_detection(): + """Find supported character detection libraries.""" + chardet = None + for lib in ("chardet", "charset_normalizer"): + if chardet is None: + try: + chardet = importlib.import_module(lib) + except ImportError: + pass + return chardet + + +chardet = _resolve_char_detection() + # ------- # Pythons # ------- diff --git a/vendor/requests/cookies.py b/vendor/requests/cookies.py index bf54ab2..f69d0cd 100644 --- a/vendor/requests/cookies.py +++ b/vendor/requests/cookies.py @@ -2,7 +2,7 @@ requests.cookies ~~~~~~~~~~~~~~~~ -Compatibility code to be able to use `cookielib.CookieJar` with requests. +Compatibility code to be able to use `http.cookiejar.CookieJar` with requests. requests.utils imports from here, so be careful with imports. """ @@ -23,7 +23,7 @@ class MockRequest: """Wraps a `requests.Request` to mimic a `urllib2.Request`. - The code in `cookielib.CookieJar` expects this interface in order to correctly + The code in `http.cookiejar.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. @@ -76,7 +76,7 @@ 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.""" + """cookiejar 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()" ) @@ -104,11 +104,11 @@ class MockResponse: """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. + the way `http.cookiejar` expects to see them. """ def __init__(self, headers): - """Make a MockResponse for `cookielib` to read. + """Make a MockResponse for `cookiejar` to read. :param headers: a httplib.HTTPMessage or analogous carrying the headers """ @@ -124,7 +124,7 @@ def getheaders(self, 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 jar: http.cookiejar.CookieJar (not necessarily a RequestsCookieJar) :param request: our own requests.Request object :param response: urllib3.HTTPResponse object """ @@ -174,7 +174,7 @@ class CookieConflictError(RuntimeError): class RequestsCookieJar(cookielib.CookieJar, MutableMapping): - """Compatibility class; is a cookielib.CookieJar, but exposes a dict + """Compatibility class; is a http.cookiejar.CookieJar, but exposes a dict interface. This is the CookieJar we create by default for requests and sessions that @@ -341,7 +341,7 @@ def __setitem__(self, name, value): self.set(name, value) def __delitem__(self, name): - """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + """Deletes a cookie given a name. Wraps ``http.cookiejar.CookieJar``'s ``remove_cookie_by_name()``. """ remove_cookie_by_name(self, name) diff --git a/vendor/requests/exceptions.py b/vendor/requests/exceptions.py index e1cedf8..83986b4 100644 --- a/vendor/requests/exceptions.py +++ b/vendor/requests/exceptions.py @@ -41,6 +41,16 @@ def __init__(self, *args, **kwargs): CompatJSONDecodeError.__init__(self, *args) InvalidJSONError.__init__(self, *self.args, **kwargs) + def __reduce__(self): + """ + The __reduce__ method called when pickling the object must + be the one from the JSONDecodeError (be it json/simplejson) + as it expects all the arguments for instantiation, not just + one like the IOError, and the MRO would by default call the + __reduce__ method from the IOError due to the inheritance order. + """ + return CompatJSONDecodeError.__reduce__(self) + class HTTPError(RequestException): """An HTTP error occurred.""" diff --git a/vendor/requests/models.py b/vendor/requests/models.py index 617a413..8f56ca7 100644 --- a/vendor/requests/models.py +++ b/vendor/requests/models.py @@ -170,7 +170,7 @@ def _encode_files(files, data): ) ) - for (k, v) in files: + for k, v in files: # support for explicit filename ft = None fh = None @@ -268,7 +268,6 @@ def __init__( hooks=None, json=None, ): - # Default empty dicts for dict params. data = [] if data is None else data files = [] if files is None else files @@ -277,7 +276,7 @@ def __init__( hooks = {} if hooks is None else hooks self.hooks = default_hooks() - for (k, v) in list(hooks.items()): + for k, v in list(hooks.items()): self.register_hook(event=k, hook=v) self.method = method @@ -790,7 +789,12 @@ def next(self): @property def apparent_encoding(self): """The apparent encoding, provided by the charset_normalizer or chardet libraries.""" - return chardet.detect(self.content)["encoding"] + if chardet is not None: + return chardet.detect(self.content)["encoding"] + else: + # If no character detection library is available, we'll fall back + # to a standard Python utf-8 str. + return "utf-8" def iter_content(self, chunk_size=1, decode_unicode=False): """Iterates over the response data. When stream=True is set on the @@ -865,7 +869,6 @@ def iter_lines( for chunk in self.iter_content( chunk_size=chunk_size, decode_unicode=decode_unicode ): - if pending is not None: chunk = pending + chunk diff --git a/vendor/requests/packages.py b/vendor/requests/packages.py index 77c45c9..5ab3d8e 100644 --- a/vendor/requests/packages.py +++ b/vendor/requests/packages.py @@ -1,13 +1,6 @@ import sys -try: - import chardet -except ImportError: - import warnings - - import charset_normalizer as chardet - - warnings.filterwarnings("ignore", "Trying to detect", module="charset_normalizer") +from .compat import chardet # This code exists for backwards compatibility reasons. # I don't like it either. Just look the other way. :) @@ -20,9 +13,11 @@ if mod == package or mod.startswith(f"{package}."): sys.modules[f"requests.packages.{mod}"] = sys.modules[mod] -target = chardet.__name__ -for mod in list(sys.modules): - if mod == target or mod.startswith(f"{target}."): - target = target.replace(target, "chardet") - sys.modules[f"requests.packages.{target}"] = sys.modules[mod] -# Kinda cool, though, right? +if chardet is not None: + target = chardet.__name__ + for mod in list(sys.modules): + if mod == target or mod.startswith(f"{target}."): + imported_mod = sys.modules[mod] + sys.modules[f"requests.packages.{mod}"] = imported_mod + mod = mod.replace(target, "chardet") + sys.modules[f"requests.packages.{mod}"] = imported_mod diff --git a/vendor/requests/sessions.py b/vendor/requests/sessions.py index 6cb3b4d..b387bc3 100644 --- a/vendor/requests/sessions.py +++ b/vendor/requests/sessions.py @@ -262,7 +262,6 @@ def resolve_redirects( if yield_requests: yield req else: - resp = self.send( req, stream=stream, @@ -324,7 +323,9 @@ def rebuild_proxies(self, prepared_request, proxies): except KeyError: username, password = None, None - if username and password: + # urllib3 handles proxy authorization for us in the standard adapter. + # Avoid appending this to TLS tunneled requests where it may be leaked. + if not scheme.startswith("https") and username and password: headers["Proxy-Authorization"] = _basic_auth_str(username, password) return new_proxies @@ -387,7 +388,6 @@ class Session(SessionRedirectMixin): ] def __init__(self): - #: A case-insensitive dictionary of headers to be sent on each #: :class:`Request ` sent from this #: :class:`Session `. @@ -543,6 +543,8 @@ def request( :type allow_redirects: bool :param proxies: (optional) Dictionary mapping protocol or protocol and hostname to the URL of the proxy. + :param hooks: (optional) Dictionary mapping hook name to one event or + list of events, event must be callable. :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 @@ -709,7 +711,6 @@ def send(self, request, **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) @@ -757,7 +758,7 @@ def merge_environment_settings(self, url, proxies, stream, verify, cert): # 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(): + for k, v in env_proxies.items(): proxies.setdefault(k, v) # Look for requests environment configuration @@ -783,8 +784,7 @@ def get_adapter(self, url): :rtype: requests.adapters.BaseAdapter """ - for (prefix, adapter) in self.adapters.items(): - + for prefix, adapter in self.adapters.items(): if url.lower().startswith(prefix.lower()): return adapter diff --git a/vendor/requests/status_codes.py b/vendor/requests/status_codes.py index 4bd072b..c7945a2 100644 --- a/vendor/requests/status_codes.py +++ b/vendor/requests/status_codes.py @@ -24,7 +24,7 @@ # Informational. 100: ("continue",), 101: ("switching_protocols",), - 102: ("processing",), + 102: ("processing", "early-hints"), 103: ("checkpoint",), 122: ("uri_too_long", "request_uri_too_long"), 200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "āœ“"), @@ -65,8 +65,8 @@ 410: ("gone",), 411: ("length_required",), 412: ("precondition_failed", "precondition"), - 413: ("request_entity_too_large",), - 414: ("request_uri_too_large",), + 413: ("request_entity_too_large", "content_too_large"), + 414: ("request_uri_too_large", "uri_too_long"), 415: ("unsupported_media_type", "unsupported_media", "media_type"), 416: ( "requested_range_not_satisfiable", @@ -76,10 +76,10 @@ 417: ("expectation_failed",), 418: ("im_a_teapot", "teapot", "i_am_a_teapot"), 421: ("misdirected_request",), - 422: ("unprocessable_entity", "unprocessable"), + 422: ("unprocessable_entity", "unprocessable", "unprocessable_content"), 423: ("locked",), 424: ("failed_dependency", "dependency"), - 425: ("unordered_collection", "unordered"), + 425: ("unordered_collection", "unordered", "too_early"), 426: ("upgrade_required", "upgrade"), 428: ("precondition_required", "precondition"), 429: ("too_many_requests", "too_many"), diff --git a/vendor/requests/utils.py b/vendor/requests/utils.py index a367417..ae6c42f 100644 --- a/vendor/requests/utils.py +++ b/vendor/requests/utils.py @@ -97,6 +97,8 @@ def proxy_bypass_registry(host): # '' string by the localhost entry and the corresponding # canonical entry. proxyOverride = proxyOverride.split(";") + # filter out empty strings to avoid re.match return true in the following code. + proxyOverride = filter(None, proxyOverride) # now check if we match one of the registry values. for test in proxyOverride: if test == "": @@ -134,6 +136,9 @@ def super_len(o): total_length = None current_position = 0 + if isinstance(o, str): + o = o.encode("utf-8") + if hasattr(o, "__len__"): total_length = len(o) @@ -466,11 +471,7 @@ def dict_from_cookiejar(cj): :rtype: dict """ - cookie_dict = {} - - for cookie in cj: - cookie_dict[cookie.name] = cookie.value - + cookie_dict = {cookie.name: cookie.value for cookie in cj} return cookie_dict @@ -767,6 +768,7 @@ def should_bypass_proxies(url, no_proxy): :rtype: bool """ + # Prioritize lowercase environment variables over uppercase # to keep a consistent behaviour with other http projects (curl, wget). def get_proxy(key): @@ -862,7 +864,7 @@ def select_proxy(url, proxies): def resolve_proxies(request, proxies, trust_env=True): """This method takes proxy information from a request and configuration input to resolve a mapping of target proxies. This will consider settings - such a NO_PROXY to strip proxy configurations. + such as NO_PROXY to strip proxy configurations. :param request: Request or PreparedRequest :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs @@ -1054,7 +1056,7 @@ def _validate_header_part(header, header_part, header_validator_index): if not validator.match(header_part): header_kind = "name" if header_validator_index == 0 else "value" raise InvalidHeader( - f"Invalid leading whitespace, reserved character(s), or return" + f"Invalid leading whitespace, reserved character(s), or return " f"character(s) in header {header_kind}: {header_part!r}" ) diff --git a/vendor/semantic_version/__init__.py b/vendor/semantic_version/__init__.py new file mode 100644 index 0000000..1528bda --- /dev/null +++ b/vendor/semantic_version/__init__.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright (c) The python-semanticversion project +# This code is distributed under the two-clause BSD License. + + +from .base import compare, match, validate, SimpleSpec, NpmSpec, Spec, SpecItem, Version + + +__author__ = "RaphaĆ«l Barrois " +try: + # Python 3.8+ + from importlib.metadata import version + + __version__ = version("semantic_version") +except ImportError: + import pkg_resources + + __version__ = pkg_resources.get_distribution("semantic_version").version diff --git a/vendor/semantic_version/base.py b/vendor/semantic_version/base.py new file mode 100644 index 0000000..777c27a --- /dev/null +++ b/vendor/semantic_version/base.py @@ -0,0 +1,1449 @@ +# -*- coding: utf-8 -*- +# Copyright (c) The python-semanticversion project +# This code is distributed under the two-clause BSD License. + +import functools +import re +import warnings + + +def _has_leading_zero(value): + return (value + and value[0] == '0' + and value.isdigit() + and value != '0') + + +class MaxIdentifier(object): + __slots__ = [] + + def __repr__(self): + return 'MaxIdentifier()' + + def __eq__(self, other): + return isinstance(other, self.__class__) + + +@functools.total_ordering +class NumericIdentifier(object): + __slots__ = ['value'] + + def __init__(self, value): + self.value = int(value) + + def __repr__(self): + return 'NumericIdentifier(%r)' % self.value + + def __eq__(self, other): + if isinstance(other, NumericIdentifier): + return self.value == other.value + return NotImplemented + + def __lt__(self, other): + if isinstance(other, MaxIdentifier): + return True + elif isinstance(other, AlphaIdentifier): + return True + elif isinstance(other, NumericIdentifier): + return self.value < other.value + else: + return NotImplemented + + +@functools.total_ordering +class AlphaIdentifier(object): + __slots__ = ['value'] + + def __init__(self, value): + self.value = value.encode('ascii') + + def __repr__(self): + return 'AlphaIdentifier(%r)' % self.value + + def __eq__(self, other): + if isinstance(other, AlphaIdentifier): + return self.value == other.value + return NotImplemented + + def __lt__(self, other): + if isinstance(other, MaxIdentifier): + return True + elif isinstance(other, NumericIdentifier): + return False + elif isinstance(other, AlphaIdentifier): + return self.value < other.value + else: + return NotImplemented + + +class Version(object): + + version_re = re.compile(r'^(\d+)\.(\d+)\.(\d+)(?:-([0-9a-zA-Z.-]+))?(?:\+([0-9a-zA-Z.-]+))?$') + partial_version_re = re.compile(r'^(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:-([0-9a-zA-Z.-]*))?(?:\+([0-9a-zA-Z.-]*))?$') + + def __init__( + self, + version_string=None, + major=None, + minor=None, + patch=None, + prerelease=None, + build=None, + partial=False): + if partial: + warnings.warn( + "Partial versions will be removed in 3.0; use SimpleSpec('1.x.x') instead.", + DeprecationWarning, + stacklevel=2, + ) + has_text = version_string is not None + has_parts = not (major is minor is patch is prerelease is build is None) + if not has_text ^ has_parts: + raise ValueError("Call either Version('1.2.3') or Version(major=1, ...).") + + if has_text: + major, minor, patch, prerelease, build = self.parse(version_string, partial) + else: + # Convenience: allow to omit prerelease/build. + prerelease = tuple(prerelease or ()) + if not partial: + build = tuple(build or ()) + self._validate_kwargs(major, minor, patch, prerelease, build, partial) + + self.major = major + self.minor = minor + self.patch = patch + self.prerelease = prerelease + self.build = build + + self.partial = partial + + # Cached precedence keys + # _cmp_precedence_key is used for semver-precedence comparison + self._cmp_precedence_key = self._build_precedence_key(with_build=False) + # _sort_precedence_key is used for self.precedence_key, esp. for sorted(...) + self._sort_precedence_key = self._build_precedence_key(with_build=True) + + @classmethod + def _coerce(cls, value, allow_none=False): + if value is None and allow_none: + return value + return int(value) + + def next_major(self): + if self.prerelease and self.minor == self.patch == 0: + return Version( + major=self.major, + minor=0, + patch=0, + partial=self.partial, + ) + else: + return Version( + major=self.major + 1, + minor=0, + patch=0, + partial=self.partial, + ) + + def next_minor(self): + if self.prerelease and self.patch == 0: + return Version( + major=self.major, + minor=self.minor, + patch=0, + partial=self.partial, + ) + else: + return Version( + major=self.major, + minor=self.minor + 1, + patch=0, + partial=self.partial, + ) + + def next_patch(self): + if self.prerelease: + return Version( + major=self.major, + minor=self.minor, + patch=self.patch, + partial=self.partial, + ) + else: + return Version( + major=self.major, + minor=self.minor, + patch=self.patch + 1, + partial=self.partial, + ) + + def truncate(self, level='patch'): + """Return a new Version object, truncated up to the selected level.""" + if level == 'build': + return self + elif level == 'prerelease': + return Version( + major=self.major, + minor=self.minor, + patch=self.patch, + prerelease=self.prerelease, + partial=self.partial, + ) + elif level == 'patch': + return Version( + major=self.major, + minor=self.minor, + patch=self.patch, + partial=self.partial, + ) + elif level == 'minor': + return Version( + major=self.major, + minor=self.minor, + patch=None if self.partial else 0, + partial=self.partial, + ) + elif level == 'major': + return Version( + major=self.major, + minor=None if self.partial else 0, + patch=None if self.partial else 0, + partial=self.partial, + ) + else: + raise ValueError("Invalid truncation level `%s`." % level) + + @classmethod + def coerce(cls, version_string, partial=False): + """Coerce an arbitrary version string into a semver-compatible one. + + The rule is: + - If not enough components, fill minor/patch with zeroes; unless + partial=True + - If more than 3 dot-separated components, extra components are "build" + data. If some "build" data already appeared, append it to the + extra components + + Examples: + >>> Version.coerce('0.1') + Version(0, 1, 0) + >>> Version.coerce('0.1.2.3') + Version(0, 1, 2, (), ('3',)) + >>> Version.coerce('0.1.2.3+4') + Version(0, 1, 2, (), ('3', '4')) + >>> Version.coerce('0.1+2-3+4_5') + Version(0, 1, 0, (), ('2-3', '4-5')) + """ + base_re = re.compile(r'^\d+(?:\.\d+(?:\.\d+)?)?') + + match = base_re.match(version_string) + if not match: + raise ValueError( + "Version string lacks a numerical component: %r" + % version_string + ) + + version = version_string[:match.end()] + if not partial: + # We need a not-partial version. + while version.count('.') < 2: + version += '.0' + + # Strip leading zeros in components + # Version is of the form nn, nn.pp or nn.pp.qq + version = '.'.join( + # If the part was '0', we end up with an empty string. + part.lstrip('0') or '0' + for part in version.split('.') + ) + + if match.end() == len(version_string): + return Version(version, partial=partial) + + rest = version_string[match.end():] + + # Cleanup the 'rest' + rest = re.sub(r'[^a-zA-Z0-9+.-]', '-', rest) + + if rest[0] == '+': + # A 'build' component + prerelease = '' + build = rest[1:] + elif rest[0] == '.': + # An extra version component, probably 'build' + prerelease = '' + build = rest[1:] + elif rest[0] == '-': + rest = rest[1:] + if '+' in rest: + prerelease, build = rest.split('+', 1) + else: + prerelease, build = rest, '' + elif '+' in rest: + prerelease, build = rest.split('+', 1) + else: + prerelease, build = rest, '' + + build = build.replace('+', '.') + + if prerelease: + version = '%s-%s' % (version, prerelease) + if build: + version = '%s+%s' % (version, build) + + return cls(version, partial=partial) + + @classmethod + def parse(cls, version_string, partial=False, coerce=False): + """Parse a version string into a tuple of components: + (major, minor, patch, prerelease, build). + + Args: + version_string (str), the version string to parse + partial (bool), whether to accept incomplete input + coerce (bool), whether to try to map the passed in string into a + valid Version. + """ + if not version_string: + raise ValueError('Invalid empty version string: %r' % version_string) + + if partial: + version_re = cls.partial_version_re + else: + version_re = cls.version_re + + match = version_re.match(version_string) + if not match: + raise ValueError('Invalid version string: %r' % version_string) + + major, minor, patch, prerelease, build = match.groups() + + if _has_leading_zero(major): + raise ValueError("Invalid leading zero in major: %r" % version_string) + if _has_leading_zero(minor): + raise ValueError("Invalid leading zero in minor: %r" % version_string) + if _has_leading_zero(patch): + raise ValueError("Invalid leading zero in patch: %r" % version_string) + + major = int(major) + minor = cls._coerce(minor, partial) + patch = cls._coerce(patch, partial) + + if prerelease is None: + if partial and (build is None): + # No build info, strip here + return (major, minor, patch, None, None) + else: + prerelease = () + elif prerelease == '': + prerelease = () + else: + prerelease = tuple(prerelease.split('.')) + cls._validate_identifiers(prerelease, allow_leading_zeroes=False) + + if build is None: + if partial: + build = None + else: + build = () + elif build == '': + build = () + else: + build = tuple(build.split('.')) + cls._validate_identifiers(build, allow_leading_zeroes=True) + + return (major, minor, patch, prerelease, build) + + @classmethod + def _validate_identifiers(cls, identifiers, allow_leading_zeroes=False): + for item in identifiers: + if not item: + raise ValueError( + "Invalid empty identifier %r in %r" + % (item, '.'.join(identifiers)) + ) + + if item[0] == '0' and item.isdigit() and item != '0' and not allow_leading_zeroes: + raise ValueError("Invalid leading zero in identifier %r" % item) + + @classmethod + def _validate_kwargs(cls, major, minor, patch, prerelease, build, partial): + if ( + major != int(major) + or minor != cls._coerce(minor, partial) + or patch != cls._coerce(patch, partial) + or prerelease is None and not partial + or build is None and not partial + ): + raise ValueError( + "Invalid kwargs to Version(major=%r, minor=%r, patch=%r, " + "prerelease=%r, build=%r, partial=%r" % ( + major, minor, patch, prerelease, build, partial + )) + if prerelease is not None: + cls._validate_identifiers(prerelease, allow_leading_zeroes=False) + if build is not None: + cls._validate_identifiers(build, allow_leading_zeroes=True) + + def __iter__(self): + return iter((self.major, self.minor, self.patch, self.prerelease, self.build)) + + def __str__(self): + version = '%d' % self.major + if self.minor is not None: + version = '%s.%d' % (version, self.minor) + if self.patch is not None: + version = '%s.%d' % (version, self.patch) + + if self.prerelease or (self.partial and self.prerelease == () and self.build is None): + version = '%s-%s' % (version, '.'.join(self.prerelease)) + if self.build or (self.partial and self.build == ()): + version = '%s+%s' % (version, '.'.join(self.build)) + return version + + def __repr__(self): + return '%s(%r%s)' % ( + self.__class__.__name__, + str(self), + ', partial=True' if self.partial else '', + ) + + def __hash__(self): + # We don't include 'partial', since this is strictly equivalent to having + # at least a field being `None`. + return hash((self.major, self.minor, self.patch, self.prerelease, self.build)) + + def _build_precedence_key(self, with_build=False): + """Build a precedence key. + + The "build" component should only be used when sorting an iterable + of versions. + """ + if self.prerelease: + prerelease_key = tuple( + NumericIdentifier(part) if part.isdigit() else AlphaIdentifier(part) + for part in self.prerelease + ) + else: + prerelease_key = ( + MaxIdentifier(), + ) + + if not with_build: + return ( + self.major, + self.minor, + self.patch, + prerelease_key, + ) + + build_key = tuple( + NumericIdentifier(part) if part.isdigit() else AlphaIdentifier(part) + for part in self.build or () + ) + + return ( + self.major, + self.minor, + self.patch, + prerelease_key, + build_key, + ) + + @property + def precedence_key(self): + return self._sort_precedence_key + + def __cmp__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + if self < other: + return -1 + elif self > other: + return 1 + elif self == other: + return 0 + else: + return NotImplemented + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return ( + self.major == other.major + and self.minor == other.minor + and self.patch == other.patch + and (self.prerelease or ()) == (other.prerelease or ()) + and (self.build or ()) == (other.build or ()) + ) + + def __ne__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return tuple(self) != tuple(other) + + def __lt__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self._cmp_precedence_key < other._cmp_precedence_key + + def __le__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self._cmp_precedence_key <= other._cmp_precedence_key + + def __gt__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self._cmp_precedence_key > other._cmp_precedence_key + + def __ge__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + return self._cmp_precedence_key >= other._cmp_precedence_key + + +class SpecItem(object): + """A requirement specification.""" + + KIND_ANY = '*' + KIND_LT = '<' + KIND_LTE = '<=' + KIND_EQUAL = '==' + KIND_SHORTEQ = '=' + KIND_EMPTY = '' + KIND_GTE = '>=' + KIND_GT = '>' + KIND_NEQ = '!=' + KIND_CARET = '^' + KIND_TILDE = '~' + KIND_COMPATIBLE = '~=' + + # Map a kind alias to its full version + KIND_ALIASES = { + KIND_SHORTEQ: KIND_EQUAL, + KIND_EMPTY: KIND_EQUAL, + } + + re_spec = re.compile(r'^(<|<=||=|==|>=|>|!=|\^|~|~=)(\d.*)$') + + def __init__(self, requirement_string, _warn=True): + if _warn: + warnings.warn( + "The `SpecItem` class will be removed in 3.0.", + DeprecationWarning, + stacklevel=2, + ) + kind, spec = self.parse(requirement_string) + self.kind = kind + self.spec = spec + self._clause = Spec(requirement_string).clause + + @classmethod + def parse(cls, requirement_string): + if not requirement_string: + raise ValueError("Invalid empty requirement specification: %r" % requirement_string) + + # Special case: the 'any' version spec. + if requirement_string == '*': + return (cls.KIND_ANY, '') + + match = cls.re_spec.match(requirement_string) + if not match: + raise ValueError("Invalid requirement specification: %r" % requirement_string) + + kind, version = match.groups() + if kind in cls.KIND_ALIASES: + kind = cls.KIND_ALIASES[kind] + + spec = Version(version, partial=True) + if spec.build is not None and kind not in (cls.KIND_EQUAL, cls.KIND_NEQ): + raise ValueError( + "Invalid requirement specification %r: build numbers have no ordering." + % requirement_string + ) + return (kind, spec) + + @classmethod + def from_matcher(cls, matcher): + if matcher == Always(): + return cls('*', _warn=False) + elif matcher == Never(): + return cls('<0.0.0-', _warn=False) + elif isinstance(matcher, Range): + return cls('%s%s' % (matcher.operator, matcher.target), _warn=False) + + def match(self, version): + return self._clause.match(version) + + def __str__(self): + return '%s%s' % (self.kind, self.spec) + + def __repr__(self): + return '' % (self.kind, self.spec) + + def __eq__(self, other): + if not isinstance(other, SpecItem): + return NotImplemented + return self.kind == other.kind and self.spec == other.spec + + def __hash__(self): + return hash((self.kind, self.spec)) + + +def compare(v1, v2): + return Version(v1).__cmp__(Version(v2)) + + +def match(spec, version): + return Spec(spec).match(Version(version)) + + +def validate(version_string): + """Validates a version string againt the SemVer specification.""" + try: + Version.parse(version_string) + return True + except ValueError: + return False + + +DEFAULT_SYNTAX = 'simple' + + +class BaseSpec(object): + """A specification of compatible versions. + + Usage: + >>> Spec('>=1.0.0', syntax='npm') + + A version matches a specification if it matches any + of the clauses of that specification. + + Internally, a Spec is AnyOf( + AllOf(Matcher, Matcher, Matcher), + AllOf(...), + ) + """ + SYNTAXES = {} + + @classmethod + def register_syntax(cls, subclass): + syntax = subclass.SYNTAX + if syntax is None: + raise ValueError("A Spec needs its SYNTAX field to be set.") + elif syntax in cls.SYNTAXES: + raise ValueError( + "Duplicate syntax for %s: %r, %r" + % (syntax, cls.SYNTAXES[syntax], subclass) + ) + cls.SYNTAXES[syntax] = subclass + return subclass + + def __init__(self, expression): + super(BaseSpec, self).__init__() + self.expression = expression + self.clause = self._parse_to_clause(expression) + + @classmethod + def parse(cls, expression, syntax=DEFAULT_SYNTAX): + """Convert a syntax-specific expression into a BaseSpec instance.""" + return cls.SYNTAXES[syntax](expression) + + @classmethod + def _parse_to_clause(cls, expression): + """Converts an expression to a clause.""" + raise NotImplementedError() + + def filter(self, versions): + """Filter an iterable of versions satisfying the Spec.""" + for version in versions: + if self.match(version): + yield version + + def match(self, version): + """Check whether a Version satisfies the Spec.""" + return self.clause.match(version) + + def select(self, versions): + """Select the best compatible version among an iterable of options.""" + options = list(self.filter(versions)) + if options: + return max(options) + return None + + def __contains__(self, version): + """Whether `version in self`.""" + if isinstance(version, Version): + return self.match(version) + return False + + def __eq__(self, other): + if not isinstance(other, self.__class__): + return NotImplemented + + return self.clause == other.clause + + def __hash__(self): + return hash(self.clause) + + def __str__(self): + return self.expression + + def __repr__(self): + return '<%s: %r>' % (self.__class__.__name__, self.expression) + + +class Clause(object): + __slots__ = [] + + def match(self, version): + raise NotImplementedError() + + def __and__(self, other): + raise NotImplementedError() + + def __or__(self, other): + raise NotImplementedError() + + def __eq__(self, other): + raise NotImplementedError() + + def prettyprint(self, indent='\t'): + """Pretty-print the clause. + """ + return '\n'.join(self._pretty()).replace('\t', indent) + + def _pretty(self): + """Actual pretty-printing logic. + + Yields: + A list of string. Indentation is performed with \t. + """ + yield repr(self) + + def __ne__(self, other): + return not self == other + + def simplify(self): + return self + + +class AnyOf(Clause): + __slots__ = ['clauses'] + + def __init__(self, *clauses): + super(AnyOf, self).__init__() + self.clauses = frozenset(clauses) + + def match(self, version): + return any(c.match(version) for c in self.clauses) + + def simplify(self): + subclauses = set() + for clause in self.clauses: + simplified = clause.simplify() + if isinstance(simplified, AnyOf): + subclauses |= simplified.clauses + elif simplified == Never(): + continue + else: + subclauses.add(simplified) + if len(subclauses) == 1: + return subclauses.pop() + return AnyOf(*subclauses) + + def __hash__(self): + return hash((AnyOf, self.clauses)) + + def __iter__(self): + return iter(self.clauses) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.clauses == other.clauses + + def __and__(self, other): + if isinstance(other, AllOf): + return other & self + elif isinstance(other, Matcher) or isinstance(other, AnyOf): + return AllOf(self, other) + else: + return NotImplemented + + def __or__(self, other): + if isinstance(other, AnyOf): + clauses = list(self.clauses | other.clauses) + elif isinstance(other, Matcher) or isinstance(other, AllOf): + clauses = list(self.clauses | set([other])) + else: + return NotImplemented + return AnyOf(*clauses) + + def __repr__(self): + return 'AnyOf(%s)' % ', '.join(sorted(repr(c) for c in self.clauses)) + + def _pretty(self): + yield 'AnyOF(' + for clause in self.clauses: + lines = list(clause._pretty()) + for line in lines[:-1]: + yield '\t' + line + yield '\t' + lines[-1] + ',' + yield ')' + + +class AllOf(Clause): + __slots__ = ['clauses'] + + def __init__(self, *clauses): + super(AllOf, self).__init__() + self.clauses = frozenset(clauses) + + def match(self, version): + return all(clause.match(version) for clause in self.clauses) + + def simplify(self): + subclauses = set() + for clause in self.clauses: + simplified = clause.simplify() + if isinstance(simplified, AllOf): + subclauses |= simplified.clauses + elif simplified == Always(): + continue + else: + subclauses.add(simplified) + if len(subclauses) == 1: + return subclauses.pop() + return AllOf(*subclauses) + + def __hash__(self): + return hash((AllOf, self.clauses)) + + def __iter__(self): + return iter(self.clauses) + + def __eq__(self, other): + return isinstance(other, self.__class__) and self.clauses == other.clauses + + def __and__(self, other): + if isinstance(other, Matcher) or isinstance(other, AnyOf): + clauses = list(self.clauses | set([other])) + elif isinstance(other, AllOf): + clauses = list(self.clauses | other.clauses) + else: + return NotImplemented + return AllOf(*clauses) + + def __or__(self, other): + if isinstance(other, AnyOf): + return other | self + elif isinstance(other, Matcher): + return AnyOf(self, AllOf(other)) + elif isinstance(other, AllOf): + return AnyOf(self, other) + else: + return NotImplemented + + def __repr__(self): + return 'AllOf(%s)' % ', '.join(sorted(repr(c) for c in self.clauses)) + + def _pretty(self): + yield 'AllOF(' + for clause in self.clauses: + lines = list(clause._pretty()) + for line in lines[:-1]: + yield '\t' + line + yield '\t' + lines[-1] + ',' + yield ')' + + +class Matcher(Clause): + __slots__ = [] + + def __and__(self, other): + if isinstance(other, AllOf): + return other & self + elif isinstance(other, Matcher) or isinstance(other, AnyOf): + return AllOf(self, other) + else: + return NotImplemented + + def __or__(self, other): + if isinstance(other, AnyOf): + return other | self + elif isinstance(other, Matcher) or isinstance(other, AllOf): + return AnyOf(self, other) + else: + return NotImplemented + + +class Never(Matcher): + __slots__ = [] + + def match(self, version): + return False + + def __hash__(self): + return hash((Never,)) + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __and__(self, other): + return self + + def __or__(self, other): + return other + + def __repr__(self): + return 'Never()' + + +class Always(Matcher): + __slots__ = [] + + def match(self, version): + return True + + def __hash__(self): + return hash((Always,)) + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __and__(self, other): + return other + + def __or__(self, other): + return self + + def __repr__(self): + return 'Always()' + + +class Range(Matcher): + OP_EQ = '==' + OP_GT = '>' + OP_GTE = '>=' + OP_LT = '<' + OP_LTE = '<=' + OP_NEQ = '!=' + + # <1.2.3 matches 1.2.3-a1 + PRERELEASE_ALWAYS = 'always' + # <1.2.3 does not match 1.2.3-a1 + PRERELEASE_NATURAL = 'natural' + # 1.2.3-a1 is only considered if target == 1.2.3-xxx + PRERELEASE_SAMEPATCH = 'same-patch' + + # 1.2.3 matches 1.2.3+* + BUILD_IMPLICIT = 'implicit' + # 1.2.3 matches only 1.2.3, not 1.2.3+4 + BUILD_STRICT = 'strict' + + __slots__ = ['operator', 'target', 'prerelease_policy', 'build_policy'] + + def __init__(self, operator, target, prerelease_policy=PRERELEASE_NATURAL, build_policy=BUILD_IMPLICIT): + super(Range, self).__init__() + if target.build and operator not in (self.OP_EQ, self.OP_NEQ): + raise ValueError( + "Invalid range %s%s: build numbers have no ordering." + % (operator, target)) + self.operator = operator + self.target = target + self.prerelease_policy = prerelease_policy + self.build_policy = self.BUILD_STRICT if target.build else build_policy + + def match(self, version): + if self.build_policy != self.BUILD_STRICT: + version = version.truncate('prerelease') + + if version.prerelease: + same_patch = self.target.truncate() == version.truncate() + + if self.prerelease_policy == self.PRERELEASE_SAMEPATCH and not same_patch: + return False + + if self.operator == self.OP_EQ: + if self.build_policy == self.BUILD_STRICT: + return ( + self.target.truncate('prerelease') == version.truncate('prerelease') + and version.build == self.target.build + ) + return version == self.target + elif self.operator == self.OP_GT: + return version > self.target + elif self.operator == self.OP_GTE: + return version >= self.target + elif self.operator == self.OP_LT: + if ( + version.prerelease + and self.prerelease_policy == self.PRERELEASE_NATURAL + and version.truncate() == self.target.truncate() + and not self.target.prerelease + ): + return False + return version < self.target + elif self.operator == self.OP_LTE: + return version <= self.target + else: + assert self.operator == self.OP_NEQ + if self.build_policy == self.BUILD_STRICT: + return not ( + self.target.truncate('prerelease') == version.truncate('prerelease') + and version.build == self.target.build + ) + + if ( + version.prerelease + and self.prerelease_policy == self.PRERELEASE_NATURAL + and version.truncate() == self.target.truncate() + and not self.target.prerelease + ): + return False + return version != self.target + + def __hash__(self): + return hash((Range, self.operator, self.target, self.prerelease_policy)) + + def __eq__(self, other): + return ( + isinstance(other, self.__class__) + and self.operator == other.operator + and self.target == other.target + and self.prerelease_policy == other.prerelease_policy + ) + + def __str__(self): + return '%s%s' % (self.operator, self.target) + + def __repr__(self): + policy_part = ( + '' if self.prerelease_policy == self.PRERELEASE_NATURAL + else ', prerelease_policy=%r' % self.prerelease_policy + ) + ( + '' if self.build_policy == self.BUILD_IMPLICIT + else ', build_policy=%r' % self.build_policy + ) + return 'Range(%r, %r%s)' % ( + self.operator, + self.target, + policy_part, + ) + + +@BaseSpec.register_syntax +class SimpleSpec(BaseSpec): + + SYNTAX = 'simple' + + @classmethod + def _parse_to_clause(cls, expression): + return cls.Parser.parse(expression) + + class Parser: + NUMBER = r'\*|0|[1-9][0-9]*' + NAIVE_SPEC = re.compile(r"""^ + (?P<|<=||=|==|>=|>|!=|\^|~|~=) + (?P{nb})(?:\.(?P{nb})(?:\.(?P{nb}))?)? + (?:-(?P[a-z0-9A-Z.-]*))? + (?:\+(?P[a-z0-9A-Z.-]*))? + $ + """.format(nb=NUMBER), + re.VERBOSE, + ) + + @classmethod + def parse(cls, expression): + blocks = expression.split(',') + clause = Always() + for block in blocks: + if not cls.NAIVE_SPEC.match(block): + raise ValueError("Invalid simple block %r" % block) + clause &= cls.parse_block(block) + + return clause + + PREFIX_CARET = '^' + PREFIX_TILDE = '~' + PREFIX_COMPATIBLE = '~=' + PREFIX_EQ = '==' + PREFIX_NEQ = '!=' + PREFIX_GT = '>' + PREFIX_GTE = '>=' + PREFIX_LT = '<' + PREFIX_LTE = '<=' + + PREFIX_ALIASES = { + '=': PREFIX_EQ, + '': PREFIX_EQ, + } + + EMPTY_VALUES = ['*', 'x', 'X', None] + + @classmethod + def parse_block(cls, expr): + if not cls.NAIVE_SPEC.match(expr): + raise ValueError("Invalid simple spec component: %r" % expr) + prefix, major_t, minor_t, patch_t, prerel, build = cls.NAIVE_SPEC.match(expr).groups() + prefix = cls.PREFIX_ALIASES.get(prefix, prefix) + + major = None if major_t in cls.EMPTY_VALUES else int(major_t) + minor = None if minor_t in cls.EMPTY_VALUES else int(minor_t) + patch = None if patch_t in cls.EMPTY_VALUES else int(patch_t) + + if major is None: # '*' + target = Version(major=0, minor=0, patch=0) + if prefix not in (cls.PREFIX_EQ, cls.PREFIX_GTE): + raise ValueError("Invalid simple spec: %r" % expr) + elif minor is None: + target = Version(major=major, minor=0, patch=0) + elif patch is None: + target = Version(major=major, minor=minor, patch=0) + else: + target = Version( + major=major, + minor=minor, + patch=patch, + prerelease=prerel.split('.') if prerel else (), + build=build.split('.') if build else (), + ) + + if (major is None or minor is None or patch is None) and (prerel or build): + raise ValueError("Invalid simple spec: %r" % expr) + + if build is not None and prefix not in (cls.PREFIX_EQ, cls.PREFIX_NEQ): + raise ValueError("Invalid simple spec: %r" % expr) + + if prefix == cls.PREFIX_CARET: + # Accept anything with the same most-significant digit + if target.major: + high = target.next_major() + elif target.minor: + high = target.next_minor() + else: + high = target.next_patch() + return Range(Range.OP_GTE, target) & Range(Range.OP_LT, high) + + elif prefix == cls.PREFIX_TILDE: + assert major is not None + # Accept any higher patch in the same minor + # Might go higher if the initial version was a partial + if minor is None: + high = target.next_major() + else: + high = target.next_minor() + return Range(Range.OP_GTE, target) & Range(Range.OP_LT, high) + + elif prefix == cls.PREFIX_COMPATIBLE: + assert major is not None + # ~1 is 1.0.0..2.0.0; ~=2.2 is 2.2.0..3.0.0; ~=1.4.5 is 1.4.5..1.5.0 + if minor is None or patch is None: + # We got a partial version + high = target.next_major() + else: + high = target.next_minor() + return Range(Range.OP_GTE, target) & Range(Range.OP_LT, high) + + elif prefix == cls.PREFIX_EQ: + if major is None: + return Range(Range.OP_GTE, target) + elif minor is None: + return Range(Range.OP_GTE, target) & Range(Range.OP_LT, target.next_major()) + elif patch is None: + return Range(Range.OP_GTE, target) & Range(Range.OP_LT, target.next_minor()) + elif build == '': + return Range(Range.OP_EQ, target, build_policy=Range.BUILD_STRICT) + else: + return Range(Range.OP_EQ, target) + + elif prefix == cls.PREFIX_NEQ: + assert major is not None + if minor is None: + # !=1.x => <1.0.0 || >=2.0.0 + return Range(Range.OP_LT, target) | Range(Range.OP_GTE, target.next_major()) + elif patch is None: + # !=1.2.x => <1.2.0 || >=1.3.0 + return Range(Range.OP_LT, target) | Range(Range.OP_GTE, target.next_minor()) + elif prerel == '': + # !=1.2.3- + return Range(Range.OP_NEQ, target, prerelease_policy=Range.PRERELEASE_ALWAYS) + elif build == '': + # !=1.2.3+ or !=1.2.3-a2+ + return Range(Range.OP_NEQ, target, build_policy=Range.BUILD_STRICT) + else: + return Range(Range.OP_NEQ, target) + + elif prefix == cls.PREFIX_GT: + assert major is not None + if minor is None: + # >1.x => >=2.0 + return Range(Range.OP_GTE, target.next_major()) + elif patch is None: + return Range(Range.OP_GTE, target.next_minor()) + else: + return Range(Range.OP_GT, target) + + elif prefix == cls.PREFIX_GTE: + return Range(Range.OP_GTE, target) + + elif prefix == cls.PREFIX_LT: + assert major is not None + if prerel == '': + # <1.2.3- + return Range(Range.OP_LT, target, prerelease_policy=Range.PRERELEASE_ALWAYS) + return Range(Range.OP_LT, target) + + else: + assert prefix == cls.PREFIX_LTE + assert major is not None + if minor is None: + # <=1.x => <2.0 + return Range(Range.OP_LT, target.next_major()) + elif patch is None: + return Range(Range.OP_LT, target.next_minor()) + else: + return Range(Range.OP_LTE, target) + + +class LegacySpec(SimpleSpec): + def __init__(self, *expressions): + warnings.warn( + "The Spec() class will be removed in 3.1; use SimpleSpec() instead.", + PendingDeprecationWarning, + stacklevel=2, + ) + + if len(expressions) > 1: + warnings.warn( + "Passing 2+ arguments to SimpleSpec will be removed in 3.0; concatenate them with ',' instead.", + DeprecationWarning, + stacklevel=2, + ) + expression = ','.join(expressions) + super(LegacySpec, self).__init__(expression) + + @property + def specs(self): + return list(self) + + def __iter__(self): + warnings.warn( + "Iterating over the components of a SimpleSpec object will be removed in 3.0.", + DeprecationWarning, + stacklevel=2, + ) + try: + clauses = list(self.clause) + except TypeError: # Not an iterable + clauses = [self.clause] + for clause in clauses: + yield SpecItem.from_matcher(clause) + + +Spec = LegacySpec + + +@BaseSpec.register_syntax +class NpmSpec(BaseSpec): + SYNTAX = 'npm' + + @classmethod + def _parse_to_clause(cls, expression): + return cls.Parser.parse(expression) + + class Parser: + JOINER = '||' + HYPHEN = ' - ' + + NUMBER = r'x|X|\*|0|[1-9][0-9]*' + PART = r'[a-zA-Z0-9.-]*' + NPM_SPEC_BLOCK = re.compile(r""" + ^(?:v)? # Strip optional initial v + (?P<|<=|>=|>|=|\^|~|) # Operator, can be empty + (?P{nb})(?:\.(?P{nb})(?:\.(?P{nb}))?)? + (?:-(?P{part}))? # Optional re-release + (?:\+(?P{part}))? # Optional build + $""".format(nb=NUMBER, part=PART), + re.VERBOSE, + ) + + @classmethod + def range(cls, operator, target): + return Range(operator, target, prerelease_policy=Range.PRERELEASE_SAMEPATCH) + + @classmethod + def parse(cls, expression): + result = Never() + groups = expression.split(cls.JOINER) + for group in groups: + group = group.strip() + if not group: + group = '>=0.0.0' + + subclauses = [] + if cls.HYPHEN in group: + low, high = group.split(cls.HYPHEN, 2) + subclauses = cls.parse_simple('>=' + low) + cls.parse_simple('<=' + high) + + else: + blocks = group.split(' ') + for block in blocks: + if not cls.NPM_SPEC_BLOCK.match(block): + raise ValueError("Invalid NPM block in %r: %r" % (expression, block)) + + subclauses.extend(cls.parse_simple(block)) + + prerelease_clauses = [] + non_prerel_clauses = [] + for clause in subclauses: + if clause.target.prerelease: + if clause.operator in (Range.OP_GT, Range.OP_GTE): + prerelease_clauses.append(Range( + operator=Range.OP_LT, + target=Version( + major=clause.target.major, + minor=clause.target.minor, + patch=clause.target.patch + 1, + ), + prerelease_policy=Range.PRERELEASE_ALWAYS, + )) + elif clause.operator in (Range.OP_LT, Range.OP_LTE): + prerelease_clauses.append(Range( + operator=Range.OP_GTE, + target=Version( + major=clause.target.major, + minor=clause.target.minor, + patch=0, + prerelease=(), + ), + prerelease_policy=Range.PRERELEASE_ALWAYS, + )) + prerelease_clauses.append(clause) + non_prerel_clauses.append(cls.range( + operator=clause.operator, + target=clause.target.truncate(), + )) + else: + non_prerel_clauses.append(clause) + if prerelease_clauses: + result |= AllOf(*prerelease_clauses) + result |= AllOf(*non_prerel_clauses) + + return result + + PREFIX_CARET = '^' + PREFIX_TILDE = '~' + PREFIX_EQ = '=' + PREFIX_GT = '>' + PREFIX_GTE = '>=' + PREFIX_LT = '<' + PREFIX_LTE = '<=' + + PREFIX_ALIASES = { + '': PREFIX_EQ, + } + + PREFIX_TO_OPERATOR = { + PREFIX_EQ: Range.OP_EQ, + PREFIX_LT: Range.OP_LT, + PREFIX_LTE: Range.OP_LTE, + PREFIX_GTE: Range.OP_GTE, + PREFIX_GT: Range.OP_GT, + } + + EMPTY_VALUES = ['*', 'x', 'X', None] + + @classmethod + def parse_simple(cls, simple): + match = cls.NPM_SPEC_BLOCK.match(simple) + + prefix, major_t, minor_t, patch_t, prerel, build = match.groups() + + prefix = cls.PREFIX_ALIASES.get(prefix, prefix) + major = None if major_t in cls.EMPTY_VALUES else int(major_t) + minor = None if minor_t in cls.EMPTY_VALUES else int(minor_t) + patch = None if patch_t in cls.EMPTY_VALUES else int(patch_t) + + if build is not None and prefix not in [cls.PREFIX_EQ]: + # Ignore the 'build' part when not comparing to a specific part. + build = None + + if major is None: # '*', 'x', 'X' + target = Version(major=0, minor=0, patch=0) + if prefix not in [cls.PREFIX_EQ, cls.PREFIX_GTE]: + raise ValueError("Invalid expression %r" % simple) + prefix = cls.PREFIX_GTE + elif minor is None: + target = Version(major=major, minor=0, patch=0) + elif patch is None: + target = Version(major=major, minor=minor, patch=0) + else: + target = Version( + major=major, + minor=minor, + patch=patch, + prerelease=prerel.split('.') if prerel else (), + build=build.split('.') if build else (), + ) + + if (major is None or minor is None or patch is None) and (prerel or build): + raise ValueError("Invalid NPM spec: %r" % simple) + + if prefix == cls.PREFIX_CARET: + if target.major: # ^1.2.4 => >=1.2.4 <2.0.0 ; ^1.x => >=1.0.0 <2.0.0 + high = target.truncate().next_major() + elif target.minor: # ^0.1.2 => >=0.1.2 <0.2.0 + high = target.truncate().next_minor() + elif minor is None: # ^0.x => >=0.0.0 <1.0.0 + high = target.truncate().next_major() + elif patch is None: # ^0.2.x => >=0.2.0 <0.3.0 + high = target.truncate().next_minor() + else: # ^0.0.1 => >=0.0.1 <0.0.2 + high = target.truncate().next_patch() + return [cls.range(Range.OP_GTE, target), cls.range(Range.OP_LT, high)] + + elif prefix == cls.PREFIX_TILDE: + assert major is not None + if minor is None: # ~1.x => >=1.0.0 <2.0.0 + high = target.next_major() + else: # ~1.2.x => >=1.2.0 <1.3.0; ~1.2.3 => >=1.2.3 <1.3.0 + high = target.next_minor() + return [cls.range(Range.OP_GTE, target), cls.range(Range.OP_LT, high)] + + elif prefix == cls.PREFIX_EQ: + if major is None: + return [cls.range(Range.OP_GTE, target)] + elif minor is None: + return [cls.range(Range.OP_GTE, target), cls.range(Range.OP_LT, target.next_major())] + elif patch is None: + return [cls.range(Range.OP_GTE, target), cls.range(Range.OP_LT, target.next_minor())] + else: + return [cls.range(Range.OP_EQ, target)] + + elif prefix == cls.PREFIX_GT: + assert major is not None + if minor is None: # >1.x + return [cls.range(Range.OP_GTE, target.next_major())] + elif patch is None: # >1.2.x => >=1.3.0 + return [cls.range(Range.OP_GTE, target.next_minor())] + else: + return [cls.range(Range.OP_GT, target)] + + elif prefix == cls.PREFIX_GTE: + return [cls.range(Range.OP_GTE, target)] + + elif prefix == cls.PREFIX_LT: + assert major is not None + return [cls.range(Range.OP_LT, target)] + + else: + assert prefix == cls.PREFIX_LTE + assert major is not None + if minor is None: # <=1.x => <2.0.0 + return [cls.range(Range.OP_LT, target.next_major())] + elif patch is None: # <=1.2.x => <1.3.0 + return [cls.range(Range.OP_LT, target.next_minor())] + else: + return [cls.range(Range.OP_LTE, target)] diff --git a/vendor/semantic_version/django_fields.py b/vendor/semantic_version/django_fields.py new file mode 100644 index 0000000..e5bd7eb --- /dev/null +++ b/vendor/semantic_version/django_fields.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# Copyright (c) The python-semanticversion project +# This code is distributed under the two-clause BSD License. + +import warnings + +import django +from django.db import models + +if django.VERSION >= (3, 0): + # See https://docs.djangoproject.com/en/dev/releases/3.0/#features-deprecated-in-3-0 + from django.utils.translation import gettext_lazy as _ +else: + from django.utils.translation import ugettext_lazy as _ + +from . import base + + +class SemVerField(models.CharField): + + def __init__(self, *args, **kwargs): + kwargs.setdefault('max_length', 200) + super(SemVerField, self).__init__(*args, **kwargs) + + def from_db_value(self, value, expression, connection, *args): + """Convert from the database format. + + This should be the inverse of self.get_prep_value() + """ + return self.to_python(value) + + def get_prep_value(self, obj): + return None if obj is None else str(obj) + + def get_db_prep_value(self, value, connection, prepared=False): + if not prepared: + value = self.get_prep_value(value) + return value + + def value_to_string(self, obj): + value = self.to_python(self.value_from_object(obj)) + return str(value) + + def run_validators(self, value): + return super(SemVerField, self).run_validators(str(value)) + + +class VersionField(SemVerField): + default_error_messages = { + 'invalid': _("Enter a valid version number in X.Y.Z format."), + } + description = _("Version") + + def __init__(self, *args, **kwargs): + self.partial = kwargs.pop('partial', False) + if self.partial: + warnings.warn( + "Use of `partial=True` will be removed in 3.0.", + DeprecationWarning, + stacklevel=2, + ) + self.coerce = kwargs.pop('coerce', False) + super(VersionField, self).__init__(*args, **kwargs) + + def deconstruct(self): + """Handle django.db.migrations.""" + name, path, args, kwargs = super(VersionField, self).deconstruct() + kwargs['partial'] = self.partial + kwargs['coerce'] = self.coerce + return name, path, args, kwargs + + def to_python(self, value): + """Converts any value to a base.Version field.""" + if value is None or value == '': + return value + if isinstance(value, base.Version): + return value + if self.coerce: + return base.Version.coerce(value, partial=self.partial) + else: + return base.Version(value, partial=self.partial) + + +class SpecField(SemVerField): + default_error_messages = { + 'invalid': _("Enter a valid version number spec list in ==X.Y.Z,>=A.B.C format."), + } + description = _("Version specification list") + + def __init__(self, *args, **kwargs): + self.syntax = kwargs.pop('syntax', base.DEFAULT_SYNTAX) + super(SpecField, self).__init__(*args, **kwargs) + + def deconstruct(self): + """Handle django.db.migrations.""" + name, path, args, kwargs = super(SpecField, self).deconstruct() + if self.syntax != base.DEFAULT_SYNTAX: + kwargs['syntax'] = self.syntax + return name, path, args, kwargs + + def to_python(self, value): + """Converts any value to a base.Spec field.""" + if value is None or value == '': + return value + if isinstance(value, base.BaseSpec): + return value + return base.BaseSpec.parse(value, syntax=self.syntax) diff --git a/vendor/urllib3/__init__.py b/vendor/urllib3/__init__.py index 43e79fa..3fe782c 100644 --- a/vendor/urllib3/__init__.py +++ b/vendor/urllib3/__init__.py @@ -6,6 +6,7 @@ # Set default logging handler to avoid "No handler found" warnings. import logging +import sys import typing import warnings from logging import NullHandler @@ -30,34 +31,19 @@ except ImportError: pass else: - # fmt: off - if ( - not ssl.OPENSSL_VERSION.startswith("OpenSSL ") - or ssl.OPENSSL_VERSION_INFO < (1, 1, 1) - ): # Defensive: + if not ssl.OPENSSL_VERSION.startswith("OpenSSL "): # Defensive: + warnings.warn( + "urllib3 v2 only supports OpenSSL 1.1.1+, currently " + f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. " + "See: https://github.com/urllib3/urllib3/issues/3020", + exceptions.NotOpenSSLWarning, + ) + elif ssl.OPENSSL_VERSION_INFO < (1, 1, 1): # Defensive: raise ImportError( - "urllib3 v2.0 only supports OpenSSL 1.1.1+, currently " - f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION}. " + "urllib3 v2 only supports OpenSSL 1.1.1+, currently " + f"the 'ssl' module is compiled with {ssl.OPENSSL_VERSION!r}. " "See: https://github.com/urllib3/urllib3/issues/2168" ) - # fmt: on - -# === 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 ModuleNotFoundError: - pass -else: - warnings.warn( - "'urllib3[secure]' extra is deprecated and will be removed " - "in urllib3 v2.1.0. 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" @@ -79,6 +65,7 @@ "make_headers", "proxy_from_url", "request", + "BaseHTTPResponse", ) logging.getLogger(__name__).addHandler(NullHandler()) @@ -146,6 +133,61 @@ def request( Therefore, its side effects could be shared across dependencies relying on it. To avoid side effects create a new ``PoolManager`` instance and use it instead. The method does not accept low-level ``**urlopen_kw`` keyword arguments. + + :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 fields: + Data to encode and send in the request body. + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. + + :param bool preload_content: + If True, the response's body will be preloaded into memory. + + :param bool decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :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 retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. 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 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 json: + Data to encode and send as JSON with UTF-encoded in the request body. + The ``"Content-Type"`` header will be set to ``"application/json"`` + unless specified otherwise. """ return _DEFAULT_POOL.request( @@ -161,3 +203,9 @@ def request( timeout=timeout, json=json, ) + + +if sys.platform == "emscripten": + from .contrib.emscripten import inject_into_urllib3 # noqa: 401 + + inject_into_urllib3() diff --git a/vendor/urllib3/_base_connection.py b/vendor/urllib3/_base_connection.py index 3afed76..29ca334 100644 --- a/vendor/urllib3/_base_connection.py +++ b/vendor/urllib3/_base_connection.py @@ -12,7 +12,7 @@ class ProxyConfig(typing.NamedTuple): ssl_context: ssl.SSLContext | None use_forwarding_for_https: bool - assert_hostname: None | str | Literal[False] + assert_hostname: None | str | typing.Literal[False] assert_fingerprint: str | None @@ -28,8 +28,7 @@ class _ResponseOptions(typing.NamedTuple): if typing.TYPE_CHECKING: import ssl - - from typing_extensions import Literal, Protocol + from typing import Protocol from .response import BaseHTTPResponse @@ -125,7 +124,7 @@ class BaseHTTPSConnection(BaseHTTPConnection, Protocol): # Certificate verification methods cert_reqs: int | str | None - assert_hostname: None | str | Literal[False] + assert_hostname: None | str | typing.Literal[False] assert_fingerprint: str | None ssl_context: ssl.SSLContext | None @@ -151,12 +150,12 @@ def __init__( *, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, source_address: tuple[str, int] | None = None, - blocksize: int = 8192, + blocksize: int = 16384, socket_options: _TYPE_SOCKET_OPTIONS | None = ..., proxy: Url | None = None, proxy_config: ProxyConfig | None = None, cert_reqs: int | str | None = None, - assert_hostname: None | str | Literal[False] = None, + assert_hostname: None | str | typing.Literal[False] = None, assert_fingerprint: str | None = None, server_hostname: str | None = None, ssl_context: ssl.SSLContext | None = None, diff --git a/vendor/urllib3/_collections.py b/vendor/urllib3/_collections.py index 3e43afb..8a4409a 100644 --- a/vendor/urllib3/_collections.py +++ b/vendor/urllib3/_collections.py @@ -8,7 +8,9 @@ if typing.TYPE_CHECKING: # We can only import Protocol if TYPE_CHECKING because it's a development # dependency, and is not available at runtime. - from typing_extensions import Protocol + from typing import Protocol + + from typing_extensions import Self class HasGettableStringKeys(Protocol): def keys(self) -> typing.Iterator[str]: @@ -239,7 +241,7 @@ class HTTPHeaderDict(typing.MutableMapping[str, str]): def __init__(self, headers: ValidHTTPHeaderSource | None = None, **kwargs: str): super().__init__() - self._container = {} # 'dict' is insert-ordered in Python 3.7+ + self._container = {} # 'dict' is insert-ordered if headers is not None: if isinstance(headers, HTTPHeaderDict): self._copy_from(headers) @@ -391,6 +393,24 @@ def getlist( # meets our external interface requirement of `Union[List[str], _DT]`. return vals[1:] + def _prepare_for_method_change(self) -> 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 @@ -407,7 +427,7 @@ def _copy_from(self, other: HTTPHeaderDict) -> None: val = other.getlist(key) self._container[key.lower()] = [key, *val] - def copy(self) -> HTTPHeaderDict: + def copy(self) -> Self: clone = type(self)() clone._copy_from(self) return clone @@ -432,3 +452,32 @@ def _has_value_for_header(self, header_name: str, potential_value: str) -> bool: if header_name in self: return potential_value in self._container[header_name.lower()][1:] return False + + def __ior__(self, other: object) -> HTTPHeaderDict: + # Supports extending a header dict in-place using operator |= + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + self.extend(maybe_constructable) + return self + + def __or__(self, other: object) -> Self: + # Supports merging header dicts using operator | + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + result = self.copy() + result.extend(maybe_constructable) + return result + + def __ror__(self, other: object) -> Self: + # Supports merging header dicts using operator | when other is on left side + # combining items with add instead of __setitem__ + maybe_constructable = ensure_can_construct_http_header_dict(other) + if maybe_constructable is None: + return NotImplemented + result = type(self)(maybe_constructable) + result.extend(self) + return result diff --git a/vendor/urllib3/_request_methods.py b/vendor/urllib3/_request_methods.py index 1d0f346..03186e5 100644 --- a/vendor/urllib3/_request_methods.py +++ b/vendor/urllib3/_request_methods.py @@ -85,6 +85,29 @@ def request( 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`. + + :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 fields: + Data to encode and send in the URL or request body, depending on ``method``. + + :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 json: + Data to encode and send as JSON with UTF-encoded in the request body. + The ``"Content-Type"`` header will be set to ``"application/json"`` + unless specified otherwise. """ method = method.upper() @@ -95,9 +118,11 @@ def request( if json is not None: if headers is None: - headers = self.headers.copy() # type: ignore + headers = self.headers + if not ("content-type" in map(str.lower, headers.keys())): - headers["Content-Type"] = "application/json" # type: ignore + headers = HTTPHeaderDict(headers) + headers["Content-Type"] = "application/json" body = _json.dumps(json, separators=(",", ":"), ensure_ascii=False).encode( "utf-8" @@ -130,6 +155,20 @@ def request_encode_url( """ Make a request using :meth:`urlopen` with the ``fields`` encoded in the url. This is useful for request methods like GET, HEAD, DELETE, etc. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param url: + The URL to perform the request on. + + :param fields: + Data to encode and send in the URL. + + :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. """ if headers is None: headers = self.headers @@ -186,6 +225,28 @@ def request_encode_body( 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. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param url: + The URL to perform the request on. + + :param fields: + Data to encode and send in the request body. + + :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 encode_multipart: + If True, encode the ``fields`` using the multipart/form-data MIME + format. + + :param multipart_boundary: + If not specified, then a random boundary will be generated using + :func:`urllib3.filepost.choose_boundary`. """ if headers is None: headers = self.headers diff --git a/vendor/urllib3/_version.py b/vendor/urllib3/_version.py index 60cc514..eb8b5c2 100644 --- a/vendor/urllib3/_version.py +++ b/vendor/urllib3/_version.py @@ -1,4 +1,16 @@ -# This file is protected via CODEOWNERS -from __future__ import annotations +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object -__version__ = "2.0.2" +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '2.2.3' +__version_tuple__ = version_tuple = (2, 2, 3) diff --git a/vendor/urllib3/connection.py b/vendor/urllib3/connection.py index 9dc04fe..7cbef7d 100644 --- a/vendor/urllib3/connection.py +++ b/vendor/urllib3/connection.py @@ -1,10 +1,13 @@ from __future__ import annotations import datetime +import http.client import logging import os import re import socket +import sys +import threading import typing import warnings from http.client import HTTPConnection as _HTTPConnection @@ -13,13 +16,12 @@ from socket import timeout as SocketTimeout if typing.TYPE_CHECKING: - from typing_extensions import Literal - from .response import HTTPResponse from .util.ssl_ import _TYPE_PEER_CERT_RET_DICT from .util.ssltransport import SSLTransport from ._collections import HTTPHeaderDict +from .http2 import probe as http2_probe from .util.response import assert_header_parsing from .util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT, Timeout from .util.util import to_str @@ -72,10 +74,12 @@ class BaseSSLError(BaseException): # type: ignore[no-redef] # 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(2022, 1, 1) +RECENT_DATE = datetime.date(2023, 6, 1) _CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") +_HAS_SYS_AUDIT = hasattr(sys, "audit") + class HTTPConnection(_HTTPConnection): """ @@ -134,7 +138,7 @@ def __init__( *, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, source_address: tuple[str, int] | None = None, - blocksize: int = 8192, + blocksize: int = 16384, socket_options: None | (connection._TYPE_SOCKET_OPTIONS) = default_socket_options, proxy: Url | None = None, @@ -157,11 +161,6 @@ def __init__( self._tunnel_port: int | None = None self._tunnel_scheme: str | None = None - # https://github.com/python/mypy/issues/4125 - # Mypy treats this as LSP violation, which is considered a bug. - # If `host` is made a property it violates LSP, because a writeable attribute is overridden with a read-only one. - # However, there is also a `host` setter so LSP is not violated. - # Potentially, a `@host.deleter` might be needed depending on how this issue will be fixed. @property def host(self) -> str: """ @@ -216,6 +215,10 @@ def _new_conn(self) -> socket.socket: self, f"Failed to establish a new connection: {e}" ) from e + # Audit hooks are only available in Python 3.8+ + if _HAS_SYS_AUDIT: + sys.audit("http.client.connect", self, self.host, self.port) + return sock def set_tunnel( @@ -232,6 +235,46 @@ def set_tunnel( super().set_tunnel(host, port=port, headers=headers) self._tunnel_scheme = scheme + if sys.version_info < (3, 11, 4): + + def _tunnel(self) -> None: + _MAXLINE = http.client._MAXLINE # type: ignore[attr-defined] + connect = b"CONNECT %s:%d HTTP/1.0\r\n" % ( # type: ignore[str-format] + self._tunnel_host.encode("ascii"), # type: ignore[union-attr] + self._tunnel_port, + ) + headers = [connect] + for header, value in self._tunnel_headers.items(): # type: ignore[attr-defined] + headers.append(f"{header}: {value}\r\n".encode("latin-1")) + headers.append(b"\r\n") + # Making a single send() call instead of one per line encourages + # the host OS to use a more optimal packet size instead of + # potentially emitting a series of small packets. + self.send(b"".join(headers)) + del headers + + response = self.response_class(self.sock, method=self._method) # type: ignore[attr-defined] + try: + (version, code, message) = response._read_status() # type: ignore[attr-defined] + + if code != http.HTTPStatus.OK: + self.close() + raise OSError(f"Tunnel connection failed: {code} {message.strip()}") + while True: + line = response.fp.readline(_MAXLINE + 1) + if len(line) > _MAXLINE: + raise http.client.LineTooLong("header line") + if not line: + # for sites which EOF without sending a trailer + break + if line in (b"\r\n", b"\n", b""): + break + + if self.debuglevel > 0: + print("header:", line.decode()) + finally: + response.close() + def connect(self) -> None: self.sock = self._new_conn() if self._tunnel_host: @@ -239,13 +282,16 @@ def connect(self) -> None: self._has_connected_to_proxy = True # TODO: Fix tunnel so it doesn't depend on self.sock state. - self._tunnel() # type: ignore[attr-defined] + self._tunnel() # If there's a proxy to be connected to we are fully connected. # This is set twice (once above and here) due to forwarding proxies # not using tunnelling. self._has_connected_to_proxy = bool(self.proxy) + if self._has_connected_to_proxy: + self.proxy_is_verified = False + @property def is_closed(self) -> bool: return self.sock is None @@ -260,6 +306,13 @@ def is_connected(self) -> bool: def has_connected_to_proxy(self) -> bool: return self._has_connected_to_proxy + @property + def proxy_is_forwarding(self) -> bool: + """ + Return True if a forwarding proxy is configured, else return False + """ + return bool(self.proxy) and self._tunnel_host is None + def close(self) -> None: try: super().close() @@ -295,7 +348,7 @@ def putrequest( method, url, skip_host=skip_host, skip_accept_encoding=skip_accept_encoding ) - def putheader(self, header: str, *values: str) -> None: + def putheader(self, header: str, *values: str) -> None: # type: ignore[override] """""" if not any(isinstance(v, str) and v == SKIP_HEADER for v in values): super().putheader(header, *values) @@ -470,6 +523,7 @@ def getresponse( # type: ignore[override] headers=headers, status=httplib_response.status, version=httplib_response.version, + version_string=getattr(self, "_http_vsn_str", "HTTP/?"), reason=httplib_response.reason, preload_content=resp_options.preload_content, decode_content=resp_options.decode_content, @@ -497,6 +551,7 @@ class HTTPSConnection(HTTPConnection): ssl_minimum_version: int | None = None ssl_maximum_version: int | None = None assert_fingerprint: str | None = None + _connect_callback: typing.Callable[..., None] | None = None def __init__( self, @@ -505,13 +560,13 @@ def __init__( *, timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, source_address: tuple[str, int] | None = None, - blocksize: int = 8192, + blocksize: int = 16384, socket_options: None | (connection._TYPE_SOCKET_OPTIONS) = HTTPConnection.default_socket_options, proxy: Url | None = None, proxy_config: ProxyConfig | None = None, cert_reqs: int | str | None = None, - assert_hostname: None | str | Literal[False] = None, + assert_hostname: None | str | typing.Literal[False] = None, assert_fingerprint: str | None = None, server_hostname: str | None = None, ssl_context: ssl.SSLContext | None = None, @@ -557,6 +612,7 @@ def __init__( else: cert_reqs = resolve_cert_reqs(None) self.cert_reqs = cert_reqs + self._connect_callback = None def set_cert( self, @@ -565,7 +621,7 @@ def set_cert( cert_reqs: int | str | None = None, key_password: str | None = None, ca_certs: str | None = None, - assert_hostname: None | str | Literal[False] = None, + assert_hostname: None | str | typing.Literal[False] = None, assert_fingerprint: str | None = None, ca_cert_dir: str | None = None, ca_cert_data: None | str | bytes = None, @@ -600,64 +656,142 @@ def set_cert( self.ca_cert_data = ca_cert_data def connect(self) -> None: - sock: socket.socket | ssl.SSLSocket - self.sock = sock = self._new_conn() - server_hostname: str = self.host - tls_in_tls = False - - # Do we need to establish a tunnel? - if self._tunnel_host is not None: - # We're tunneling to an HTTPS origin so need to do TLS-in-TLS. - if self._tunnel_scheme == "https": - self.sock = sock = self._connect_tls_proxy(self.host, sock) - tls_in_tls = True + # Today we don't need to be doing this step before the /actual/ socket + # connection, however in the future we'll need to decide whether to + # create a new socket or re-use an existing "shared" socket as a part + # of the HTTP/2 handshake dance. + if self._tunnel_host is not None and self._tunnel_port is not None: + probe_http2_host = self._tunnel_host + probe_http2_port = self._tunnel_port + else: + probe_http2_host = self.host + probe_http2_port = self.port + + # Check if the target origin supports HTTP/2. + # If the value comes back as 'None' it means that the current thread + # is probing for HTTP/2 support. Otherwise, we're waiting for another + # probe to complete, or we get a value right away. + target_supports_http2: bool | None + if "h2" in ssl_.ALPN_PROTOCOLS: + target_supports_http2 = http2_probe.acquire_and_get( + host=probe_http2_host, port=probe_http2_port + ) + else: + # If HTTP/2 isn't going to be offered it doesn't matter if + # the target supports HTTP/2. Don't want to make a probe. + target_supports_http2 = False + + if self._connect_callback is not None: + self._connect_callback( + "before connect", + thread_id=threading.get_ident(), + target_supports_http2=target_supports_http2, + ) - # If we're tunneling it means we're connected to our proxy. - self._has_connected_to_proxy = True + try: + sock: socket.socket | ssl.SSLSocket + self.sock = sock = self._new_conn() + server_hostname: str = self.host + tls_in_tls = False + + # Do we need to establish a tunnel? + if self._tunnel_host is not None: + # We're tunneling to an HTTPS origin so need to do TLS-in-TLS. + if self._tunnel_scheme == "https": + # _connect_tls_proxy will verify and assign proxy_is_verified + self.sock = sock = self._connect_tls_proxy(self.host, sock) + tls_in_tls = True + elif self._tunnel_scheme == "http": + self.proxy_is_verified = False + + # If we're tunneling it means we're connected to our proxy. + self._has_connected_to_proxy = True + + self._tunnel() + # Override the host with the one we're requesting data from. + server_hostname = self._tunnel_host + + 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( + ( + f"System time is way off (before {RECENT_DATE}). This will probably " + "lead to SSL verification errors" + ), + SystemTimeWarning, + ) - self._tunnel() # type: ignore[attr-defined] - # Override the host with the one we're requesting data from. - server_hostname = self._tunnel_host - - 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( - ( - f"System time is way off (before {RECENT_DATE}). This will probably " - "lead to SSL verification errors" - ), - SystemTimeWarning, + # Remove trailing '.' from fqdn hostnames to allow certificate validation + server_hostname_rm_dot = server_hostname.rstrip(".") + + sock_and_verified = _ssl_wrap_socket_and_match_hostname( + sock=sock, + cert_reqs=self.cert_reqs, + ssl_version=self.ssl_version, + ssl_minimum_version=self.ssl_minimum_version, + ssl_maximum_version=self.ssl_maximum_version, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + ca_cert_data=self.ca_cert_data, + cert_file=self.cert_file, + key_file=self.key_file, + key_password=self.key_password, + server_hostname=server_hostname_rm_dot, + ssl_context=self.ssl_context, + tls_in_tls=tls_in_tls, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint, ) + self.sock = sock_and_verified.socket + + # If an error occurs during connection/handshake we may need to release + # our lock so another connection can probe the origin. + except BaseException: + if self._connect_callback is not None: + self._connect_callback( + "after connect failure", + thread_id=threading.get_ident(), + target_supports_http2=target_supports_http2, + ) - sock_and_verified = _ssl_wrap_socket_and_match_hostname( - sock=sock, - cert_reqs=self.cert_reqs, - ssl_version=self.ssl_version, - ssl_minimum_version=self.ssl_minimum_version, - ssl_maximum_version=self.ssl_maximum_version, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - ca_cert_data=self.ca_cert_data, - cert_file=self.cert_file, - key_file=self.key_file, - key_password=self.key_password, - server_hostname=server_hostname, - ssl_context=self.ssl_context, - tls_in_tls=tls_in_tls, - assert_hostname=self.assert_hostname, - assert_fingerprint=self.assert_fingerprint, - ) - self.sock = sock_and_verified.socket - self.is_verified = sock_and_verified.is_verified + if target_supports_http2 is None: + http2_probe.set_and_release( + host=probe_http2_host, port=probe_http2_port, supports_http2=None + ) + raise + + # If this connection doesn't know if the origin supports HTTP/2 + # we report back to the HTTP/2 probe our result. + if target_supports_http2 is None: + supports_http2 = sock_and_verified.socket.selected_alpn_protocol() == "h2" + http2_probe.set_and_release( + host=probe_http2_host, + port=probe_http2_port, + supports_http2=supports_http2, + ) + + # Forwarding proxies can never have a verified target since + # the proxy is the one doing the verification. Should instead + # use a CONNECT tunnel in order to verify the target. + # See: https://github.com/urllib3/urllib3/issues/3267. + if self.proxy_is_forwarding: + self.is_verified = False + else: + self.is_verified = sock_and_verified.is_verified # If there's a proxy to be connected to we are fully connected. # This is set twice (once above and here) due to forwarding proxies # not using tunnelling. self._has_connected_to_proxy = bool(self.proxy) + # Set `self.proxy_is_verified` unless it's already set while + # establishing a tunnel. + if self._has_connected_to_proxy and self.proxy_is_verified is None: + self.proxy_is_verified = sock_and_verified.is_verified + def _connect_tls_proxy(self, hostname: str, sock: socket.socket) -> ssl.SSLSocket: """ Establish a TLS connection to the proxy using the provided SSL context. @@ -711,7 +845,7 @@ def _ssl_wrap_socket_and_match_hostname( ca_certs: str | None, ca_cert_dir: str | None, ca_cert_data: None | str | bytes, - assert_hostname: None | str | Literal[False], + assert_hostname: None | str | typing.Literal[False], assert_fingerprint: str | None, server_hostname: str | None, ssl_context: ssl.SSLContext | None, @@ -741,6 +875,8 @@ def _ssl_wrap_socket_and_match_hostname( # `ssl` can't verify fingerprints or alternate hostnames assert_fingerprint or assert_hostname + # assert_hostname can be set to False to disable hostname checking + or assert_hostname is False # We still support OpenSSL 1.0.2, which prevents us from verifying # hostnames easily: https://github.com/pyca/pyopenssl/pull/933 or ssl_.IS_PYOPENSSL @@ -748,10 +884,9 @@ def _ssl_wrap_socket_and_match_hostname( ): context.check_hostname = False - # Try to load OS default certs if none are given. - # We need to do the hasattr() check for our custom - # pyOpenSSL and SecureTransport SSLContext objects - # because neither support load_default_certs(). + # Try to load OS default certs if none are given. We need to do the hasattr() check + # for custom pyOpenSSL SSLContext objects because they don't support + # load_default_certs(). if ( not ca_certs and not ca_cert_dir @@ -856,6 +991,7 @@ def _wrap_proxy_error(err: Exception, proxy_scheme: str | None) -> ProxyError: is_likely_http_proxy = ( "wrong version number" in error_normalized or "unknown protocol" in error_normalized + or "record layer failure" in error_normalized ) http_proxy_warning = ( ". Your proxy appears to only use HTTP and not HTTPS, " diff --git a/vendor/urllib3/connectionpool.py b/vendor/urllib3/connectionpool.py index 2479405..a2c3cf6 100644 --- a/vendor/urllib3/connectionpool.py +++ b/vendor/urllib3/connectionpool.py @@ -11,6 +11,7 @@ from types import TracebackType from ._base_connection import _TYPE_BODY +from ._collections import HTTPHeaderDict from ._request_methods import RequestMethods from .connection import ( BaseSSLError, @@ -53,7 +54,7 @@ if typing.TYPE_CHECKING: import ssl - from typing_extensions import Literal + from typing_extensions import Self from ._base_connection import BaseHTTPConnection, BaseHTTPSConnection @@ -61,8 +62,6 @@ _TYPE_TIMEOUT = typing.Union[Timeout, float, _TYPE_DEFAULT, None] -_SelfT = typing.TypeVar("_SelfT") - # Pool objects class ConnectionPool: @@ -95,7 +94,7 @@ def __init__(self, host: str, port: int | None = None) -> None: def __str__(self) -> str: return f"{type(self).__name__}(host={self.host!r}, port={self.port!r})" - def __enter__(self: _SelfT) -> _SelfT: + def __enter__(self) -> Self: return self def __exit__( @@ -103,7 +102,7 @@ def __exit__( exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, - ) -> Literal[False]: + ) -> typing.Literal[False]: self.close() # Return False to re-raise any potential exceptions return False @@ -511,9 +510,10 @@ def _make_request( pass except OSError as e: # MacOS/Linux - # EPROTOTYPE is needed on macOS + # EPROTOTYPE and ECONNRESET are needed on macOS # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/ - if e.errno != errno.EPROTOTYPE: + # Condition changed later to emit ECONNRESET instead of only EPROTOTYPE. + if e.errno != errno.EPROTOTYPE and e.errno != errno.ECONNRESET: raise # Reset the timeout for the recv() on the socket @@ -544,16 +544,15 @@ def _make_request( response._pool = self # type: ignore[attr-defined] log.debug( - '%s://%s:%s "%s %s %s" %s %s', + '%s://%s:%s "%s %s HTTP/%s" %s %s', self.scheme, self.host, self.port, method, url, - # HTTP version - conn._http_vsn_str, # type: ignore[attr-defined] + response.version, response.status, - response.length_remaining, # type: ignore[attr-defined] + response.length_remaining, ) return response @@ -646,7 +645,7 @@ def urlopen( # type: ignore[override] 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 + If ``None`` (default) will retry 3 times, see ``Retry.DEFAULT``. 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, @@ -893,7 +892,11 @@ def urlopen( # type: ignore[override] 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) @@ -995,7 +998,7 @@ def __init__( ssl_version: int | str | None = None, ssl_minimum_version: ssl.TLSVersion | None = None, ssl_maximum_version: ssl.TLSVersion | None = None, - assert_hostname: str | Literal[False] | None = None, + assert_hostname: str | typing.Literal[False] | None = None, assert_fingerprint: str | None = None, ca_cert_dir: str | None = None, **conn_kw: typing.Any, @@ -1091,7 +1094,8 @@ def _validate_conn(self, conn: BaseHTTPConnection) -> None: if conn.is_closed: conn.connect() - if not conn.is_verified: + # TODO revise this, see https://github.com/urllib3/urllib3/issues/2791 + if not conn.is_verified and not conn.proxy_is_verified: warnings.warn( ( f"Unverified HTTPS request is being made to host '{conn.host}'. " diff --git a/vendor/urllib3/contrib/_securetransport/bindings.py b/vendor/urllib3/contrib/_securetransport/bindings.py deleted file mode 100644 index 3e4cd46..0000000 --- a/vendor/urllib3/contrib/_securetransport/bindings.py +++ /dev/null @@ -1,430 +0,0 @@ -# type: ignore - -""" -This module uses ctypes to bind a whole bunch of functions and constants from -SecureTransport. The goal here is to provide the low-level API to -SecureTransport. These are essentially the C-level functions and constants, and -they're pretty gross to work with. - -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: - - 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 annotations - -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 - -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( - f"Only OS X 10.8 and newer are supported, not {version_info[0]}.{version_info[1]}" - ) - - -def load_cdll(name: str, macos10_16_path: str) -> CDLL: - """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. - path: str | None - 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 ImportError(f"The library {name} failed to load") from 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") from None - - -class CFConst: - """ - A class object that acts as essentially a namespace for CoreFoundation - constants. - """ - - kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) diff --git a/vendor/urllib3/contrib/_securetransport/low_level.py b/vendor/urllib3/contrib/_securetransport/low_level.py deleted file mode 100644 index e235699..0000000 --- a/vendor/urllib3/contrib/_securetransport/low_level.py +++ /dev/null @@ -1,474 +0,0 @@ -""" -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. -""" -from __future__ import annotations - -import base64 -import ctypes -import itertools -import os -import re -import ssl -import struct -import tempfile -import typing - -from .bindings import ( # type: ignore[attr-defined] - CFArray, - CFConst, - CFData, - CFDictionary, - CFMutableArray, - CFString, - CFTypeRef, - CoreFoundation, - SecKeychainRef, - 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: bytes) -> CFData: - """ - 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: list[tuple[typing.Any, typing.Any]] -) -> CFDictionary: - """ - 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: bytes) -> CFString: - """ - 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: list[bytes]) -> CFMutableArray: - """ - 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(f"Unable to allocate array: {e}") from None - return cf_arr - - -def _cf_string_to_unicode(value: CFString) -> str | None: - """ - 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 # type: ignore[no-any-return] - - -def _assert_no_error( - error: int, exception_class: type[BaseException] | None = None -) -> 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 == "": - output = f"OSStatus {error}" - - if exception_class is None: - exception_class = ssl.SSLError - - raise exception_class(output) - - -def _cert_array_from_pem(pem_bundle: bytes) -> CFArray: - """ - 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: CFTypeRef) -> bool: - """ - Returns True if a given CFTypeRef is a certificate. - """ - expected = Security.SecCertificateGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected # type: ignore[no-any-return] - - -def _is_identity(item: CFTypeRef) -> bool: - """ - Returns True if a given CFTypeRef is an identity. - """ - expected = Security.SecIdentityGetTypeID() - return CoreFoundation.CFGetTypeID(item) == expected # type: ignore[no-any-return] - - -def _temporary_keychain() -> tuple[SecKeychainRef, str]: - """ - 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: SecKeychainRef, path: str -) -> tuple[list[CFTypeRef], list[CFTypeRef]]: - """ - 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: SecKeychainRef, *paths: str | None) -> CFArray: - """ - 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. - filtered_paths = (path for path in paths if path) - - try: - for file_path in filtered_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: str) -> bytes: - """ - 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 - - -class SecurityConst: - """ - 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 diff --git a/vendor/urllib3/contrib/emscripten/__init__.py b/vendor/urllib3/contrib/emscripten/__init__.py new file mode 100644 index 0000000..8a3c5be --- /dev/null +++ b/vendor/urllib3/contrib/emscripten/__init__.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +import urllib3.connection + +from ...connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from .connection import EmscriptenHTTPConnection, EmscriptenHTTPSConnection + + +def inject_into_urllib3() -> None: + # override connection classes to use emscripten specific classes + # n.b. mypy complains about the overriding of classes below + # if it isn't ignored + HTTPConnectionPool.ConnectionCls = EmscriptenHTTPConnection + HTTPSConnectionPool.ConnectionCls = EmscriptenHTTPSConnection + urllib3.connection.HTTPConnection = EmscriptenHTTPConnection # type: ignore[misc,assignment] + urllib3.connection.HTTPSConnection = EmscriptenHTTPSConnection # type: ignore[misc,assignment] diff --git a/vendor/urllib3/contrib/emscripten/connection.py b/vendor/urllib3/contrib/emscripten/connection.py new file mode 100644 index 0000000..2ceb457 --- /dev/null +++ b/vendor/urllib3/contrib/emscripten/connection.py @@ -0,0 +1,254 @@ +from __future__ import annotations + +import os +import typing + +# use http.client.HTTPException for consistency with non-emscripten +from http.client import HTTPException as HTTPException # noqa: F401 +from http.client import ResponseNotReady + +from ..._base_connection import _TYPE_BODY +from ...connection import HTTPConnection, ProxyConfig, port_by_scheme +from ...exceptions import TimeoutError +from ...response import BaseHTTPResponse +from ...util.connection import _TYPE_SOCKET_OPTIONS +from ...util.timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT +from ...util.url import Url +from .fetch import _RequestError, _TimeoutError, send_request, send_streaming_request +from .request import EmscriptenRequest +from .response import EmscriptenHttpResponseWrapper, EmscriptenResponse + +if typing.TYPE_CHECKING: + from ..._base_connection import BaseHTTPConnection, BaseHTTPSConnection + + +class EmscriptenHTTPConnection: + default_port: typing.ClassVar[int] = port_by_scheme["http"] + default_socket_options: typing.ClassVar[_TYPE_SOCKET_OPTIONS] + + timeout: None | (float) + + host: str + port: int + blocksize: int + source_address: tuple[str, int] | None + socket_options: _TYPE_SOCKET_OPTIONS | None + + proxy: Url | None + proxy_config: ProxyConfig | None + + is_verified: bool = False + proxy_is_verified: bool | None = None + + _response: EmscriptenResponse | None + + def __init__( + self, + host: str, + port: int = 0, + *, + timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, + source_address: tuple[str, int] | None = None, + blocksize: int = 8192, + socket_options: _TYPE_SOCKET_OPTIONS | None = None, + proxy: Url | None = None, + proxy_config: ProxyConfig | None = None, + ) -> None: + self.host = host + self.port = port + self.timeout = timeout if isinstance(timeout, float) else 0.0 + self.scheme = "http" + self._closed = True + self._response = None + # ignore these things because we don't + # have control over that stuff + self.proxy = None + self.proxy_config = None + self.blocksize = blocksize + self.source_address = None + self.socket_options = None + self.is_verified = False + + def set_tunnel( + self, + host: str, + port: int | None = 0, + headers: typing.Mapping[str, str] | None = None, + scheme: str = "http", + ) -> None: + pass + + def connect(self) -> None: + pass + + def request( + self, + method: str, + url: str, + body: _TYPE_BODY | None = None, + headers: typing.Mapping[str, str] | None = None, + # We know *at least* botocore is depending on the order of the + # first 3 parameters so to be safe we only mark the later ones + # as keyword-only to ensure we have space to extend. + *, + chunked: bool = False, + preload_content: bool = True, + decode_content: bool = True, + enforce_content_length: bool = True, + ) -> None: + self._closed = False + if url.startswith("/"): + # no scheme / host / port included, make a full url + url = f"{self.scheme}://{self.host}:{self.port}" + url + request = EmscriptenRequest( + url=url, + method=method, + timeout=self.timeout if self.timeout else 0, + decode_content=decode_content, + ) + request.set_body(body) + if headers: + for k, v in headers.items(): + request.set_header(k, v) + self._response = None + try: + if not preload_content: + self._response = send_streaming_request(request) + if self._response is None: + self._response = send_request(request) + except _TimeoutError as e: + raise TimeoutError(e.message) from e + except _RequestError as e: + raise HTTPException(e.message) from e + + def getresponse(self) -> BaseHTTPResponse: + if self._response is not None: + return EmscriptenHttpResponseWrapper( + internal_response=self._response, + url=self._response.request.url, + connection=self, + ) + else: + raise ResponseNotReady() + + def close(self) -> None: + self._closed = True + self._response = None + + @property + def is_closed(self) -> bool: + """Whether the connection either is brand new or has been previously closed. + If this property is True then both ``is_connected`` and ``has_connected_to_proxy`` + properties must be False. + """ + return self._closed + + @property + def is_connected(self) -> bool: + """Whether the connection is actively connected to any origin (proxy or target)""" + return True + + @property + def has_connected_to_proxy(self) -> bool: + """Whether the connection has successfully connected to its proxy. + This returns False if no proxy is in use. Used to determine whether + errors are coming from the proxy layer or from tunnelling to the target origin. + """ + return False + + +class EmscriptenHTTPSConnection(EmscriptenHTTPConnection): + default_port = port_by_scheme["https"] + # all this is basically ignored, as browser handles https + cert_reqs: int | str | None = None + ca_certs: str | None = None + ca_cert_dir: str | None = None + ca_cert_data: None | str | bytes = None + cert_file: str | None + key_file: str | None + key_password: str | None + ssl_context: typing.Any | None + ssl_version: int | str | None = None + ssl_minimum_version: int | None = None + ssl_maximum_version: int | None = None + assert_hostname: None | str | typing.Literal[False] + assert_fingerprint: str | None = None + + def __init__( + self, + host: str, + port: int = 0, + *, + timeout: _TYPE_TIMEOUT = _DEFAULT_TIMEOUT, + source_address: tuple[str, int] | None = None, + blocksize: int = 16384, + socket_options: None + | _TYPE_SOCKET_OPTIONS = HTTPConnection.default_socket_options, + proxy: Url | None = None, + proxy_config: ProxyConfig | None = None, + cert_reqs: int | str | None = None, + assert_hostname: None | str | typing.Literal[False] = None, + assert_fingerprint: str | None = None, + server_hostname: str | None = None, + ssl_context: typing.Any | None = None, + ca_certs: str | None = None, + ca_cert_dir: str | None = None, + ca_cert_data: None | str | bytes = None, + ssl_minimum_version: int | None = None, + ssl_maximum_version: int | None = None, + ssl_version: int | str | None = None, # Deprecated + cert_file: str | None = None, + key_file: str | None = None, + key_password: str | None = None, + ) -> None: + super().__init__( + host, + port=port, + timeout=timeout, + source_address=source_address, + blocksize=blocksize, + socket_options=socket_options, + proxy=proxy, + proxy_config=proxy_config, + ) + self.scheme = "https" + + 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 + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + self.ssl_version = ssl_version + self.ssl_minimum_version = ssl_minimum_version + self.ssl_maximum_version = ssl_maximum_version + 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 + + self.cert_reqs = None + + # The browser will automatically verify all requests. + # We have no control over that setting. + self.is_verified = True + + def set_cert( + self, + key_file: str | None = None, + cert_file: str | None = None, + cert_reqs: int | str | None = None, + key_password: str | None = None, + ca_certs: str | None = None, + assert_hostname: None | str | typing.Literal[False] = None, + assert_fingerprint: str | None = None, + ca_cert_dir: str | None = None, + ca_cert_data: None | str | bytes = None, + ) -> None: + pass + + +# verify that this class implements BaseHTTP(s) connection correctly +if typing.TYPE_CHECKING: + _supports_http_protocol: BaseHTTPConnection = EmscriptenHTTPConnection("", 0) + _supports_https_protocol: BaseHTTPSConnection = EmscriptenHTTPSConnection("", 0) diff --git a/vendor/urllib3/contrib/emscripten/emscripten_fetch_worker.js b/vendor/urllib3/contrib/emscripten/emscripten_fetch_worker.js new file mode 100644 index 0000000..243b862 --- /dev/null +++ b/vendor/urllib3/contrib/emscripten/emscripten_fetch_worker.js @@ -0,0 +1,110 @@ +let Status = { + SUCCESS_HEADER: -1, + SUCCESS_EOF: -2, + ERROR_TIMEOUT: -3, + ERROR_EXCEPTION: -4, +}; + +let connections = {}; +let nextConnectionID = 1; +const encoder = new TextEncoder(); + +self.addEventListener("message", async function (event) { + if (event.data.close) { + let connectionID = event.data.close; + delete connections[connectionID]; + return; + } else if (event.data.getMore) { + let connectionID = event.data.getMore; + let { curOffset, value, reader, intBuffer, byteBuffer } = + connections[connectionID]; + // if we still have some in buffer, then just send it back straight away + if (!value || curOffset >= value.length) { + // read another buffer if required + try { + let readResponse = await reader.read(); + + if (readResponse.done) { + // read everything - clear connection and return + delete connections[connectionID]; + Atomics.store(intBuffer, 0, Status.SUCCESS_EOF); + Atomics.notify(intBuffer, 0); + // finished reading successfully + // return from event handler + return; + } + curOffset = 0; + connections[connectionID].value = readResponse.value; + value = readResponse.value; + } catch (error) { + console.log("Request exception:", error); + let errorBytes = encoder.encode(error.message); + let written = errorBytes.length; + byteBuffer.set(errorBytes); + intBuffer[1] = written; + Atomics.store(intBuffer, 0, Status.ERROR_EXCEPTION); + Atomics.notify(intBuffer, 0); + } + } + + // send as much buffer as we can + let curLen = value.length - curOffset; + if (curLen > byteBuffer.length) { + curLen = byteBuffer.length; + } + byteBuffer.set(value.subarray(curOffset, curOffset + curLen), 0); + + Atomics.store(intBuffer, 0, curLen); // store current length in bytes + Atomics.notify(intBuffer, 0); + curOffset += curLen; + connections[connectionID].curOffset = curOffset; + + return; + } else { + // start fetch + let connectionID = nextConnectionID; + nextConnectionID += 1; + const intBuffer = new Int32Array(event.data.buffer); + const byteBuffer = new Uint8Array(event.data.buffer, 8); + try { + const response = await fetch(event.data.url, event.data.fetchParams); + // return the headers first via textencoder + var headers = []; + for (const pair of response.headers.entries()) { + headers.push([pair[0], pair[1]]); + } + let headerObj = { + headers: headers, + status: response.status, + connectionID, + }; + const headerText = JSON.stringify(headerObj); + let headerBytes = encoder.encode(headerText); + let written = headerBytes.length; + byteBuffer.set(headerBytes); + intBuffer[1] = written; + // make a connection + connections[connectionID] = { + reader: response.body.getReader(), + intBuffer: intBuffer, + byteBuffer: byteBuffer, + value: undefined, + curOffset: 0, + }; + // set header ready + Atomics.store(intBuffer, 0, Status.SUCCESS_HEADER); + Atomics.notify(intBuffer, 0); + // all fetching after this goes through a new postmessage call with getMore + // this allows for parallel requests + } catch (error) { + console.log("Request exception:", error); + let errorBytes = encoder.encode(error.message); + let written = errorBytes.length; + byteBuffer.set(errorBytes); + intBuffer[1] = written; + Atomics.store(intBuffer, 0, Status.ERROR_EXCEPTION); + Atomics.notify(intBuffer, 0); + } + } +}); +self.postMessage({ inited: true }); diff --git a/vendor/urllib3/contrib/emscripten/fetch.py b/vendor/urllib3/contrib/emscripten/fetch.py new file mode 100644 index 0000000..8d197ea --- /dev/null +++ b/vendor/urllib3/contrib/emscripten/fetch.py @@ -0,0 +1,418 @@ +""" +Support for streaming http requests in emscripten. + +A few caveats - + +Firstly, you can't do streaming http in the main UI thread, because atomics.wait isn't allowed. +Streaming only works if you're running pyodide in a web worker. + +Secondly, this uses an extra web worker and SharedArrayBuffer to do the asynchronous fetch +operation, so it requires that you have crossOriginIsolation enabled, by serving over https +(or from localhost) with the two headers below set: + + Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp + +You can tell if cross origin isolation is successfully enabled by looking at the global crossOriginIsolated variable in +javascript console. If it isn't, streaming requests will fallback to XMLHttpRequest, i.e. getting the whole +request into a buffer and then returning it. it shows a warning in the javascript console in this case. + +Finally, the webworker which does the streaming fetch is created on initial import, but will only be started once +control is returned to javascript. Call `await wait_for_streaming_ready()` to wait for streaming fetch. + +NB: in this code, there are a lot of javascript objects. They are named js_* +to make it clear what type of object they are. +""" +from __future__ import annotations + +import io +import json +from email.parser import Parser +from importlib.resources import files +from typing import TYPE_CHECKING, Any + +import js # type: ignore[import-not-found] +from pyodide.ffi import ( # type: ignore[import-not-found] + JsArray, + JsException, + JsProxy, + to_js, +) + +if TYPE_CHECKING: + from typing_extensions import Buffer + +from .request import EmscriptenRequest +from .response import EmscriptenResponse + +""" +There are some headers that trigger unintended CORS preflight requests. +See also https://github.com/koenvo/pyodide-http/issues/22 +""" +HEADERS_TO_IGNORE = ("user-agent",) + +SUCCESS_HEADER = -1 +SUCCESS_EOF = -2 +ERROR_TIMEOUT = -3 +ERROR_EXCEPTION = -4 + +_STREAMING_WORKER_CODE = ( + files(__package__) + .joinpath("emscripten_fetch_worker.js") + .read_text(encoding="utf-8") +) + + +class _RequestError(Exception): + def __init__( + self, + message: str | None = None, + *, + request: EmscriptenRequest | None = None, + response: EmscriptenResponse | None = None, + ): + self.request = request + self.response = response + self.message = message + super().__init__(self.message) + + +class _StreamingError(_RequestError): + pass + + +class _TimeoutError(_RequestError): + pass + + +def _obj_from_dict(dict_val: dict[str, Any]) -> JsProxy: + return to_js(dict_val, dict_converter=js.Object.fromEntries) + + +class _ReadStream(io.RawIOBase): + def __init__( + self, + int_buffer: JsArray, + byte_buffer: JsArray, + timeout: float, + worker: JsProxy, + connection_id: int, + request: EmscriptenRequest, + ): + self.int_buffer = int_buffer + self.byte_buffer = byte_buffer + self.read_pos = 0 + self.read_len = 0 + self.connection_id = connection_id + self.worker = worker + self.timeout = int(1000 * timeout) if timeout > 0 else None + self.is_live = True + self._is_closed = False + self.request: EmscriptenRequest | None = request + + def __del__(self) -> None: + self.close() + + # this is compatible with _base_connection + def is_closed(self) -> bool: + return self._is_closed + + # for compatibility with RawIOBase + @property + def closed(self) -> bool: + return self.is_closed() + + def close(self) -> None: + if not self.is_closed(): + self.read_len = 0 + self.read_pos = 0 + self.int_buffer = None + self.byte_buffer = None + self._is_closed = True + self.request = None + if self.is_live: + self.worker.postMessage(_obj_from_dict({"close": self.connection_id})) + self.is_live = False + super().close() + + def readable(self) -> bool: + return True + + def writable(self) -> bool: + return False + + def seekable(self) -> bool: + return False + + def readinto(self, byte_obj: Buffer) -> int: + if not self.int_buffer: + raise _StreamingError( + "No buffer for stream in _ReadStream.readinto", + request=self.request, + response=None, + ) + if self.read_len == 0: + # wait for the worker to send something + js.Atomics.store(self.int_buffer, 0, ERROR_TIMEOUT) + self.worker.postMessage(_obj_from_dict({"getMore": self.connection_id})) + if ( + js.Atomics.wait(self.int_buffer, 0, ERROR_TIMEOUT, self.timeout) + == "timed-out" + ): + raise _TimeoutError + data_len = self.int_buffer[0] + if data_len > 0: + self.read_len = data_len + self.read_pos = 0 + elif data_len == ERROR_EXCEPTION: + string_len = self.int_buffer[1] + # decode the error string + js_decoder = js.TextDecoder.new() + json_str = js_decoder.decode(self.byte_buffer.slice(0, string_len)) + raise _StreamingError( + f"Exception thrown in fetch: {json_str}", + request=self.request, + response=None, + ) + else: + # EOF, free the buffers and return zero + # and free the request + self.is_live = False + self.close() + return 0 + # copy from int32array to python bytes + ret_length = min(self.read_len, len(memoryview(byte_obj))) + subarray = self.byte_buffer.subarray( + self.read_pos, self.read_pos + ret_length + ).to_py() + memoryview(byte_obj)[0:ret_length] = subarray + self.read_len -= ret_length + self.read_pos += ret_length + return ret_length + + +class _StreamingFetcher: + def __init__(self) -> None: + # make web-worker and data buffer on startup + self.streaming_ready = False + + js_data_blob = js.Blob.new( + [_STREAMING_WORKER_CODE], _obj_from_dict({"type": "application/javascript"}) + ) + + def promise_resolver(js_resolve_fn: JsProxy, js_reject_fn: JsProxy) -> None: + def onMsg(e: JsProxy) -> None: + self.streaming_ready = True + js_resolve_fn(e) + + def onErr(e: JsProxy) -> None: + js_reject_fn(e) # Defensive: never happens in ci + + self.js_worker.onmessage = onMsg + self.js_worker.onerror = onErr + + js_data_url = js.URL.createObjectURL(js_data_blob) + self.js_worker = js.globalThis.Worker.new(js_data_url) + self.js_worker_ready_promise = js.globalThis.Promise.new(promise_resolver) + + def send(self, request: EmscriptenRequest) -> EmscriptenResponse: + headers = { + k: v for k, v in request.headers.items() if k not in HEADERS_TO_IGNORE + } + + body = request.body + fetch_data = {"headers": headers, "body": to_js(body), "method": request.method} + # start the request off in the worker + timeout = int(1000 * request.timeout) if request.timeout > 0 else None + js_shared_buffer = js.SharedArrayBuffer.new(1048576) + js_int_buffer = js.Int32Array.new(js_shared_buffer) + js_byte_buffer = js.Uint8Array.new(js_shared_buffer, 8) + + js.Atomics.store(js_int_buffer, 0, ERROR_TIMEOUT) + js.Atomics.notify(js_int_buffer, 0) + js_absolute_url = js.URL.new(request.url, js.location).href + self.js_worker.postMessage( + _obj_from_dict( + { + "buffer": js_shared_buffer, + "url": js_absolute_url, + "fetchParams": fetch_data, + } + ) + ) + # wait for the worker to send something + js.Atomics.wait(js_int_buffer, 0, ERROR_TIMEOUT, timeout) + if js_int_buffer[0] == ERROR_TIMEOUT: + raise _TimeoutError( + "Timeout connecting to streaming request", + request=request, + response=None, + ) + elif js_int_buffer[0] == SUCCESS_HEADER: + # got response + # header length is in second int of intBuffer + string_len = js_int_buffer[1] + # decode the rest to a JSON string + js_decoder = js.TextDecoder.new() + # this does a copy (the slice) because decode can't work on shared array + # for some silly reason + json_str = js_decoder.decode(js_byte_buffer.slice(0, string_len)) + # get it as an object + response_obj = json.loads(json_str) + return EmscriptenResponse( + request=request, + status_code=response_obj["status"], + headers=response_obj["headers"], + body=_ReadStream( + js_int_buffer, + js_byte_buffer, + request.timeout, + self.js_worker, + response_obj["connectionID"], + request, + ), + ) + elif js_int_buffer[0] == ERROR_EXCEPTION: + string_len = js_int_buffer[1] + # decode the error string + js_decoder = js.TextDecoder.new() + json_str = js_decoder.decode(js_byte_buffer.slice(0, string_len)) + raise _StreamingError( + f"Exception thrown in fetch: {json_str}", request=request, response=None + ) + else: + raise _StreamingError( + f"Unknown status from worker in fetch: {js_int_buffer[0]}", + request=request, + response=None, + ) + + +# check if we are in a worker or not +def is_in_browser_main_thread() -> bool: + return hasattr(js, "window") and hasattr(js, "self") and js.self == js.window + + +def is_cross_origin_isolated() -> bool: + return hasattr(js, "crossOriginIsolated") and js.crossOriginIsolated + + +def is_in_node() -> bool: + return ( + hasattr(js, "process") + and hasattr(js.process, "release") + and hasattr(js.process.release, "name") + and js.process.release.name == "node" + ) + + +def is_worker_available() -> bool: + return hasattr(js, "Worker") and hasattr(js, "Blob") + + +_fetcher: _StreamingFetcher | None = None + +if is_worker_available() and ( + (is_cross_origin_isolated() and not is_in_browser_main_thread()) + and (not is_in_node()) +): + _fetcher = _StreamingFetcher() +else: + _fetcher = None + + +def send_streaming_request(request: EmscriptenRequest) -> EmscriptenResponse | None: + if _fetcher and streaming_ready(): + return _fetcher.send(request) + else: + _show_streaming_warning() + return None + + +_SHOWN_TIMEOUT_WARNING = False + + +def _show_timeout_warning() -> None: + global _SHOWN_TIMEOUT_WARNING + if not _SHOWN_TIMEOUT_WARNING: + _SHOWN_TIMEOUT_WARNING = True + message = "Warning: Timeout is not available on main browser thread" + js.console.warn(message) + + +_SHOWN_STREAMING_WARNING = False + + +def _show_streaming_warning() -> None: + global _SHOWN_STREAMING_WARNING + if not _SHOWN_STREAMING_WARNING: + _SHOWN_STREAMING_WARNING = True + message = "Can't stream HTTP requests because: \n" + if not is_cross_origin_isolated(): + message += " Page is not cross-origin isolated\n" + if is_in_browser_main_thread(): + message += " Python is running in main browser thread\n" + if not is_worker_available(): + message += " Worker or Blob classes are not available in this environment." # Defensive: this is always False in browsers that we test in + if streaming_ready() is False: + message += """ Streaming fetch worker isn't ready. If you want to be sure that streaming fetch +is working, you need to call: 'await urllib3.contrib.emscripten.fetch.wait_for_streaming_ready()`""" + from js import console + + console.warn(message) + + +def send_request(request: EmscriptenRequest) -> EmscriptenResponse: + try: + js_xhr = js.XMLHttpRequest.new() + + if not is_in_browser_main_thread(): + js_xhr.responseType = "arraybuffer" + if request.timeout: + js_xhr.timeout = int(request.timeout * 1000) + else: + js_xhr.overrideMimeType("text/plain; charset=ISO-8859-15") + if request.timeout: + # timeout isn't available on the main thread - show a warning in console + # if it is set + _show_timeout_warning() + + js_xhr.open(request.method, request.url, False) + for name, value in request.headers.items(): + if name.lower() not in HEADERS_TO_IGNORE: + js_xhr.setRequestHeader(name, value) + + js_xhr.send(to_js(request.body)) + + headers = dict(Parser().parsestr(js_xhr.getAllResponseHeaders())) + + if not is_in_browser_main_thread(): + body = js_xhr.response.to_py().tobytes() + else: + body = js_xhr.response.encode("ISO-8859-15") + return EmscriptenResponse( + status_code=js_xhr.status, headers=headers, body=body, request=request + ) + except JsException as err: + if err.name == "TimeoutError": + raise _TimeoutError(err.message, request=request) + elif err.name == "NetworkError": + raise _RequestError(err.message, request=request) + else: + # general http error + raise _RequestError(err.message, request=request) + + +def streaming_ready() -> bool | None: + if _fetcher: + return _fetcher.streaming_ready + else: + return None # no fetcher, return None to signify that + + +async def wait_for_streaming_ready() -> bool: + if _fetcher: + await _fetcher.js_worker_ready_promise + return True + else: + return False diff --git a/vendor/urllib3/contrib/emscripten/request.py b/vendor/urllib3/contrib/emscripten/request.py new file mode 100644 index 0000000..e692e69 --- /dev/null +++ b/vendor/urllib3/contrib/emscripten/request.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +from dataclasses import dataclass, field + +from ..._base_connection import _TYPE_BODY + + +@dataclass +class EmscriptenRequest: + method: str + url: str + params: dict[str, str] | None = None + body: _TYPE_BODY | None = None + headers: dict[str, str] = field(default_factory=dict) + timeout: float = 0 + decode_content: bool = True + + def set_header(self, name: str, value: str) -> None: + self.headers[name.capitalize()] = value + + def set_body(self, body: _TYPE_BODY | None) -> None: + self.body = body diff --git a/vendor/urllib3/contrib/emscripten/response.py b/vendor/urllib3/contrib/emscripten/response.py new file mode 100644 index 0000000..cd3d80e --- /dev/null +++ b/vendor/urllib3/contrib/emscripten/response.py @@ -0,0 +1,285 @@ +from __future__ import annotations + +import json as _json +import logging +import typing +from contextlib import contextmanager +from dataclasses import dataclass +from http.client import HTTPException as HTTPException +from io import BytesIO, IOBase + +from ...exceptions import InvalidHeader, TimeoutError +from ...response import BaseHTTPResponse +from ...util.retry import Retry +from .request import EmscriptenRequest + +if typing.TYPE_CHECKING: + from ..._base_connection import BaseHTTPConnection, BaseHTTPSConnection + +log = logging.getLogger(__name__) + + +@dataclass +class EmscriptenResponse: + status_code: int + headers: dict[str, str] + body: IOBase | bytes + request: EmscriptenRequest + + +class EmscriptenHttpResponseWrapper(BaseHTTPResponse): + def __init__( + self, + internal_response: EmscriptenResponse, + url: str | None = None, + connection: BaseHTTPConnection | BaseHTTPSConnection | None = None, + ): + self._pool = None # set by pool class + self._body = None + self._response = internal_response + self._url = url + self._connection = connection + self._closed = False + super().__init__( + headers=internal_response.headers, + status=internal_response.status_code, + request_url=url, + version=0, + version_string="HTTP/?", + reason="", + decode_content=True, + ) + self.length_remaining = self._init_length(self._response.request.method) + self.length_is_certain = False + + @property + def url(self) -> str | None: + return self._url + + @url.setter + def url(self, url: str | None) -> None: + self._url = url + + @property + def connection(self) -> BaseHTTPConnection | BaseHTTPSConnection | None: + return self._connection + + @property + def retries(self) -> Retry | None: + return self._retries + + @retries.setter + def retries(self, retries: Retry | None) -> None: + # Override the request_url if retries has a redirect location. + self._retries = retries + + def stream( + self, amt: int | None = 2**16, decode_content: bool | None = None + ) -> typing.Generator[bytes, None, 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. + """ + while True: + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + else: + break + + def _init_length(self, request_method: str | None) -> int | None: + length: int | None + content_length: str | None = self.headers.get("content-length") + + if content_length is not 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 = {int(val) for val in content_length.split(",")} + if len(lengths) > 1: + raise InvalidHeader( + "Content-Length contained multiple " + "unmatching values (%s)" % content_length + ) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + else: # if content_length is None + length = None + + # Check for responses that shouldn't include a body + if ( + self.status in (204, 304) + or 100 <= self.status < 200 + or request_method == "HEAD" + ): + length = 0 + + return length + + def read( + self, + amt: int | None = None, + decode_content: bool | None = None, # ignored because browser decodes always + cache_content: bool = False, + ) -> bytes: + if ( + self._closed + or self._response is None + or (isinstance(self._response.body, IOBase) and self._response.body.closed) + ): + return b"" + + with self._error_catcher(): + # body has been preloaded as a string by XmlHttpRequest + if not isinstance(self._response.body, IOBase): + self.length_remaining = len(self._response.body) + self.length_is_certain = True + # wrap body in IOStream + self._response.body = BytesIO(self._response.body) + if amt is not None and amt >= 0: + # don't cache partial content + cache_content = False + data = self._response.body.read(amt) + if self.length_remaining is not None: + self.length_remaining = max(self.length_remaining - len(data), 0) + if (self.length_is_certain and self.length_remaining == 0) or len( + data + ) < amt: + # definitely finished reading, close response stream + self._response.body.close() + return typing.cast(bytes, data) + else: # read all we can (and cache it) + data = self._response.body.read() + if cache_content: + self._body = data + if self.length_remaining is not None: + self.length_remaining = max(self.length_remaining - len(data), 0) + if len(data) == 0 or ( + self.length_is_certain and self.length_remaining == 0 + ): + # definitely finished reading, close response stream + self._response.body.close() + return typing.cast(bytes, data) + + def read_chunked( + self, + amt: int | None = None, + decode_content: bool | None = None, + ) -> typing.Generator[bytes, None, None]: + # chunked is handled by browser + while True: + bytes = self.read(amt, decode_content) + if not bytes: + break + yield bytes + + def release_conn(self) -> None: + if not self._pool or not self._connection: + return None + + self._pool._put_conn(self._connection) + self._connection = None + + def drain_conn(self) -> None: + self.close() + + @property + def data(self) -> bytes: + if self._body: + return self._body + else: + return self.read(cache_content=True) + + def json(self) -> typing.Any: + """ + Deserializes the body of the HTTP response as a Python object. + + The body of the HTTP response must be encoded using UTF-8, as per + `RFC 8529 Section 8.1 `_. + + To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to + your custom decoder instead. + + If the body of the HTTP response is not decodable to UTF-8, a + `UnicodeDecodeError` will be raised. If the body of the HTTP response is not a + valid JSON document, a `json.JSONDecodeError` will be raised. + + Read more :ref:`here `. + + :returns: The body of the HTTP response as a Python object. + """ + data = self.data.decode("utf-8") + return _json.loads(data) + + def close(self) -> None: + if not self._closed: + if isinstance(self._response.body, IOBase): + self._response.body.close() + if self._connection: + self._connection.close() + self._connection = None + self._closed = True + + @contextmanager + def _error_catcher(self) -> typing.Generator[None, None, None]: + """ + Catch Emscripten specific exceptions thrown by fetch.py, + 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. + """ + from .fetch import _RequestError, _TimeoutError # avoid circular import + + clean_exit = False + + try: + yield + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + except _TimeoutError as e: + raise TimeoutError(str(e)) + except _RequestError as e: + raise HTTPException(str(e)) + 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 + if ( + isinstance(self._response.body, IOBase) + and not self._response.body.closed + ): + self._response.body.close() + # release the connection back to the pool + self.release_conn() + else: + # If we have read everything from the response stream, + # return the connection back to the pool. + if ( + isinstance(self._response.body, IOBase) + and self._response.body.closed + ): + self.release_conn() diff --git a/vendor/urllib3/contrib/pyopenssl.py b/vendor/urllib3/contrib/pyopenssl.py index 0089cd2..c12cb31 100644 --- a/vendor/urllib3/contrib/pyopenssl.py +++ b/vendor/urllib3/contrib/pyopenssl.py @@ -8,10 +8,10 @@ * `pyOpenSSL`_ (tested with 16.0.0) * `cryptography`_ (minimum 1.3.4, from pyopenssl) -* `idna`_ (minimum 2.0, from cryptography) +* `idna`_ (minimum 2.0) -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. +However, pyOpenSSL depends on cryptography, so while we use all three directly here we +end up having relatively few packages required. You can install them with the following command: @@ -40,7 +40,7 @@ from __future__ import annotations -import OpenSSL.SSL # type: ignore[import] +import OpenSSL.SSL # type: ignore[import-untyped] from cryptography import x509 try: @@ -54,29 +54,20 @@ class UnsupportedExtension(Exception): # type: ignore[no-redef] import logging import ssl import typing -import warnings from io import BytesIO from socket import socket as socket_cls from socket import timeout from .. import util -warnings.warn( - "'urllib3.contrib.pyopenssl' module is deprecated and will be removed " - "in urllib3 v2.1.0. Read more in this issue: " - "https://github.com/urllib3/urllib3/issues/2680", - category=DeprecationWarning, - stacklevel=2, -) - if typing.TYPE_CHECKING: - from OpenSSL.crypto import X509 # type: ignore[import] + from OpenSSL.crypto import X509 # type: ignore[import-untyped] __all__ = ["inject_into_urllib3", "extract_from_urllib3"] # Map from urllib3 to PyOpenSSL compatible parameter-values. -_openssl_versions = { +_openssl_versions: dict[int, int] = { util.ssl_.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD, # type: ignore[attr-defined] util.ssl_.PROTOCOL_TLS_CLIENT: OpenSSL.SSL.SSLv23_METHOD, # type: ignore[attr-defined] ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, @@ -409,6 +400,10 @@ def getpeercert( def version(self) -> str: return self.connection.get_protocol_version_name() # type: ignore[no-any-return] + def selected_alpn_protocol(self) -> str | None: + alpn_proto = self.connection.get_alpn_proto_negotiated() + return alpn_proto.decode() if alpn_proto else None + WrappedSocket.makefile = socket_cls.makefile # type: ignore[attr-defined] diff --git a/vendor/urllib3/contrib/securetransport.py b/vendor/urllib3/contrib/securetransport.py deleted file mode 100644 index 11beb3d..0000000 --- a/vendor/urllib3/contrib/securetransport.py +++ /dev/null @@ -1,913 +0,0 @@ -""" -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 annotations - -import contextlib -import ctypes -import errno -import os.path -import shutil -import socket -import ssl -import struct -import threading -import typing -import warnings -import weakref -from socket import socket as socket_cls - -from .. import util -from ._securetransport.bindings import ( # type: ignore[attr-defined] - CoreFoundation, - Security, -) -from ._securetransport.low_level import ( - SecurityConst, - _assert_no_error, - _build_tls_unknown_ca_alert, - _cert_array_from_pem, - _create_cfstring_array, - _load_client_cert_chain, - _temporary_keychain, -) - -warnings.warn( - "'urllib3.contrib.securetransport' module is deprecated and will be removed " - "in urllib3 v2.1.0. Read more in this issue: " - "https://github.com/urllib3/urllib3/issues/2681", - category=DeprecationWarning, - stacklevel=2, -) - -if typing.TYPE_CHECKING: - from typing_extensions import Literal - -__all__ = ["inject_into_urllib3", "extract_from_urllib3"] - -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[ - int, WrappedSocket -] = 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 - -# 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.ssl_.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), # type: ignore[attr-defined] - util.ssl_.PROTOCOL_TLS_CLIENT: ( # type: ignore[attr-defined] - 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, - ) - - -_tls_version_to_st: dict[int, int] = { - ssl.TLSVersion.MINIMUM_SUPPORTED: SecurityConst.kTLSProtocol1, - ssl.TLSVersion.TLSv1: SecurityConst.kTLSProtocol1, - ssl.TLSVersion.TLSv1_1: SecurityConst.kTLSProtocol11, - ssl.TLSVersion.TLSv1_2: SecurityConst.kTLSProtocol12, - ssl.TLSVersion.MAXIMUM_SUPPORTED: SecurityConst.kTLSProtocol12, -} - - -def inject_into_urllib3() -> None: - """ - Monkey-patch urllib3 with SecureTransport-backed SSL-support. - """ - util.SSLContext = SecureTransportContext # type: ignore[assignment] - util.ssl_.SSLContext = SecureTransportContext # type: ignore[assignment] - util.IS_SECURETRANSPORT = True - util.ssl_.IS_SECURETRANSPORT = True - - -def extract_from_urllib3() -> None: - """ - Undo monkey-patching by :func:`inject_into_urllib3`. - """ - util.SSLContext = orig_util_SSLContext - util.ssl_.SSLContext = orig_util_SSLContext - util.IS_SECURETRANSPORT = False - util.ssl_.IS_SECURETRANSPORT = False - - -def _read_callback( - connection_id: int, data_buffer: int, data_length_pointer: bytearray -) -> int: - """ - 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 OSError(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 OSError 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: int, data_buffer: int, data_length_pointer: bytearray -) -> int: - """ - 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 OSError(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 OSError 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: - """ - API-compatibility wrapper for Python's OpenSSL wrapped socket object. - """ - - def __init__(self, socket: socket_cls) -> None: - self.socket = socket - self.context = None - self._io_refs = 0 - self._closed = False - self._real_closed = False - self._exception: Exception | None = None - self._keychain = None - self._keychain_dir: str | None = 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) -> typing.Generator[None, None, None]: - """ - 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._real_close() - raise exception - - def _set_alpn_protocols(self, protocols: list[bytes] | None) -> None: - """ - 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: bool, trust_bundle: bytes | None) -> None: - """ - 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 or trust_bundle is None: - return - - successes = ( - SecurityConst.kSecTrustResultUnspecified, - SecurityConst.kSecTrustResultProceed, - ) - try: - trust_result = self._evaluate_trust(trust_bundle) - if trust_result in successes: - return - reason = f"error code: {int(trust_result)}" - exc = None - except Exception as e: - # Do not trust on error - reason = f"exception: {e!r}" - exc = 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._real_close() - raise ssl.SSLError(f"certificate verify failed, {reason}") from exc - - def _evaluate_trust(self, trust_bundle: bytes) -> int: - # 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 # type: ignore[no-any-return] - - def handshake( - self, - server_hostname: bytes | str | None, - verify: bool, - trust_bundle: bytes | None, - min_version: int, - max_version: int, - client_cert: str | None, - client_key: str | None, - client_key_passphrase: typing.Any, - alpn_protocols: list[bytes] | None, - ) -> None: - """ - 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. - # RFC6066 Section 3 tells us not to use SNI when the host is an IP, but we have - # to do it anyway to match server_hostname against the server certificate - 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 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) -> int: - return self.socket.fileno() - - # Copy-pasted from Python 3.5 source code - def _decref_socketios(self) -> None: - if self._io_refs > 0: - self._io_refs -= 1 - if self._closed: - self.close() - - def recv(self, bufsiz: int) -> bytes: - buffer = ctypes.create_string_buffer(bufsiz) - bytes_read = self.recv_into(buffer, bufsiz) - data = buffer[:bytes_read] - return typing.cast(bytes, data) - - def recv_into( - self, buffer: ctypes.Array[ctypes.c_char], nbytes: int | None = None - ) -> int: - # Read short on EOF. - if self._real_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._real_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: float) -> None: - self._timeout = timeout - - def gettimeout(self) -> float | None: - return self._timeout - - def send(self, data: bytes) -> int: - 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: bytes) -> None: - 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) -> None: - with self._raise_on_error(): - Security.SSLClose(self.context) - - def close(self) -> None: - self._closed = True - # TODO: should I do clean shutdown here? Do I have to? - if self._io_refs <= 0: - self._real_close() - - def _real_close(self) -> None: - self._real_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() - - def getpeercert(self, binary_form: bool = False) -> bytes | None: - # 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) -> str: - 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(f"Unknown TLS version: {protocol!r}") - - -def makefile( - self: socket_cls, - mode: ( - Literal["r"] | Literal["w"] | Literal["rw"] | Literal["wr"] | Literal[""] - ) = "r", - buffering: int | None = None, - *args: typing.Any, - **kwargs: typing.Any, -) -> typing.BinaryIO | typing.TextIO: - # We disable buffering with SecureTransport because it conflicts with - # the buffering that ST does internally (see issue #1153 for more). - buffering = 0 - return socket_cls.makefile(self, mode, buffering, *args, **kwargs) - - -WrappedSocket.makefile = makefile # type: ignore[attr-defined] - - -class SecureTransportContext: - """ - 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: int) -> None: - self._minimum_version: int = ssl.TLSVersion.MINIMUM_SUPPORTED - self._maximum_version: int = ssl.TLSVersion.MAXIMUM_SUPPORTED - if protocol not in (None, ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS_CLIENT): - self._min_version, self._max_version = _protocol_to_min_max[protocol] - - self._options = 0 - self._verify = False - self._trust_bundle: bytes | None = None - self._client_cert: str | None = None - self._client_key: str | None = None - self._client_key_passphrase = None - self._alpn_protocols: list[bytes] | None = None - - @property - def check_hostname(self) -> Literal[True]: - """ - 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: typing.Any) -> None: - """ - SecureTransport cannot have its hostname checking disabled. For more, - see the comment on getpeercert() in this file. - """ - - @property - def options(self) -> int: - # 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: int) -> None: - # TODO: Update in line with above. - self._options = value - - @property - def verify_mode(self) -> int: - return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE - - @verify_mode.setter - def verify_mode(self, value: int) -> None: - self._verify = value == ssl.CERT_REQUIRED - - def set_default_verify_paths(self) -> None: - # 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) -> None: - return self.set_default_verify_paths() - - def set_ciphers(self, ciphers: typing.Any) -> None: - raise ValueError("SecureTransport doesn't support custom cipher strings") - - def load_verify_locations( - self, - cafile: str | None = None, - capath: str | None = None, - cadata: bytes | None = None, - ) -> 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 # type: ignore[assignment] - - def load_cert_chain( - self, - certfile: str, - keyfile: str | None = None, - password: str | None = None, - ) -> None: - self._client_cert = certfile - self._client_key = keyfile - self._client_cert_passphrase = password - - def set_alpn_protocols(self, protocols: list[str | bytes]) -> None: - """ - 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 = [util.util.to_bytes(p, "ascii") for p in protocols] - - def wrap_socket( - self, - sock: socket_cls, - server_side: bool = False, - do_handshake_on_connect: bool = True, - suppress_ragged_eofs: bool = True, - server_hostname: bytes | str | None = None, - ) -> WrappedSocket: - # 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, - _tls_version_to_st[self._minimum_version], - _tls_version_to_st[self._maximum_version], - self._client_cert, - self._client_key, - self._client_key_passphrase, - self._alpn_protocols, - ) - return wrapped_socket - - @property - def minimum_version(self) -> int: - return self._minimum_version - - @minimum_version.setter - def minimum_version(self, minimum_version: int) -> None: - self._minimum_version = minimum_version - - @property - def maximum_version(self) -> int: - return self._maximum_version - - @maximum_version.setter - def maximum_version(self, maximum_version: int) -> None: - self._maximum_version = maximum_version diff --git a/vendor/urllib3/contrib/socks.py b/vendor/urllib3/contrib/socks.py index 5e552dd..c62b5e0 100644 --- a/vendor/urllib3/contrib/socks.py +++ b/vendor/urllib3/contrib/socks.py @@ -41,7 +41,7 @@ from __future__ import annotations try: - import socks # type: ignore[import] + import socks # type: ignore[import-not-found] except ImportError: import warnings @@ -51,7 +51,7 @@ ( "SOCKS support in urllib3 requires the installation of optional " "dependencies: specifically, PySocks. For more information, see " - "https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies" + "https://urllib3.readthedocs.io/en/latest/advanced-usage.html#socks-proxies" ), DependencyWarning, ) @@ -71,19 +71,14 @@ except ImportError: ssl = None # type: ignore[assignment] -try: - from typing import TypedDict - - class _TYPE_SOCKS_OPTIONS(TypedDict): - socks_version: int - proxy_host: str | None - proxy_port: str | None - username: str | None - password: str | None - rdns: bool - -except ImportError: # Python 3.7 - _TYPE_SOCKS_OPTIONS = typing.Dict[str, typing.Any] # type: ignore[misc, assignment] + +class _TYPE_SOCKS_OPTIONS(typing.TypedDict): + socks_version: int + proxy_host: str | None + proxy_port: str | None + username: str | None + password: str | None + rdns: bool class SOCKSConnection(HTTPConnection): diff --git a/vendor/urllib3/exceptions.py b/vendor/urllib3/exceptions.py index 7f42689..b0792f0 100644 --- a/vendor/urllib3/exceptions.py +++ b/vendor/urllib3/exceptions.py @@ -214,6 +214,10 @@ class InsecureRequestWarning(SecurityWarning): """Warned when making an unverified HTTPS request.""" +class NotOpenSSLWarning(SecurityWarning): + """Warned when using unsupported SSL library""" + + class SystemTimeWarning(SecurityWarning): """Warned when system time is suspected to be wrong""" @@ -248,13 +252,16 @@ class IncompleteRead(HTTPError, httplib_IncompleteRead): for ``partial`` to avoid creating large objects on streamed reads. """ + partial: int # type: ignore[assignment] + expected: int + def __init__(self, partial: int, expected: int) -> None: - self.partial = partial # type: ignore[assignment] + self.partial = partial self.expected = expected def __repr__(self) -> str: return "IncompleteRead(%i bytes read, %i more expected)" % ( - self.partial, # type: ignore[str-format] + self.partial, self.expected, ) diff --git a/vendor/urllib3/fields.py b/vendor/urllib3/fields.py index 51d898e..3e258a5 100644 --- a/vendor/urllib3/fields.py +++ b/vendor/urllib3/fields.py @@ -225,13 +225,9 @@ def from_tuples( if isinstance(value, tuple): if len(value) == 3: - filename, data, content_type = typing.cast( - typing.Tuple[str, _TYPE_FIELD_VALUE, str], value - ) + filename, data, content_type = value else: - filename, data = typing.cast( - typing.Tuple[str, _TYPE_FIELD_VALUE], value - ) + filename, data = value content_type = guess_content_type(filename) else: filename = None diff --git a/vendor/urllib3/http2/__init__.py b/vendor/urllib3/http2/__init__.py new file mode 100644 index 0000000..133e1d8 --- /dev/null +++ b/vendor/urllib3/http2/__init__.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +from importlib.metadata import version + +__all__ = [ + "inject_into_urllib3", + "extract_from_urllib3", +] + +import typing + +orig_HTTPSConnection: typing.Any = None + + +def inject_into_urllib3() -> None: + # First check if h2 version is valid + h2_version = version("h2") + if not h2_version.startswith("4."): + raise ImportError( + "urllib3 v2 supports h2 version 4.x.x, currently " + f"the 'h2' module is compiled with {h2_version!r}. " + "See: https://github.com/urllib3/urllib3/issues/3290" + ) + + # Import here to avoid circular dependencies. + from .. import connection as urllib3_connection + from .. import util as urllib3_util + from ..connectionpool import HTTPSConnectionPool + from ..util import ssl_ as urllib3_util_ssl + from .connection import HTTP2Connection + + global orig_HTTPSConnection + orig_HTTPSConnection = urllib3_connection.HTTPSConnection + + HTTPSConnectionPool.ConnectionCls = HTTP2Connection + urllib3_connection.HTTPSConnection = HTTP2Connection # type: ignore[misc] + + # TODO: Offer 'http/1.1' as well, but for testing purposes this is handy. + urllib3_util.ALPN_PROTOCOLS = ["h2"] + urllib3_util_ssl.ALPN_PROTOCOLS = ["h2"] + + +def extract_from_urllib3() -> None: + from .. import connection as urllib3_connection + from .. import util as urllib3_util + from ..connectionpool import HTTPSConnectionPool + from ..util import ssl_ as urllib3_util_ssl + + HTTPSConnectionPool.ConnectionCls = orig_HTTPSConnection + urllib3_connection.HTTPSConnection = orig_HTTPSConnection # type: ignore[misc] + + urllib3_util.ALPN_PROTOCOLS = ["http/1.1"] + urllib3_util_ssl.ALPN_PROTOCOLS = ["http/1.1"] diff --git a/vendor/urllib3/http2/connection.py b/vendor/urllib3/http2/connection.py new file mode 100644 index 0000000..f486145 --- /dev/null +++ b/vendor/urllib3/http2/connection.py @@ -0,0 +1,356 @@ +from __future__ import annotations + +import logging +import re +import threading +import types +import typing + +import h2.config # type: ignore[import-untyped] +import h2.connection # type: ignore[import-untyped] +import h2.events # type: ignore[import-untyped] + +from .._base_connection import _TYPE_BODY +from .._collections import HTTPHeaderDict +from ..connection import HTTPSConnection, _get_default_user_agent +from ..exceptions import ConnectionError +from ..response import BaseHTTPResponse + +orig_HTTPSConnection = HTTPSConnection + +T = typing.TypeVar("T") + +log = logging.getLogger(__name__) + +RE_IS_LEGAL_HEADER_NAME = re.compile(rb"^[!#$%&'*+\-.^_`|~0-9a-z]+$") +RE_IS_ILLEGAL_HEADER_VALUE = re.compile(rb"[\0\x00\x0a\x0d\r\n]|^[ \r\n\t]|[ \r\n\t]$") + + +def _is_legal_header_name(name: bytes) -> bool: + """ + "An implementation that validates fields according to the definitions in Sections + 5.1 and 5.5 of [HTTP] only needs an additional check that field names do not + include uppercase characters." (https://httpwg.org/specs/rfc9113.html#n-field-validity) + + `http.client._is_legal_header_name` does not validate the field name according to the + HTTP 1.1 spec, so we do that here, in addition to checking for uppercase characters. + + This does not allow for the `:` character in the header name, so should not + be used to validate pseudo-headers. + """ + return bool(RE_IS_LEGAL_HEADER_NAME.match(name)) + + +def _is_illegal_header_value(value: bytes) -> bool: + """ + "A field value MUST NOT contain the zero value (ASCII NUL, 0x00), line feed + (ASCII LF, 0x0a), or carriage return (ASCII CR, 0x0d) at any position. A field + value MUST NOT start or end with an ASCII whitespace character (ASCII SP or HTAB, + 0x20 or 0x09)." (https://httpwg.org/specs/rfc9113.html#n-field-validity) + """ + return bool(RE_IS_ILLEGAL_HEADER_VALUE.search(value)) + + +class _LockedObject(typing.Generic[T]): + """ + A wrapper class that hides a specific object behind a lock. + The goal here is to provide a simple way to protect access to an object + that cannot safely be simultaneously accessed from multiple threads. The + intended use of this class is simple: take hold of it with a context + manager, which returns the protected object. + """ + + __slots__ = ( + "lock", + "_obj", + ) + + def __init__(self, obj: T): + self.lock = threading.RLock() + self._obj = obj + + def __enter__(self) -> T: + self.lock.acquire() + return self._obj + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: types.TracebackType | None, + ) -> None: + self.lock.release() + + +class HTTP2Connection(HTTPSConnection): + def __init__( + self, host: str, port: int | None = None, **kwargs: typing.Any + ) -> None: + self._h2_conn = self._new_h2_conn() + self._h2_stream: int | None = None + self._headers: list[tuple[bytes, bytes]] = [] + + if "proxy" in kwargs or "proxy_config" in kwargs: # Defensive: + raise NotImplementedError("Proxies aren't supported with HTTP/2") + + super().__init__(host, port, **kwargs) + + if self._tunnel_host is not None: + raise NotImplementedError("Tunneling isn't supported with HTTP/2") + + def _new_h2_conn(self) -> _LockedObject[h2.connection.H2Connection]: + config = h2.config.H2Configuration(client_side=True) + return _LockedObject(h2.connection.H2Connection(config=config)) + + def connect(self) -> None: + super().connect() + with self._h2_conn as conn: + conn.initiate_connection() + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + + def putrequest( # type: ignore[override] + self, + method: str, + url: str, + **kwargs: typing.Any, + ) -> None: + """putrequest + This deviates from the HTTPConnection method signature since we never need to override + sending accept-encoding headers or the host header. + """ + if "skip_host" in kwargs: + raise NotImplementedError("`skip_host` isn't supported") + if "skip_accept_encoding" in kwargs: + raise NotImplementedError("`skip_accept_encoding` isn't supported") + + self._request_url = url or "/" + self._validate_path(url) # type: ignore[attr-defined] + + if ":" in self.host: + authority = f"[{self.host}]:{self.port or 443}" + else: + authority = f"{self.host}:{self.port or 443}" + + self._headers.append((b":scheme", b"https")) + self._headers.append((b":method", method.encode())) + self._headers.append((b":authority", authority.encode())) + self._headers.append((b":path", url.encode())) + + with self._h2_conn as conn: + self._h2_stream = conn.get_next_available_stream_id() + + def putheader(self, header: str | bytes, *values: str | bytes) -> None: + # TODO SKIPPABLE_HEADERS from urllib3 are ignored. + header = header.encode() if isinstance(header, str) else header + header = header.lower() # A lot of upstream code uses capitalized headers. + if not _is_legal_header_name(header): + raise ValueError(f"Illegal header name {str(header)}") + + for value in values: + value = value.encode() if isinstance(value, str) else value + if _is_illegal_header_value(value): + raise ValueError(f"Illegal header value {str(value)}") + self._headers.append((header, value)) + + def endheaders(self, message_body: typing.Any = None) -> None: # type: ignore[override] + if self._h2_stream is None: + raise ConnectionError("Must call `putrequest` first.") + + with self._h2_conn as conn: + conn.send_headers( + stream_id=self._h2_stream, + headers=self._headers, + end_stream=(message_body is None), + ) + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + self._headers = [] # Reset headers for the next request. + + def send(self, data: typing.Any) -> None: + """Send data to the server. + `data` can be: `str`, `bytes`, an iterable, or file-like objects + that support a .read() method. + """ + if self._h2_stream is None: + raise ConnectionError("Must call `putrequest` first.") + + with self._h2_conn as conn: + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + + if hasattr(data, "read"): # file-like objects + while True: + chunk = data.read(self.blocksize) + if not chunk: + break + if isinstance(chunk, str): + chunk = chunk.encode() # pragma: no cover + conn.send_data(self._h2_stream, chunk, end_stream=False) + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + conn.end_stream(self._h2_stream) + return + + if isinstance(data, str): # str -> bytes + data = data.encode() + + try: + if isinstance(data, bytes): + conn.send_data(self._h2_stream, data, end_stream=True) + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + else: + for chunk in data: + conn.send_data(self._h2_stream, chunk, end_stream=False) + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + conn.end_stream(self._h2_stream) + except TypeError: + raise TypeError( + "`data` should be str, bytes, iterable, or file. got %r" + % type(data) + ) + + def set_tunnel( + self, + host: str, + port: int | None = None, + headers: typing.Mapping[str, str] | None = None, + scheme: str = "http", + ) -> None: + raise NotImplementedError( + "HTTP/2 does not support setting up a tunnel through a proxy" + ) + + def getresponse( # type: ignore[override] + self, + ) -> HTTP2Response: + status = None + data = bytearray() + with self._h2_conn as conn: + end_stream = False + while not end_stream: + # TODO: Arbitrary read value. + if received_data := self.sock.recv(65535): + events = conn.receive_data(received_data) + for event in events: + if isinstance(event, h2.events.ResponseReceived): + headers = HTTPHeaderDict() + for header, value in event.headers: + if header == b":status": + status = int(value.decode()) + else: + headers.add( + header.decode("ascii"), value.decode("ascii") + ) + + elif isinstance(event, h2.events.DataReceived): + data += event.data + conn.acknowledge_received_data( + event.flow_controlled_length, event.stream_id + ) + + elif isinstance(event, h2.events.StreamEnded): + end_stream = True + + if data_to_send := conn.data_to_send(): + self.sock.sendall(data_to_send) + + assert status is not None + return HTTP2Response( + status=status, + headers=headers, + request_url=self._request_url, + data=bytes(data), + ) + + def request( # type: ignore[override] + self, + method: str, + url: str, + body: _TYPE_BODY | None = None, + headers: typing.Mapping[str, str] | None = None, + *, + preload_content: bool = True, + decode_content: bool = True, + enforce_content_length: bool = True, + **kwargs: typing.Any, + ) -> None: + """Send an HTTP/2 request""" + if "chunked" in kwargs: + # TODO this is often present from upstream. + # raise NotImplementedError("`chunked` isn't supported with HTTP/2") + pass + + if self.sock is not None: + self.sock.settimeout(self.timeout) + + self.putrequest(method, url) + + headers = headers or {} + for k, v in headers.items(): + if k.lower() == "transfer-encoding" and v == "chunked": + continue + else: + self.putheader(k, v) + + if b"user-agent" not in dict(self._headers): + self.putheader(b"user-agent", _get_default_user_agent()) + + if body: + self.endheaders(message_body=body) + self.send(body) + else: + self.endheaders() + + def close(self) -> None: + with self._h2_conn as conn: + try: + conn.close_connection() + if data := conn.data_to_send(): + self.sock.sendall(data) + except Exception: + pass + + # Reset all our HTTP/2 connection state. + self._h2_conn = self._new_h2_conn() + self._h2_stream = None + self._headers = [] + + super().close() + + +class HTTP2Response(BaseHTTPResponse): + # TODO: This is a woefully incomplete response object, but works for non-streaming. + def __init__( + self, + status: int, + headers: HTTPHeaderDict, + request_url: str, + data: bytes, + decode_content: bool = False, # TODO: support decoding + ) -> None: + super().__init__( + status=status, + headers=headers, + # Following CPython, we map HTTP versions to major * 10 + minor integers + version=20, + version_string="HTTP/2", + # No reason phrase in HTTP/2 + reason=None, + decode_content=decode_content, + request_url=request_url, + ) + self._data = data + self.length_remaining = 0 + + @property + def data(self) -> bytes: + return self._data + + def get_redirect_location(self) -> None: + return None + + def close(self) -> None: + pass diff --git a/vendor/urllib3/http2/probe.py b/vendor/urllib3/http2/probe.py new file mode 100644 index 0000000..9ea9007 --- /dev/null +++ b/vendor/urllib3/http2/probe.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +import threading + + +class _HTTP2ProbeCache: + __slots__ = ( + "_lock", + "_cache_locks", + "_cache_values", + ) + + def __init__(self) -> None: + self._lock = threading.Lock() + self._cache_locks: dict[tuple[str, int], threading.RLock] = {} + self._cache_values: dict[tuple[str, int], bool | None] = {} + + def acquire_and_get(self, host: str, port: int) -> bool | None: + # By the end of this block we know that + # _cache_[values,locks] is available. + value = None + with self._lock: + key = (host, port) + try: + value = self._cache_values[key] + # If it's a known value we return right away. + if value is not None: + return value + except KeyError: + self._cache_locks[key] = threading.RLock() + self._cache_values[key] = None + + # If the value is unknown, we acquire the lock to signal + # to the requesting thread that the probe is in progress + # or that the current thread needs to return their findings. + key_lock = self._cache_locks[key] + key_lock.acquire() + try: + # If the by the time we get the lock the value has been + # updated we want to return the updated value. + value = self._cache_values[key] + + # In case an exception like KeyboardInterrupt is raised here. + except BaseException as e: # Defensive: + assert not isinstance(e, KeyError) # KeyError shouldn't be possible. + key_lock.release() + raise + + return value + + def set_and_release( + self, host: str, port: int, supports_http2: bool | None + ) -> None: + key = (host, port) + key_lock = self._cache_locks[key] + with key_lock: # Uses an RLock, so can be locked again from same thread. + if supports_http2 is None and self._cache_values[key] is not None: + raise ValueError( + "Cannot reset HTTP/2 support for origin after value has been set." + ) # Defensive: not expected in normal usage + + self._cache_values[key] = supports_http2 + key_lock.release() + + def _values(self) -> dict[tuple[str, int], bool | None]: + """This function is for testing purposes only. Gets the current state of the probe cache""" + with self._lock: + return {k: v for k, v in self._cache_values.items()} + + def _reset(self) -> None: + """This function is for testing purposes only. Reset the cache values""" + with self._lock: + self._cache_locks = {} + self._cache_values = {} + + +_HTTP2_PROBE_CACHE = _HTTP2ProbeCache() + +set_and_release = _HTTP2_PROBE_CACHE.set_and_release +acquire_and_get = _HTTP2_PROBE_CACHE.acquire_and_get +_values = _HTTP2_PROBE_CACHE._values +_reset = _HTTP2_PROBE_CACHE._reset + +__all__ = [ + "set_and_release", + "acquire_and_get", +] diff --git a/vendor/urllib3/poolmanager.py b/vendor/urllib3/poolmanager.py index b8434a3..085d1db 100644 --- a/vendor/urllib3/poolmanager.py +++ b/vendor/urllib3/poolmanager.py @@ -7,7 +7,7 @@ from types import TracebackType from urllib.parse import urljoin -from ._collections import RecentlyUsedContainer +from ._collections import HTTPHeaderDict, RecentlyUsedContainer from ._request_methods import RequestMethods from .connection import ProxyConfig from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme @@ -27,7 +27,7 @@ if typing.TYPE_CHECKING: import ssl - from typing_extensions import Literal + from typing_extensions import Self __all__ = ["PoolManager", "ProxyManager", "proxy_from_url"] @@ -39,6 +39,7 @@ "cert_file", "cert_reqs", "ca_certs", + "ca_cert_data", "ssl_version", "ssl_minimum_version", "ssl_maximum_version", @@ -51,8 +52,6 @@ # http.client.HTTPConnection & http.client.HTTPSConnection in Python 3.7 _DEFAULT_BLOCKSIZE = 16384 -_SelfT = typing.TypeVar("_SelfT") - class PoolKey(typing.NamedTuple): """ @@ -74,6 +73,7 @@ class PoolKey(typing.NamedTuple): key_cert_file: str | None key_cert_reqs: str | None key_ca_certs: str | None + key_ca_cert_data: str | bytes | None key_ssl_version: int | str | None key_ssl_minimum_version: ssl.TLSVersion | None key_ssl_maximum_version: ssl.TLSVersion | None @@ -213,7 +213,7 @@ def __init__( self.pool_classes_by_scheme = pool_classes_by_scheme self.key_fn_by_scheme = key_fn_by_scheme.copy() - def __enter__(self: _SelfT) -> _SelfT: + def __enter__(self) -> Self: return self def __exit__( @@ -221,7 +221,7 @@ def __exit__( exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None, - ) -> Literal[False]: + ) -> typing.Literal[False]: self.clear() # Return False to re-raise any potential exceptions return False @@ -419,6 +419,16 @@ def urlopen( # type: ignore[override] """ u = parse_url(url) + if u.scheme is None: + warnings.warn( + "URLs without a scheme (ie 'https://') are deprecated and will raise an error " + "in a future version of urllib3. To avoid this DeprecationWarning ensure all URLs " + "start with 'https://' or 'http://'. Read more in this issue: " + "https://github.com/urllib3/urllib3/issues/2920", + category=DeprecationWarning, + stacklevel=2, + ) + conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) kw["assert_same_host"] = False @@ -439,9 +449,12 @@ def urlopen( # type: ignore[override] # Support relative URLs for redirecting. redirect_location = urljoin(url, redirect_location) - # RFC 7231, Section 6.4.4 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): @@ -539,7 +552,7 @@ def __init__( proxy_headers: typing.Mapping[str, str] | None = None, proxy_ssl_context: ssl.SSLContext | None = None, use_forwarding_for_https: bool = False, - proxy_assert_hostname: None | str | Literal[False] = None, + proxy_assert_hostname: None | str | typing.Literal[False] = None, proxy_assert_fingerprint: str | None = None, **connection_pool_kw: typing.Any, ) -> None: diff --git a/vendor/urllib3/response.py b/vendor/urllib3/response.py index 1963f85..a0273d6 100644 --- a/vendor/urllib3/response.py +++ b/vendor/urllib3/response.py @@ -14,29 +14,33 @@ from http.client import HTTPResponse as _HttplibHTTPResponse from socket import timeout as SocketTimeout +if typing.TYPE_CHECKING: + from ._base_connection import BaseHTTPConnection + try: try: - import brotlicffi as brotli # type: ignore[import] + import brotlicffi as brotli # type: ignore[import-not-found] except ImportError: - import brotli # type: ignore[import] + import brotli # type: ignore[import-not-found] except ImportError: brotli = None try: - import zstandard as zstd # type: ignore[import] - + import zstandard as zstd +except (AttributeError, ImportError, ValueError): # Defensive: + HAS_ZSTD = False +else: # The package 'zstandard' added the 'eof' property starting # in v0.18.0 which we require to ensure a complete and # valid zstd stream was fed into the ZstdDecoder. # See: https://github.com/urllib3/urllib3/pull/2624 - _zstd_version = _zstd_version = tuple( + _zstd_version = tuple( map(int, re.search(r"^([0-9]+)\.([0-9]+)", zstd.__version__).groups()) # type: ignore[union-attr] ) if _zstd_version < (0, 18): # Defensive: - zstd = None - -except (AttributeError, ImportError, ValueError): # Defensive: - zstd = None + HAS_ZSTD = False + else: + HAS_ZSTD = True from . import util from ._base_connection import _TYPE_BODY @@ -58,8 +62,6 @@ from .util.retry import Retry if typing.TYPE_CHECKING: - from typing_extensions import Literal - from .connectionpool import HTTPConnectionPool log = logging.getLogger(__name__) @@ -160,7 +162,7 @@ def flush(self) -> bytes: return b"" -if zstd is not None: +if HAS_ZSTD: class ZstdDecoder(ContentDecoder): def __init__(self) -> None: @@ -169,13 +171,18 @@ def __init__(self) -> None: def decompress(self, data: bytes) -> bytes: if not data: return b"" - return self._obj.decompress(data) # type: ignore[no-any-return] + data_parts = [self._obj.decompress(data)] + while self._obj.eof and self._obj.unused_data: + unused_data = self._obj.unused_data + self._obj = zstd.ZstdDecompressor().decompressobj() + data_parts.append(self._obj.decompress(unused_data)) + return b"".join(data_parts) def flush(self) -> bytes: - ret = self._obj.flush() + ret = self._obj.flush() # note: this is a no-op if not self._obj.eof: raise DecodeError("Zstandard data is incomplete") - return ret # type: ignore[no-any-return] + return ret class MultiDecoder(ContentDecoder): @@ -203,13 +210,15 @@ def _get_decoder(mode: str) -> ContentDecoder: if "," in mode: return MultiDecoder(mode) - if mode == "gzip": + # According to RFC 9110 section 8.4.1.3, recipients should + # consider x-gzip equivalent to gzip + if mode in ("gzip", "x-gzip"): return GzipDecoder() if brotli is not None and mode == "br": return BrotliDecoder() - if zstd is not None and mode == "zstd": + if HAS_ZSTD and mode == "zstd": return ZstdDecoder() return DeflateDecoder() @@ -273,12 +282,26 @@ def get(self, n: int) -> bytes: return ret.getvalue() + def get_all(self) -> bytes: + buffer = self.buffer + if not buffer: + assert self._size == 0 + return b"" + if len(buffer) == 1: + result = buffer.pop() + else: + ret = io.BytesIO() + ret.writelines(buffer.popleft() for _ in range(len(buffer))) + result = ret.getvalue() + self._size = 0 + return result + class BaseHTTPResponse(io.IOBase): - CONTENT_DECODERS = ["gzip", "deflate"] + CONTENT_DECODERS = ["gzip", "x-gzip", "deflate"] if brotli is not None: CONTENT_DECODERS += ["br"] - if zstd is not None: + if HAS_ZSTD: CONTENT_DECODERS += ["zstd"] REDIRECT_STATUSES = [301, 302, 303, 307, 308] @@ -286,7 +309,7 @@ class BaseHTTPResponse(io.IOBase): if brotli is not None: DECODER_ERROR_CLASSES += (brotli.error,) - if zstd is not None: + if HAS_ZSTD: DECODER_ERROR_CLASSES += (zstd.ZstdError,) def __init__( @@ -295,6 +318,7 @@ def __init__( headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None, status: int, version: int, + version_string: str, reason: str | None, decode_content: bool, request_url: str | None, @@ -306,6 +330,7 @@ def __init__( self.headers = HTTPHeaderDict(headers) # type: ignore[arg-type] self.status = status self.version = version + self.version_string = version_string self.reason = reason self.decode_content = decode_content self._has_decoded_content = False @@ -320,8 +345,9 @@ def __init__( self.chunked = True self._decoder: ContentDecoder | None = None + self.length_remaining: int | None - def get_redirect_location(self) -> str | None | Literal[False]: + def get_redirect_location(self) -> str | None | typing.Literal[False]: """ Should we redirect and where to? @@ -339,13 +365,21 @@ def data(self) -> bytes: def json(self) -> typing.Any: """ - Parses the body of the HTTP response as JSON. + Deserializes the body of the HTTP response as a Python object. + + The body of the HTTP response must be encoded using UTF-8, as per + `RFC 8529 Section 8.1 `_. + + To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to + your custom decoder instead. - To use a custom JSON decoder pass the result of :attr:`HTTPResponse.data` to the decoder. + If the body of the HTTP response is not decodable to UTF-8, a + `UnicodeDecodeError` will be raised. If the body of the HTTP response is not a + valid JSON document, a `json.JSONDecodeError` will be raised. - This method can raise either `UnicodeDecodeError` or `json.JSONDecodeError`. + Read more :ref:`here `. - Read more :ref:`here `. + :returns: The body of the HTTP response as a Python object. """ data = self.data.decode("utf-8") return _json.loads(data) @@ -359,7 +393,7 @@ def url(self, url: str | None) -> None: raise NotImplementedError() @property - def connection(self) -> HTTPConnection | None: + def connection(self) -> BaseHTTPConnection | None: raise NotImplementedError() @property @@ -386,6 +420,13 @@ def read( ) -> bytes: raise NotImplementedError() + def read1( + self, + amt: int | None = None, + decode_content: bool | None = None, + ) -> bytes: + raise NotImplementedError() + def read_chunked( self, amt: int | None = None, @@ -535,6 +576,7 @@ def __init__( headers: typing.Mapping[str, str] | typing.Mapping[bytes, bytes] | None = None, status: int = 0, version: int = 0, + version_string: str = "HTTP/?", reason: str | None = None, preload_content: bool = True, decode_content: bool = True, @@ -552,6 +594,7 @@ def __init__( headers=headers, status=status, version=version, + version_string=version_string, reason=reason, decode_content=decode_content, request_url=request_url, @@ -717,8 +760,18 @@ def _error_catcher(self) -> typing.Generator[None, None, None]: raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] + except IncompleteRead as e: + if ( + e.expected is not None + and e.partial is not None + and e.expected == -e.partial + ): + arg = "Response may not contain content." + else: + arg = f"Connection broken: {e!r}" + raise ProtocolError(arg, e) from e + except (HTTPException, OSError) as e: - # This includes IncompleteRead. raise ProtocolError(f"Connection broken: {e!r}", e) from e # If no exception is thrown, we should avoid cleaning up @@ -745,7 +798,12 @@ def _error_catcher(self) -> typing.Generator[None, None, None]: if self._original_response and self._original_response.isclosed(): self.release_conn() - def _fp_read(self, amt: int | None = None) -> bytes: + def _fp_read( + self, + amt: int | None = None, + *, + read1: bool = False, + ) -> bytes: """ 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 @@ -762,13 +820,15 @@ def _fp_read(self, amt: int | None = None) -> bytes: 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) + (amt and amt > c_int_max) + or ( + amt is None + and 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)) - ): + ) and (util.IS_PYOPENSSL or sys.version_info < (3, 10)): + if read1: + return self._fp.read1(c_int_max) buffer = io.BytesIO() # Besides `max_chunk_amt` being a maximum chunk size, it # affects memory overhead of reading a response by this @@ -789,6 +849,8 @@ def _fp_read(self, amt: int | None = None) -> bytes: buffer.write(data) del data # to reduce peak memory usage by `max_chunk_amt`. return buffer.getvalue() + elif read1: + return self._fp.read1(amt) if amt is not None else self._fp.read1() else: # StringIO doesn't like amt=None return self._fp.read(amt) if amt is not None else self._fp.read() @@ -796,6 +858,8 @@ def _fp_read(self, amt: int | None = None) -> bytes: def _raw_read( self, amt: int | None = None, + *, + read1: bool = False, ) -> bytes: """ Reads `amt` of bytes from the socket. @@ -806,7 +870,7 @@ def _raw_read( fp_closed = getattr(self._fp, "closed", False) with self._error_catcher(): - data = self._fp_read(amt) if not fp_closed else b"" + data = self._fp_read(amt, read1=read1) if not fp_closed else b"" if amt is not None and amt != 0 and not data: # Platform-specific: Buggy versions of Python. # Close the connection when no data is returned @@ -828,6 +892,14 @@ def _raw_read( # raised during streaming, so all calls with incorrect # Content-Length are caught. raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + elif read1 and ( + (amt != 0 and not data) or self.length_remaining == len(data) + ): + # All data has been read, but `self._fp.read1` in + # CPython 3.12 and older doesn't always close + # `http.client.HTTPResponse`, so we close it here. + # See https://github.com/python/cpython/issues/113199 + self._fp.close() if data: self._fp_bytes_read += len(data) @@ -865,7 +937,10 @@ def read( if decode_content is None: decode_content = self.decode_content - if amt is not None: + if amt and amt < 0: + # Negative numbers and `None` should be treated the same. + amt = None + elif amt is not None: cache_content = False if len(self._decoded_buffer) >= amt: @@ -873,11 +948,7 @@ def read( data = self._raw_read(amt) - flush_decoder = False - if amt is None: - flush_decoder = True - elif amt != 0 and not data: - flush_decoder = True + flush_decoder = amt is None or (amt != 0 and not data) if not data and len(self._decoded_buffer) == 0: return data @@ -910,6 +981,60 @@ def read( return data + def read1( + self, + amt: int | None = None, + decode_content: bool | None = None, + ) -> bytes: + """ + Similar to ``http.client.HTTPResponse.read1`` and documented + in :meth:`io.BufferedReader.read1`, but with an additional parameter: + ``decode_content``. + + :param amt: + How much of the content to read. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if decode_content is None: + decode_content = self.decode_content + if amt and amt < 0: + # Negative numbers and `None` should be treated the same. + amt = None + # try and respond without going to the network + if self._has_decoded_content: + if not decode_content: + raise RuntimeError( + "Calling read1(decode_content=False) is not supported after " + "read1(decode_content=True) was called." + ) + if len(self._decoded_buffer) > 0: + if amt is None: + return self._decoded_buffer.get_all() + return self._decoded_buffer.get(amt) + if amt == 0: + return b"" + + # FIXME, this method's type doesn't say returning None is possible + data = self._raw_read(amt, read1=True) + if not decode_content or data is None: + return data + + self._init_decoder() + while True: + flush_decoder = not data + decoded_data = self._decode(data, decode_content, flush_decoder) + self._decoded_buffer.put(decoded_data) + if decoded_data or flush_decoder: + break + data = self._raw_read(8192, read1=True) + + if amt is None: + return self._decoded_buffer.get_all() + return self._decoded_buffer.get(amt) + def stream( self, amt: int | None = 2**16, decode_content: bool | None = None ) -> typing.Generator[bytes, None, None]: @@ -1002,9 +1127,13 @@ def _update_chunk_length(self) -> None: try: self.chunk_left = int(line, 16) except ValueError: - # Invalid chunked protocol response, abort. self.close() - raise InvalidChunkLength(self, line) from None + if line: + # Invalid chunked protocol response, abort. + raise InvalidChunkLength(self, line) from None + else: + # Truncated at start of next chunk + raise ProtocolError("Response ended prematurely") from None def _handle_chunk(self, amt: int | None) -> bytes: returned_chunk = None @@ -1068,6 +1197,11 @@ def read_chunked( if self._fp.fp is None: # type: ignore[union-attr] return None + if amt and amt < 0: + # Negative numbers and `None` should be treated the same, + # but httplib handles only `None` correctly. + amt = None + while True: self._update_chunk_length() if self.chunk_left == 0: diff --git a/vendor/urllib3/util/__init__.py b/vendor/urllib3/util/__init__.py index ff56c55..5341260 100644 --- a/vendor/urllib3/util/__init__.py +++ b/vendor/urllib3/util/__init__.py @@ -8,7 +8,6 @@ from .ssl_ import ( ALPN_PROTOCOLS, IS_PYOPENSSL, - IS_SECURETRANSPORT, SSLContext, assert_fingerprint, create_urllib3_context, @@ -22,7 +21,6 @@ __all__ = ( "IS_PYOPENSSL", - "IS_SECURETRANSPORT", "SSLContext", "ALPN_PROTOCOLS", "Retry", diff --git a/vendor/urllib3/util/connection.py b/vendor/urllib3/util/connection.py index 5c7da73..89bd189 100644 --- a/vendor/urllib3/util/connection.py +++ b/vendor/urllib3/util/connection.py @@ -6,7 +6,7 @@ from ..exceptions import LocationParseError from .timeout import _DEFAULT_TIMEOUT, _TYPE_TIMEOUT -_TYPE_SOCKET_OPTIONS = typing.Sequence[typing.Tuple[int, int, typing.Union[int, bytes]]] +_TYPE_SOCKET_OPTIONS = typing.List[typing.Tuple[int, int, typing.Union[int, bytes]]] if typing.TYPE_CHECKING: from .._base_connection import BaseHTTPConnection diff --git a/vendor/urllib3/util/request.py b/vendor/urllib3/util/request.py index def099d..82454a0 100644 --- a/vendor/urllib3/util/request.py +++ b/vendor/urllib3/util/request.py @@ -9,7 +9,7 @@ from .util import to_bytes if typing.TYPE_CHECKING: - from typing_extensions import Final + from typing import Final # Pass as a value within ``headers`` to skip # emitting some HTTP headers that are added automatically. @@ -21,15 +21,15 @@ ACCEPT_ENCODING = "gzip,deflate" try: try: - import brotlicffi as _unused_module_brotli # type: ignore[import] # noqa: F401 + import brotlicffi as _unused_module_brotli # type: ignore[import-not-found] # noqa: F401 except ImportError: - import brotli as _unused_module_brotli # type: ignore[import] # noqa: F401 + import brotli as _unused_module_brotli # type: ignore[import-not-found] # noqa: F401 except ImportError: pass else: ACCEPT_ENCODING += ",br" try: - import zstandard as _unused_module_zstd # type: ignore[import] # noqa: F401 + import zstandard as _unused_module_zstd # noqa: F401 except ImportError: pass else: @@ -223,11 +223,11 @@ def chunk_readable() -> typing.Iterable[bytes]: nonlocal body, blocksize encode = isinstance(body, io.TextIOBase) while True: - datablock = body.read(blocksize) # type: ignore[union-attr] + datablock = body.read(blocksize) if not datablock: break if encode: - datablock = datablock.encode("iso-8859-1") + datablock = datablock.encode("utf-8") yield datablock chunks = chunk_readable() diff --git a/vendor/urllib3/util/retry.py b/vendor/urllib3/util/retry.py index 691f62c..0456cce 100644 --- a/vendor/urllib3/util/retry.py +++ b/vendor/urllib3/util/retry.py @@ -21,6 +21,8 @@ from .util import reraise if typing.TYPE_CHECKING: + from typing_extensions import Self + from ..connectionpool import ConnectionPool from ..response import BaseHTTPResponse @@ -143,7 +145,7 @@ class Retry: (most errors are resolved immediately by a second try without a delay). urllib3 will sleep for:: - {backoff factor} * (2 ** ({number of total retries} - 1)) + {backoff factor} * (2 ** ({number of previous retries})) seconds. If `backoff_jitter` is non-zero, this sleep is extended by:: @@ -187,7 +189,9 @@ class Retry: RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) #: Default headers to be used for ``remove_headers_on_redirect`` - DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"]) + DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset( + ["Cookie", "Authorization", "Proxy-Authorization"] + ) #: Default maximum backoff time. DEFAULT_BACKOFF_MAX = 120 @@ -240,7 +244,7 @@ def __init__( ) self.backoff_jitter = backoff_jitter - def new(self, **kw: typing.Any) -> Retry: + def new(self, **kw: typing.Any) -> Self: params = dict( total=self.total, connect=self.connect, @@ -429,7 +433,7 @@ def increment( error: Exception | None = None, _pool: ConnectionPool | None = None, _stacktrace: TracebackType | None = None, - ) -> Retry: + ) -> Self: """Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not diff --git a/vendor/urllib3/util/ssl_.py b/vendor/urllib3/util/ssl_.py index 5e24810..5e93be9 100644 --- a/vendor/urllib3/util/ssl_.py +++ b/vendor/urllib3/util/ssl_.py @@ -1,5 +1,6 @@ from __future__ import annotations +import hashlib import hmac import os import socket @@ -7,7 +8,6 @@ import typing import warnings from binascii import unhexlify -from hashlib import md5, sha1, sha256 from ..exceptions import ProxySchemeUnsupported, SSLError from .url import _BRACELESS_IPV6_ADDRZ_RE, _IPV4_RE @@ -16,64 +16,72 @@ SSLTransport = None HAS_NEVER_CHECK_COMMON_NAME = False IS_PYOPENSSL = False -IS_SECURETRANSPORT = False ALPN_PROTOCOLS = ["http/1.1"] _TYPE_VERSION_INFO = typing.Tuple[int, int, int, str, int] # Maps the length of a digest to a possible hash function producing this digest -HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256} +HASHFUNC_MAP = { + length: getattr(hashlib, algorithm, None) + for length, algorithm in ((32, "md5"), (40, "sha1"), (64, "sha256")) +} def _is_bpo_43522_fixed( - implementation_name: str, version_info: _TYPE_VERSION_INFO + implementation_name: str, + version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool: - """Return True for CPython 3.8.9+, 3.9.3+ or 3.10+ where setting - SSLContext.hostname_checks_common_name to False works. - - PyPy 7.3.7 doesn't work as it doesn't ship with OpenSSL 1.1.1l+ - so we're waiting for a version of PyPy that works before - allowing this function to return 'True'. + """Return True for CPython 3.8.9+, 3.9.3+ or 3.10+ and PyPy 7.3.8+ where + setting SSLContext.hostname_checks_common_name to False works. Outside of CPython and PyPy we don't know which implementations work or not so we conservatively use our hostname matching as we know that works on all implementations. https://github.com/urllib3/urllib3/issues/2192#issuecomment-821832963 - https://foss.heptapod.net/pypy/pypy/-/issues/3539# + https://foss.heptapod.net/pypy/pypy/-/issues/3539 """ - if implementation_name != "cpython": + if implementation_name == "pypy": + # https://foss.heptapod.net/pypy/pypy/-/issues/3129 + return pypy_version_info >= (7, 3, 8) # type: ignore[operator] + elif implementation_name == "cpython": + major_minor = version_info[:2] + micro = version_info[2] + return ( + (major_minor == (3, 8) and micro >= 9) + or (major_minor == (3, 9) and micro >= 3) + or major_minor >= (3, 10) + ) + else: # Defensive: return False - major_minor = version_info[:2] - micro = version_info[2] - return ( - (major_minor == (3, 8) and micro >= 9) - or (major_minor == (3, 9) and micro >= 3) - or major_minor >= (3, 10) - ) - def _is_has_never_check_common_name_reliable( + openssl_version: str, openssl_version_number: int, implementation_name: str, version_info: _TYPE_VERSION_INFO, + pypy_version_info: _TYPE_VERSION_INFO | None, ) -> bool: + # As of May 2023, all released versions of LibreSSL fail to reject certificates with + # only common names, see https://github.com/urllib3/urllib3/pull/3024 + is_openssl = openssl_version.startswith("OpenSSL ") # Before fixing OpenSSL issue #14579, the SSL_new() API was not copying hostflags # like X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, which tripped up CPython. # https://github.com/openssl/openssl/issues/14579 # This was released in OpenSSL 1.1.1l+ (>=0x101010cf) is_openssl_issue_14579_fixed = openssl_version_number >= 0x101010CF - return is_openssl_issue_14579_fixed or _is_bpo_43522_fixed( - implementation_name, version_info + return is_openssl and ( + is_openssl_issue_14579_fixed + or _is_bpo_43522_fixed(implementation_name, version_info, pypy_version_info) ) if typing.TYPE_CHECKING: from ssl import VerifyMode - - from typing_extensions import Literal, TypedDict + from typing import TypedDict from .ssltransport import SSLTransport as SSLTransportType @@ -93,6 +101,7 @@ class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False): HAS_NEVER_CHECK_COMMON_NAME, OP_NO_COMPRESSION, OP_NO_TICKET, + OPENSSL_VERSION, OPENSSL_VERSION_NUMBER, PROTOCOL_TLS, PROTOCOL_TLS_CLIENT, @@ -107,9 +116,11 @@ class _TYPE_PEER_CERT_RET_DICT(TypedDict, total=False): # Setting SSLContext.hostname_checks_common_name = False didn't work before CPython # 3.8.9, 3.9.3, and 3.10 (but OK on PyPy) or OpenSSL 1.1.1l+ if HAS_NEVER_CHECK_COMMON_NAME and not _is_has_never_check_common_name_reliable( + OPENSSL_VERSION, OPENSSL_VERSION_NUMBER, sys.implementation.name, sys.version_info, + sys.pypy_version_info if sys.implementation.name == "pypy" else None, # type: ignore[attr-defined] ): HAS_NEVER_CHECK_COMMON_NAME = False @@ -151,9 +162,13 @@ def assert_fingerprint(cert: bytes | None, fingerprint: str) -> None: fingerprint = fingerprint.replace(":", "").lower() digest_length = len(fingerprint) - hashfunc = HASHFUNC_MAP.get(digest_length) - if not hashfunc: + if digest_length not in HASHFUNC_MAP: raise SSLError(f"Fingerprint of invalid length: {fingerprint}") + hashfunc = HASHFUNC_MAP.get(digest_length) + if hashfunc is None: + raise SSLError( + f"Hash function implementation unavailable for fingerprint length: {digest_length}" + ) # We need encode() here for py32; works on py2 and p33. fingerprint_bytes = unhexlify(fingerprint.encode()) @@ -311,13 +326,9 @@ def create_urllib3_context( # 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: + # The attribute is None for OpenSSL <= 1.1.0 or does not exist when using + # an SSLContext created by pyOpenSSL. + if getattr(context, "post_handshake_auth", None) is not None: context.post_handshake_auth = True # The order of the below lines setting verify_mode and check_hostname @@ -334,7 +345,7 @@ def create_urllib3_context( try: context.hostname_checks_common_name = False - except AttributeError: + except AttributeError: # Defensive: for CPython < 3.8.9 and 3.9.3; for PyPy < 7.3.8 pass # Enable logging of TLS session keys via defacto standard environment variable @@ -361,7 +372,7 @@ def ssl_wrap_socket( ca_cert_dir: str | None = ..., key_password: str | None = ..., ca_cert_data: None | str | bytes = ..., - tls_in_tls: Literal[False] = ..., + tls_in_tls: typing.Literal[False] = ..., ) -> ssl.SSLSocket: ... @@ -401,8 +412,10 @@ def ssl_wrap_socket( tls_in_tls: bool = False, ) -> ssl.SSLSocket | SSLTransportType: """ - 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`. + All arguments except for server_hostname, ssl_context, tls_in_tls, ca_cert_data and + ca_cert_dir have the same meaning as they do when using + :func:`ssl.create_default_context`, :meth:`ssl.SSLContext.load_cert_chain`, + :meth:`ssl.SSLContext.set_ciphers` and :meth:`ssl.SSLContext.wrap_socket`. :param server_hostname: When SNI is supported, the expected hostname of the certificate @@ -451,10 +464,7 @@ def ssl_wrap_socket( else: context.load_cert_chain(certfile, keyfile, key_password) - try: - context.set_alpn_protocols(ALPN_PROTOCOLS) - except NotImplementedError: # Defensive: in CI, we always have set_alpn_protocols - pass + context.set_alpn_protocols(ALPN_PROTOCOLS) ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname) return ssl_sock diff --git a/vendor/urllib3/util/ssltransport.py b/vendor/urllib3/util/ssltransport.py index 5ec8647..d69ccb3 100644 --- a/vendor/urllib3/util/ssltransport.py +++ b/vendor/urllib3/util/ssltransport.py @@ -8,12 +8,11 @@ from ..exceptions import ProxySchemeUnsupported if typing.TYPE_CHECKING: - from typing_extensions import Literal + from typing_extensions import Self from .ssl_ import _TYPE_PEER_CERT_RET, _TYPE_PEER_CERT_RET_DICT -_SelfT = typing.TypeVar("_SelfT", bound="SSLTransport") _WriteBuffer = typing.Union[bytearray, memoryview] _ReturnValue = typing.TypeVar("_ReturnValue") @@ -70,7 +69,7 @@ def __init__( # Perform initial handshake. self._ssl_io_loop(self.sslobj.do_handshake) - def __enter__(self: _SelfT) -> _SelfT: + def __enter__(self) -> Self: return self def __exit__(self, *_: typing.Any) -> None: @@ -174,12 +173,12 @@ def close(self) -> None: @typing.overload def getpeercert( - self, binary_form: Literal[False] = ... + self, binary_form: typing.Literal[False] = ... ) -> _TYPE_PEER_CERT_RET_DICT | None: ... @typing.overload - def getpeercert(self, binary_form: Literal[True]) -> bytes | None: + def getpeercert(self, binary_form: typing.Literal[True]) -> bytes | None: ... def getpeercert(self, binary_form: bool = False) -> _TYPE_PEER_CERT_RET: @@ -194,9 +193,6 @@ def cipher(self) -> tuple[str, str, int] | None: def selected_alpn_protocol(self) -> str | None: return self.sslobj.selected_alpn_protocol() - def selected_npn_protocol(self) -> str | None: - return self.sslobj.selected_npn_protocol() - def shared_ciphers(self) -> list[tuple[str, str, int]] | None: return self.sslobj.shared_ciphers() diff --git a/vendor/urllib3/util/timeout.py b/vendor/urllib3/util/timeout.py index ec090f6..4bb1be1 100644 --- a/vendor/urllib3/util/timeout.py +++ b/vendor/urllib3/util/timeout.py @@ -8,7 +8,7 @@ from ..exceptions import TimeoutStateError if typing.TYPE_CHECKING: - from typing_extensions import Final + from typing import Final class _TYPE_DEFAULT(Enum): @@ -101,10 +101,6 @@ class Timeout: 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 diff --git a/vendor/yaml/__init__.py b/vendor/yaml/__init__.py index 465041d..2ec4f20 100644 --- a/vendor/yaml/__init__.py +++ b/vendor/yaml/__init__.py @@ -8,7 +8,7 @@ from .loader import * from .dumper import * -__version__ = '6.0' +__version__ = '6.0.2' try: from .cyaml import * __with_libyaml__ = True From 1653ede53224031d7aef43e26dfec6239a1f275e Mon Sep 17 00:00:00 2001 From: Mathew Payne <2772944+GeekMasher@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:57:25 +0000 Subject: [PATCH 3/3] fix(vendor): Patch semver --- vendor/semantic_version/__init__.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/vendor/semantic_version/__init__.py b/vendor/semantic_version/__init__.py index 1528bda..4f4787a 100644 --- a/vendor/semantic_version/__init__.py +++ b/vendor/semantic_version/__init__.py @@ -7,12 +7,4 @@ __author__ = "Raphaƫl Barrois " -try: - # Python 3.8+ - from importlib.metadata import version - - __version__ = version("semantic_version") -except ImportError: - import pkg_resources - - __version__ = pkg_resources.get_distribution("semantic_version").version +__version__ = "2.10.0"