From 1aab041f7ea6aff32b59a2e5f5ea2c72ec05e9fe Mon Sep 17 00:00:00 2001 From: Juan Pablo Duque Date: Thu, 26 Oct 2023 14:07:13 -0500 Subject: [PATCH] Initial commit for currency coverter --- .../Jinja2-3.1.2.dist-info/INSTALLER | 1 + .../Jinja2-3.1.2.dist-info/LICENSE.rst | 28 + .../Jinja2-3.1.2.dist-info/METADATA | 113 + .../Jinja2-3.1.2.dist-info/RECORD | 58 + .../Jinja2-3.1.2.dist-info/WHEEL | 5 + .../Jinja2-3.1.2.dist-info/entry_points.txt | 2 + .../Jinja2-3.1.2.dist-info/top_level.txt | 1 + .../MarkupSafe-2.1.3.dist-info/INSTALLER | 1 + .../MarkupSafe-2.1.3.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.3.dist-info/METADATA | 93 + .../MarkupSafe-2.1.3.dist-info/RECORD | 14 + .../MarkupSafe-2.1.3.dist-info/WHEEL | 5 + .../MarkupSafe-2.1.3.dist-info/top_level.txt | 1 + .../site-packages/_distutils_hack/__init__.py | 222 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7581 bytes .../__pycache__/override.cpython-310.pyc | Bin 0 -> 228 bytes .../site-packages/_distutils_hack/override.py | 1 + .../blinker-1.6.3.dist-info/INSTALLER | 1 + .../blinker-1.6.3.dist-info/LICENSE.rst | 20 + .../blinker-1.6.3.dist-info/METADATA | 62 + .../blinker-1.6.3.dist-info/RECORD | 14 + .../blinker-1.6.3.dist-info/WHEEL | 4 + .venv/Lib/site-packages/blinker/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 492 bytes .../__pycache__/_saferef.cpython-310.pyc | Bin 0 -> 7179 bytes .../__pycache__/_utilities.cpython-310.pyc | Bin 0 -> 4231 bytes .../blinker/__pycache__/base.cpython-310.pyc | Bin 0 -> 17411 bytes .venv/Lib/site-packages/blinker/_saferef.py | 230 + .venv/Lib/site-packages/blinker/_utilities.py | 142 + .venv/Lib/site-packages/blinker/base.py | 548 ++ .venv/Lib/site-packages/blinker/py.typed | 0 .../certifi-2023.7.22.dist-info/INSTALLER | 1 + .../certifi-2023.7.22.dist-info/LICENSE | 21 + .../certifi-2023.7.22.dist-info/METADATA | 69 + .../certifi-2023.7.22.dist-info/RECORD | 14 + .../certifi-2023.7.22.dist-info/WHEEL | 5 + .../certifi-2023.7.22.dist-info/top_level.txt | 1 + .venv/Lib/site-packages/certifi/__init__.py | 4 + .venv/Lib/site-packages/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 282 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 420 bytes .../certifi/__pycache__/core.cpython-310.pyc | Bin 0 -> 1890 bytes .venv/Lib/site-packages/certifi/cacert.pem | 4635 +++++++++ .venv/Lib/site-packages/certifi/core.py | 108 + .venv/Lib/site-packages/certifi/py.typed | 0 .../INSTALLER | 1 + .../LICENSE | 21 + .../METADATA | 668 ++ .../charset_normalizer-3.3.0.dist-info/RECORD | 35 + .../charset_normalizer-3.3.0.dist-info/WHEEL | 5 + .../entry_points.txt | 2 + .../top_level.txt | 1 + .../charset_normalizer/__init__.py | 46 + .../charset_normalizer/__main__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1578 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 262 bytes .../__pycache__/api.cpython-310.pyc | Bin 0 -> 11409 bytes .../__pycache__/cd.cpython-310.pyc | Bin 0 -> 9674 bytes .../__pycache__/constant.cpython-310.pyc | Bin 0 -> 30444 bytes .../__pycache__/legacy.cpython-310.pyc | Bin 0 -> 1844 bytes .../__pycache__/md.cpython-310.pyc | Bin 0 -> 14657 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 11494 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 8487 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 264 bytes .../site-packages/charset_normalizer/api.py | 626 ++ .../site-packages/charset_normalizer/cd.py | 395 + .../charset_normalizer/cli/__init__.py | 6 + .../charset_normalizer/cli/__main__.py | 296 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 265 bytes .../cli/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 6464 bytes .../charset_normalizer/constant.py | 1995 ++++ .../charset_normalizer/legacy.py | 54 + .../charset_normalizer/md.cp310-win_amd64.pyd | Bin 0 -> 10752 bytes .../site-packages/charset_normalizer/md.py | 581 ++ .../md__mypyc.cp310-win_amd64.pyd | Bin 0 -> 113664 bytes .../charset_normalizer/models.py | 337 + .../site-packages/charset_normalizer/py.typed | 0 .../site-packages/charset_normalizer/utils.py | 399 + .../charset_normalizer/version.py | 6 + .../click-8.1.7.dist-info/INSTALLER | 1 + .../click-8.1.7.dist-info/LICENSE.rst | 28 + .../click-8.1.7.dist-info/METADATA | 103 + .../click-8.1.7.dist-info/RECORD | 39 + .../site-packages/click-8.1.7.dist-info/WHEEL | 5 + .../click-8.1.7.dist-info/top_level.txt | 1 + .venv/Lib/site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2611 bytes .../click/__pycache__/_compat.cpython-310.pyc | Bin 0 -> 15679 bytes .../__pycache__/_termui_impl.cpython-310.pyc | Bin 0 -> 16309 bytes .../__pycache__/_textwrap.cpython-310.pyc | Bin 0 -> 1545 bytes .../__pycache__/_winconsole.cpython-310.pyc | Bin 0 -> 7663 bytes .../click/__pycache__/core.cpython-310.pyc | Bin 0 -> 91187 bytes .../__pycache__/decorators.cpython-310.pyc | Bin 0 -> 17209 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10257 bytes .../__pycache__/formatting.cpython-310.pyc | Bin 0 -> 9458 bytes .../click/__pycache__/globals.cpython-310.pyc | Bin 0 -> 2430 bytes .../click/__pycache__/parser.cpython-310.pyc | Bin 0 -> 13675 bytes .../shell_completion.cpython-310.pyc | Bin 0 -> 16846 bytes .../click/__pycache__/termui.cpython-310.pyc | Bin 0 -> 26131 bytes .../click/__pycache__/testing.cpython-310.pyc | Bin 0 -> 15204 bytes .../click/__pycache__/types.cpython-310.pyc | Bin 0 -> 33688 bytes .../click/__pycache__/utils.cpython-310.pyc | Bin 0 -> 18848 bytes .venv/Lib/site-packages/click/_compat.py | 623 ++ .venv/Lib/site-packages/click/_termui_impl.py | 739 ++ .venv/Lib/site-packages/click/_textwrap.py | 49 + .venv/Lib/site-packages/click/_winconsole.py | 279 + .venv/Lib/site-packages/click/core.py | 3042 ++++++ .venv/Lib/site-packages/click/decorators.py | 561 ++ .venv/Lib/site-packages/click/exceptions.py | 288 + .venv/Lib/site-packages/click/formatting.py | 301 + .venv/Lib/site-packages/click/globals.py | 68 + .venv/Lib/site-packages/click/parser.py | 529 + .venv/Lib/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .venv/Lib/site-packages/click/termui.py | 784 ++ .venv/Lib/site-packages/click/testing.py | 479 + .venv/Lib/site-packages/click/types.py | 1089 +++ .venv/Lib/site-packages/click/utils.py | 624 ++ .../colorama-0.4.6.dist-info/INSTALLER | 1 + .../colorama-0.4.6.dist-info/METADATA | 441 + .../colorama-0.4.6.dist-info/RECORD | 31 + .../colorama-0.4.6.dist-info/WHEEL | 5 + .../licenses/LICENSE.txt | 27 + .venv/Lib/site-packages/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 456 bytes .../colorama/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 2982 bytes .../__pycache__/ansitowin32.cpython-310.pyc | Bin 0 -> 8494 bytes .../__pycache__/initialise.cpython-310.pyc | Bin 0 -> 2239 bytes .../__pycache__/win32.cpython-310.pyc | Bin 0 -> 4449 bytes .../__pycache__/winterm.cpython-310.pyc | Bin 0 -> 5145 bytes .venv/Lib/site-packages/colorama/ansi.py | 102 + .../Lib/site-packages/colorama/ansitowin32.py | 277 + .../Lib/site-packages/colorama/initialise.py | 121 + .../site-packages/colorama/tests/__init__.py | 1 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 176 bytes .../__pycache__/ansi_test.cpython-310.pyc | Bin 0 -> 2268 bytes .../ansitowin32_test.cpython-310.pyc | Bin 0 -> 11579 bytes .../initialise_test.cpython-310.pyc | Bin 0 -> 6876 bytes .../__pycache__/isatty_test.cpython-310.pyc | Bin 0 -> 2667 bytes .../tests/__pycache__/utils.cpython-310.pyc | Bin 0 -> 1576 bytes .../__pycache__/winterm_test.cpython-310.pyc | Bin 0 -> 3169 bytes .../site-packages/colorama/tests/ansi_test.py | 76 + .../colorama/tests/ansitowin32_test.py | 294 + .../colorama/tests/initialise_test.py | 189 + .../colorama/tests/isatty_test.py | 57 + .../Lib/site-packages/colorama/tests/utils.py | 49 + .../colorama/tests/winterm_test.py | 131 + .venv/Lib/site-packages/colorama/win32.py | 180 + .venv/Lib/site-packages/colorama/winterm.py | 195 + .../site-packages/distutils-precedence.pth | 1 + .../flask-3.0.0.dist-info/INSTALLER | 1 + .../flask-3.0.0.dist-info/LICENSE.rst | 28 + .../flask-3.0.0.dist-info/METADATA | 116 + .../flask-3.0.0.dist-info/RECORD | 58 + .../flask-3.0.0.dist-info/REQUESTED | 0 .../site-packages/flask-3.0.0.dist-info/WHEEL | 4 + .../flask-3.0.0.dist-info/entry_points.txt | 3 + .venv/Lib/site-packages/flask/__init__.py | 60 + .venv/Lib/site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2282 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 207 bytes .../flask/__pycache__/app.cpython-310.pyc | Bin 0 -> 49686 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 3418 bytes .../flask/__pycache__/cli.cpython-310.pyc | Bin 0 -> 27019 bytes .../flask/__pycache__/config.cpython-310.pyc | Bin 0 -> 12864 bytes .../flask/__pycache__/ctx.cpython-310.pyc | Bin 0 -> 14674 bytes .../__pycache__/debughelpers.cpython-310.pyc | Bin 0 -> 6005 bytes .../flask/__pycache__/globals.cpython-310.pyc | Bin 0 -> 1575 bytes .../flask/__pycache__/helpers.cpython-310.pyc | Bin 0 -> 21571 bytes .../flask/__pycache__/logging.cpython-310.pyc | Bin 0 -> 2538 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 13251 bytes .../flask/__pycache__/signals.cpython-310.pyc | Bin 0 -> 805 bytes .../__pycache__/templating.cpython-310.pyc | Bin 0 -> 7082 bytes .../flask/__pycache__/testing.cpython-310.pyc | Bin 0 -> 9691 bytes .../flask/__pycache__/typing.cpython-310.pyc | Bin 0 -> 1807 bytes .../flask/__pycache__/views.cpython-310.pyc | Bin 0 -> 5461 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 5193 bytes .venv/Lib/site-packages/flask/app.py | 1478 +++ .venv/Lib/site-packages/flask/blueprints.py | 91 + .venv/Lib/site-packages/flask/cli.py | 1068 ++ .venv/Lib/site-packages/flask/config.py | 347 + .venv/Lib/site-packages/flask/ctx.py | 440 + .venv/Lib/site-packages/flask/debughelpers.py | 160 + .venv/Lib/site-packages/flask/globals.py | 51 + .venv/Lib/site-packages/flask/helpers.py | 623 ++ .../Lib/site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5989 bytes .../json/__pycache__/provider.cpython-310.pyc | Bin 0 -> 7669 bytes .../json/__pycache__/tag.cpython-310.pyc | Bin 0 -> 11096 bytes .../Lib/site-packages/flask/json/provider.py | 216 + .venv/Lib/site-packages/flask/json/tag.py | 314 + .venv/Lib/site-packages/flask/logging.py | 76 + .venv/Lib/site-packages/flask/py.typed | 0 .../Lib/site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-310.pyc | Bin 0 -> 28534 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 22754 bytes .../__pycache__/scaffold.cpython-310.pyc | Bin 0 -> 23924 bytes .venv/Lib/site-packages/flask/sansio/app.py | 964 ++ .../site-packages/flask/sansio/blueprints.py | 626 ++ .../site-packages/flask/sansio/scaffold.py | 802 ++ .venv/Lib/site-packages/flask/sessions.py | 367 + .venv/Lib/site-packages/flask/signals.py | 17 + .venv/Lib/site-packages/flask/templating.py | 221 + .venv/Lib/site-packages/flask/testing.py | 295 + .venv/Lib/site-packages/flask/typing.py | 88 + .venv/Lib/site-packages/flask/views.py | 190 + .venv/Lib/site-packages/flask/wrappers.py | 173 + .../idna-3.4.dist-info/INSTALLER | 1 + .../idna-3.4.dist-info/LICENSE.md | 29 + .../site-packages/idna-3.4.dist-info/METADATA | 242 + .../site-packages/idna-3.4.dist-info/RECORD | 22 + .../site-packages/idna-3.4.dist-info/WHEEL | 4 + .venv/Lib/site-packages/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 825 bytes .../idna/__pycache__/codec.cpython-310.pyc | Bin 0 -> 2796 bytes .../idna/__pycache__/compat.cpython-310.pyc | Bin 0 -> 725 bytes .../idna/__pycache__/core.cpython-310.pyc | Bin 0 -> 9682 bytes .../idna/__pycache__/idnadata.cpython-310.pyc | Bin 0 -> 38361 bytes .../__pycache__/intranges.cpython-310.pyc | Bin 0 -> 1962 bytes .../__pycache__/package_data.cpython-310.pyc | Bin 0 -> 189 bytes .../__pycache__/uts46data.cpython-310.pyc | Bin 0 -> 152376 bytes .venv/Lib/site-packages/idna/codec.py | 112 + .venv/Lib/site-packages/idna/compat.py | 13 + .venv/Lib/site-packages/idna/core.py | 400 + .venv/Lib/site-packages/idna/idnadata.py | 2151 +++++ .venv/Lib/site-packages/idna/intranges.py | 54 + .venv/Lib/site-packages/idna/package_data.py | 2 + .venv/Lib/site-packages/idna/py.typed | 0 .venv/Lib/site-packages/idna/uts46data.py | 8600 +++++++++++++++++ .../itsdangerous-2.1.2.dist-info/INSTALLER | 1 + .../itsdangerous-2.1.2.dist-info/LICENSE.rst | 28 + .../itsdangerous-2.1.2.dist-info/METADATA | 97 + .../itsdangerous-2.1.2.dist-info/RECORD | 23 + .../itsdangerous-2.1.2.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 860 bytes .../__pycache__/_json.cpython-310.pyc | Bin 0 -> 915 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1864 bytes .../__pycache__/exc.cpython-310.pyc | Bin 0 -> 3403 bytes .../__pycache__/serializer.cpython-310.pyc | Bin 0 -> 9687 bytes .../__pycache__/signer.cpython-310.pyc | Bin 0 -> 8455 bytes .../__pycache__/timed.cpython-310.pyc | Bin 0 -> 6469 bytes .../__pycache__/url_safe.cpython-310.pyc | Bin 0 -> 2688 bytes .venv/Lib/site-packages/itsdangerous/_json.py | 16 + .../site-packages/itsdangerous/encoding.py | 54 + .venv/Lib/site-packages/itsdangerous/exc.py | 107 + .venv/Lib/site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 295 + .../Lib/site-packages/itsdangerous/signer.py | 257 + .venv/Lib/site-packages/itsdangerous/timed.py | 234 + .../site-packages/itsdangerous/url_safe.py | 80 + .venv/Lib/site-packages/jinja2/__init__.py | 37 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1596 bytes .../__pycache__/_identifier.cpython-310.pyc | Bin 0 -> 2071 bytes .../__pycache__/async_utils.cpython-310.pyc | Bin 0 -> 2708 bytes .../__pycache__/bccache.cpython-310.pyc | Bin 0 -> 13950 bytes .../__pycache__/compiler.cpython-310.pyc | Bin 0 -> 54553 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 1532 bytes .../jinja2/__pycache__/debug.cpython-310.pyc | Bin 0 -> 3988 bytes .../__pycache__/defaults.cpython-310.pyc | Bin 0 -> 1332 bytes .../__pycache__/environment.cpython-310.pyc | Bin 0 -> 53382 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5531 bytes .../jinja2/__pycache__/ext.cpython-310.pyc | Bin 0 -> 25695 bytes .../__pycache__/filters.cpython-310.pyc | Bin 0 -> 51185 bytes .../__pycache__/idtracking.cpython-310.pyc | Bin 0 -> 11083 bytes .../jinja2/__pycache__/lexer.cpython-310.pyc | Bin 0 -> 20435 bytes .../__pycache__/loaders.cpython-310.pyc | Bin 0 -> 20522 bytes .../jinja2/__pycache__/meta.cpython-310.pyc | Bin 0 -> 3812 bytes .../__pycache__/nativetypes.cpython-310.pyc | Bin 0 -> 5007 bytes .../jinja2/__pycache__/nodes.cpython-310.pyc | Bin 0 -> 40322 bytes .../__pycache__/optimizer.cpython-310.pyc | Bin 0 -> 1952 bytes .../jinja2/__pycache__/parser.cpython-310.pyc | Bin 0 -> 27683 bytes .../__pycache__/runtime.cpython-310.pyc | Bin 0 -> 32147 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 11966 bytes .../jinja2/__pycache__/tests.cpython-310.pyc | Bin 0 -> 6686 bytes .../jinja2/__pycache__/utils.cpython-310.pyc | Bin 0 -> 24509 bytes .../__pycache__/visitor.cpython-310.pyc | Bin 0 -> 3971 bytes .venv/Lib/site-packages/jinja2/_identifier.py | 6 + .venv/Lib/site-packages/jinja2/async_utils.py | 84 + .venv/Lib/site-packages/jinja2/bccache.py | 406 + .venv/Lib/site-packages/jinja2/compiler.py | 1957 ++++ .venv/Lib/site-packages/jinja2/constants.py | 20 + .venv/Lib/site-packages/jinja2/debug.py | 191 + .venv/Lib/site-packages/jinja2/defaults.py | 48 + .venv/Lib/site-packages/jinja2/environment.py | 1667 ++++ .venv/Lib/site-packages/jinja2/exceptions.py | 166 + .venv/Lib/site-packages/jinja2/ext.py | 859 ++ .venv/Lib/site-packages/jinja2/filters.py | 1840 ++++ .venv/Lib/site-packages/jinja2/idtracking.py | 318 + .venv/Lib/site-packages/jinja2/lexer.py | 866 ++ .venv/Lib/site-packages/jinja2/loaders.py | 661 ++ .venv/Lib/site-packages/jinja2/meta.py | 111 + .venv/Lib/site-packages/jinja2/nativetypes.py | 130 + .venv/Lib/site-packages/jinja2/nodes.py | 1204 +++ .venv/Lib/site-packages/jinja2/optimizer.py | 47 + .venv/Lib/site-packages/jinja2/parser.py | 1032 ++ .venv/Lib/site-packages/jinja2/py.typed | 0 .venv/Lib/site-packages/jinja2/runtime.py | 1053 ++ .venv/Lib/site-packages/jinja2/sandbox.py | 428 + .venv/Lib/site-packages/jinja2/tests.py | 255 + .venv/Lib/site-packages/jinja2/utils.py | 755 ++ .venv/Lib/site-packages/jinja2/visitor.py | 92 + .../Lib/site-packages/markupsafe/__init__.py | 304 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 11248 bytes .../__pycache__/_native.cpython-310.pyc | Bin 0 -> 1996 bytes .venv/Lib/site-packages/markupsafe/_native.py | 63 + .../Lib/site-packages/markupsafe/_speedups.c | 320 + .../markupsafe/_speedups.cp310-win_amd64.pyd | Bin 0 -> 15872 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .venv/Lib/site-packages/markupsafe/py.typed | 0 .../pip-22.2.2.dist-info/INSTALLER | 1 + .../pip-22.2.2.dist-info/LICENSE.txt | 20 + .../pip-22.2.2.dist-info/METADATA | 90 + .../site-packages/pip-22.2.2.dist-info/RECORD | 992 ++ .../pip-22.2.2.dist-info/REQUESTED | 0 .../site-packages/pip-22.2.2.dist-info/WHEEL | 5 + .../pip-22.2.2.dist-info/entry_points.txt | 4 + .../pip-22.2.2.dist-info/top_level.txt | 1 + .venv/Lib/site-packages/pip/__init__.py | 13 + .venv/Lib/site-packages/pip/__main__.py | 31 + .venv/Lib/site-packages/pip/__pip-runner__.py | 36 + .../pip/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 621 bytes .../pip/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 583 bytes .../__pip-runner__.cpython-310.pyc | Bin 0 -> 1390 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 742 bytes .../__pycache__/build_env.cpython-310.pyc | Bin 0 -> 9173 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 9204 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 11202 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 23114 bytes .../__pycache__/main.cpython-310.pyc | Bin 0 -> 607 bytes .../__pycache__/pyproject.cpython-310.pyc | Bin 0 -> 3611 bytes .../self_outdated_check.cpython-310.pyc | Bin 0 -> 6563 bytes .../__pycache__/wheel_builder.cpython-310.pyc | Bin 0 -> 9195 bytes .../site-packages/pip/_internal/build_env.py | 290 + .../Lib/site-packages/pip/_internal/cache.py | 289 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 262 bytes .../autocompletion.cpython-310.pyc | Bin 0 -> 5297 bytes .../__pycache__/base_command.cpython-310.pyc | Bin 0 -> 6331 bytes .../__pycache__/cmdoptions.cpython-310.pyc | Bin 0 -> 23665 bytes .../command_context.cpython-310.pyc | Bin 0 -> 1302 bytes .../cli/__pycache__/main.cpython-310.pyc | Bin 0 -> 1360 bytes .../__pycache__/main_parser.cpython-310.pyc | Bin 0 -> 2146 bytes .../cli/__pycache__/parser.cpython-310.pyc | Bin 0 -> 9944 bytes .../__pycache__/progress_bars.cpython-310.pyc | Bin 0 -> 1886 bytes .../__pycache__/req_command.cpython-310.pyc | Bin 0 -> 13081 bytes .../cli/__pycache__/spinners.cpython-310.pyc | Bin 0 -> 4924 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 341 bytes .../pip/_internal/cli/autocompletion.py | 171 + .../pip/_internal/cli/base_command.py | 223 + .../pip/_internal/cli/cmdoptions.py | 1062 ++ .../pip/_internal/cli/command_context.py | 27 + .../site-packages/pip/_internal/cli/main.py | 70 + .../pip/_internal/cli/main_parser.py | 87 + .../site-packages/pip/_internal/cli/parser.py | 294 + .../pip/_internal/cli/progress_bars.py | 68 + .../pip/_internal/cli/req_command.py | 502 + .../pip/_internal/cli/spinners.py | 159 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 132 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3241 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 6224 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 1559 bytes .../__pycache__/completion.cpython-310.pyc | Bin 0 -> 4150 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 8815 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 6656 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 4036 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 2624 bytes .../commands/__pycache__/hash.cpython-310.pyc | Bin 0 -> 2138 bytes .../commands/__pycache__/help.cpython-310.pyc | Bin 0 -> 1299 bytes .../__pycache__/index.cpython-310.pyc | Bin 0 -> 4548 bytes .../__pycache__/inspect.cpython-310.pyc | Bin 0 -> 3112 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 19409 bytes .../commands/__pycache__/list.cpython-310.pyc | Bin 0 -> 10180 bytes .../__pycache__/search.cpython-310.pyc | Bin 0 -> 5352 bytes .../commands/__pycache__/show.cpython-310.pyc | Bin 0 -> 6384 bytes .../__pycache__/uninstall.cpython-310.pyc | Bin 0 -> 3212 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4875 bytes .../pip/_internal/commands/cache.py | 223 + .../pip/_internal/commands/check.py | 53 + .../pip/_internal/commands/completion.py | 126 + .../pip/_internal/commands/configuration.py | 276 + .../pip/_internal/commands/debug.py | 199 + .../pip/_internal/commands/download.py | 142 + .../pip/_internal/commands/freeze.py | 97 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 138 + .../pip/_internal/commands/inspect.py | 97 + .../pip/_internal/commands/install.py | 827 ++ .../pip/_internal/commands/list.py | 360 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 183 + .../pip/_internal/commands/uninstall.py | 106 + .../pip/_internal/commands/wheel.py | 178 + .../pip/_internal/configuration.py | 374 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 789 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1877 bytes .../__pycache__/installed.cpython-310.pyc | Bin 0 -> 1254 bytes .../__pycache__/sdist.cpython-310.pyc | Bin 0 -> 4985 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1621 bytes .../pip/_internal/distributions/base.py | 39 + .../pip/_internal/distributions/installed.py | 23 + .../pip/_internal/distributions/sdist.py | 150 + .../pip/_internal/distributions/wheel.py | 34 + .../site-packages/pip/_internal/exceptions.py | 658 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 216 bytes .../__pycache__/collector.cpython-310.pyc | Bin 0 -> 17700 bytes .../package_finder.cpython-310.pyc | Bin 0 -> 29053 bytes .../index/__pycache__/sources.cpython-310.pyc | Bin 0 -> 7109 bytes .../pip/_internal/index/collector.py | 621 ++ .../pip/_internal/index/package_finder.py | 1025 ++ .../pip/_internal/index/sources.py | 224 + .../pip/_internal/locations/__init__.py | 528 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 12532 bytes .../__pycache__/_distutils.cpython-310.pyc | Bin 0 -> 4765 bytes .../__pycache__/_sysconfig.cpython-310.pyc | Bin 0 -> 6189 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 2392 bytes .../pip/_internal/locations/_distutils.py | 180 + .../pip/_internal/locations/_sysconfig.py | 218 + .../pip/_internal/locations/base.py | 81 + .venv/Lib/site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 105 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3997 bytes .../__pycache__/_json.cpython-310.pyc | Bin 0 -> 2176 bytes .../metadata/__pycache__/base.cpython-310.pyc | Bin 0 -> 25937 bytes .../__pycache__/pkg_resources.cpython-310.pyc | Bin 0 -> 9799 bytes .../pip/_internal/metadata/_json.py | 84 + .../pip/_internal/metadata/base.py | 670 ++ .../_internal/metadata/importlib/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 307 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 2113 bytes .../__pycache__/_dists.cpython-310.pyc | Bin 0 -> 8369 bytes .../__pycache__/_envs.cpython-310.pyc | Bin 0 -> 7480 bytes .../_internal/metadata/importlib/_compat.py | 43 + .../_internal/metadata/importlib/_dists.py | 206 + .../pip/_internal/metadata/importlib/_envs.py | 180 + .../pip/_internal/metadata/pkg_resources.py | 253 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 250 bytes .../__pycache__/candidate.cpython-310.pyc | Bin 0 -> 1402 bytes .../__pycache__/direct_url.cpython-310.pyc | Bin 0 -> 7096 bytes .../format_control.cpython-310.pyc | Bin 0 -> 2727 bytes .../models/__pycache__/index.cpython-310.pyc | Bin 0 -> 1219 bytes .../installation_report.cpython-310.pyc | Bin 0 -> 1729 bytes .../models/__pycache__/link.cpython-310.pyc | Bin 0 -> 10525 bytes .../models/__pycache__/scheme.cpython-310.pyc | Bin 0 -> 1018 bytes .../__pycache__/search_scope.cpython-310.pyc | Bin 0 -> 3473 bytes .../selection_prefs.cpython-310.pyc | Bin 0 -> 1680 bytes .../__pycache__/target_python.cpython-310.pyc | Bin 0 -> 3435 bytes .../models/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4429 bytes .../pip/_internal/models/candidate.py | 34 + .../pip/_internal/models/direct_url.py | 212 + .../pip/_internal/models/format_control.py | 80 + .../pip/_internal/models/index.py | 28 + .../_internal/models/installation_report.py | 53 + .../pip/_internal/models/link.py | 314 + .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 129 + .../pip/_internal/models/selection_prefs.py | 51 + .../pip/_internal/models/target_python.py | 110 + .../pip/_internal/models/wheel.py | 92 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 238 bytes .../network/__pycache__/auth.cpython-310.pyc | Bin 0 -> 7518 bytes .../network/__pycache__/cache.cpython-310.pyc | Bin 0 -> 2925 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 5520 bytes .../__pycache__/lazy_wheel.cpython-310.pyc | Bin 0 -> 8405 bytes .../__pycache__/session.cpython-310.pyc | Bin 0 -> 12418 bytes .../network/__pycache__/utils.cpython-310.pyc | Bin 0 -> 1441 bytes .../__pycache__/xmlrpc.cpython-310.pyc | Bin 0 -> 2051 bytes .../pip/_internal/network/auth.py | 323 + .../pip/_internal/network/cache.py | 69 + .../pip/_internal/network/download.py | 186 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 518 + .../pip/_internal/network/utils.py | 96 + .../pip/_internal/network/xmlrpc.py | 60 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 186 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 3999 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 6191 bytes .../__pycache__/prepare.cpython-310.pyc | Bin 0 -> 14043 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 192 bytes .../__pycache__/build_tracker.cpython-310.pyc | Bin 0 -> 4273 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 1419 bytes .../metadata_editable.cpython-310.pyc | Bin 0 -> 1453 bytes .../metadata_legacy.cpython-310.pyc | Bin 0 -> 2364 bytes .../build/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1209 bytes .../wheel_editable.cpython-310.pyc | Bin 0 -> 1433 bytes .../__pycache__/wheel_legacy.cpython-310.pyc | Bin 0 -> 2749 bytes .../operations/build/build_tracker.py | 124 + .../_internal/operations/build/metadata.py | 39 + .../operations/build/metadata_editable.py | 41 + .../operations/build/metadata_legacy.py | 74 + .../pip/_internal/operations/build/wheel.py | 37 + .../operations/build/wheel_editable.py | 46 + .../operations/build/wheel_legacy.py | 102 + .../pip/_internal/operations/check.py | 149 + .../pip/_internal/operations/freeze.py | 254 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 250 bytes .../editable_legacy.cpython-310.pyc | Bin 0 -> 1537 bytes .../__pycache__/legacy.cpython-310.pyc | Bin 0 -> 3335 bytes .../install/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 21109 bytes .../operations/install/editable_legacy.py | 47 + .../_internal/operations/install/legacy.py | 120 + .../pip/_internal/operations/install/wheel.py | 736 ++ .../pip/_internal/operations/prepare.py | 614 ++ .../site-packages/pip/_internal/pyproject.py | 175 + .../pip/_internal/req/__init__.py | 94 + .../req/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2593 bytes .../__pycache__/constructors.cpython-310.pyc | Bin 0 -> 12365 bytes .../req/__pycache__/req_file.cpython-310.pyc | Bin 0 -> 13530 bytes .../__pycache__/req_install.cpython-310.pyc | Bin 0 -> 22671 bytes .../req/__pycache__/req_set.cpython-310.pyc | Bin 0 -> 3901 bytes .../__pycache__/req_uninstall.cpython-310.pyc | Bin 0 -> 19052 bytes .../pip/_internal/req/constructors.py | 501 + .../pip/_internal/req/req_file.py | 540 ++ .../pip/_internal/req/req_install.py | 879 ++ .../pip/_internal/req/req_set.py | 82 + .../pip/_internal/req/req_uninstall.py | 640 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 186 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1038 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 193 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 14941 bytes .../_internal/resolution/legacy/resolver.py | 600 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 197 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 6440 bytes .../__pycache__/candidates.cpython-310.pyc | Bin 0 -> 18581 bytes .../__pycache__/factory.cpython-310.pyc | Bin 0 -> 19061 bytes .../found_candidates.cpython-310.pyc | Bin 0 -> 4857 bytes .../__pycache__/provider.cpython-310.pyc | Bin 0 -> 7698 bytes .../__pycache__/reporter.cpython-310.pyc | Bin 0 -> 3166 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 7455 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 8170 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 556 ++ .../resolution/resolvelib/factory.py | 731 ++ .../resolution/resolvelib/found_candidates.py | 155 + .../resolution/resolvelib/provider.py | 248 + .../resolution/resolvelib/reporter.py | 68 + .../resolution/resolvelib/requirements.py | 166 + .../resolution/resolvelib/resolver.py | 296 + .../pip/_internal/self_outdated_check.py | 239 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 181 bytes .../utils/__pycache__/_log.cpython-310.pyc | Bin 0 -> 1509 bytes .../utils/__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 1607 bytes .../utils/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1497 bytes .../compatibility_tags.cpython-310.pyc | Bin 0 -> 4066 bytes .../__pycache__/datetime.cpython-310.pyc | Bin 0 -> 504 bytes .../__pycache__/deprecation.cpython-310.pyc | Bin 0 -> 3306 bytes .../direct_url_helpers.cpython-310.pyc | Bin 0 -> 2072 bytes .../distutils_args.cpython-310.pyc | Bin 0 -> 1046 bytes .../__pycache__/egg_link.cpython-310.pyc | Bin 0 -> 2137 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1294 bytes .../__pycache__/entrypoints.cpython-310.pyc | Bin 0 -> 2632 bytes .../__pycache__/filesystem.cpython-310.pyc | Bin 0 -> 4470 bytes .../__pycache__/filetypes.cpython-310.pyc | Bin 0 -> 931 bytes .../utils/__pycache__/glibc.cpython-310.pyc | Bin 0 -> 1660 bytes .../utils/__pycache__/hashes.cpython-310.pyc | Bin 0 -> 5183 bytes .../inject_securetransport.cpython-310.pyc | Bin 0 -> 976 bytes .../utils/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9708 bytes .../utils/__pycache__/misc.cpython-310.pyc | Bin 0 -> 21587 bytes .../utils/__pycache__/models.cpython-310.pyc | Bin 0 -> 1977 bytes .../__pycache__/packaging.cpython-310.pyc | Bin 0 -> 2069 bytes .../setuptools_build.cpython-310.pyc | Bin 0 -> 4584 bytes .../__pycache__/subprocess.cpython-310.pyc | Bin 0 -> 5757 bytes .../__pycache__/temp_dir.cpython-310.pyc | Bin 0 -> 7304 bytes .../__pycache__/unpacking.cpython-310.pyc | Bin 0 -> 6655 bytes .../utils/__pycache__/urls.cpython-310.pyc | Bin 0 -> 1582 bytes .../__pycache__/virtualenv.cpython-310.pyc | Bin 0 -> 3277 bytes .../utils/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4402 bytes .../site-packages/pip/_internal/utils/_log.py | 38 + .../pip/_internal/utils/appdirs.py | 52 + .../pip/_internal/utils/compat.py | 63 + .../pip/_internal/utils/compatibility_tags.py | 165 + .../pip/_internal/utils/datetime.py | 11 + .../pip/_internal/utils/deprecation.py | 120 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/distutils_args.py | 43 + .../pip/_internal/utils/egg_link.py | 75 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 79 + .../pip/_internal/utils/filesystem.py | 153 + .../pip/_internal/utils/filetypes.py | 27 + .../pip/_internal/utils/glibc.py | 88 + .../pip/_internal/utils/hashes.py | 144 + .../_internal/utils/inject_securetransport.py | 35 + .../pip/_internal/utils/logging.py | 348 + .../site-packages/pip/_internal/utils/misc.py | 723 ++ .../pip/_internal/utils/models.py | 39 + .../pip/_internal/utils/packaging.py | 57 + .../pip/_internal/utils/setuptools_build.py | 195 + .../pip/_internal/utils/subprocess.py | 260 + .../pip/_internal/utils/temp_dir.py | 246 + .../pip/_internal/utils/unpacking.py | 257 + .../site-packages/pip/_internal/utils/urls.py | 62 + .../pip/_internal/utils/virtualenv.py | 104 + .../pip/_internal/utils/wheel.py | 136 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 504 bytes .../vcs/__pycache__/bazaar.cpython-310.pyc | Bin 0 -> 3331 bytes .../vcs/__pycache__/git.cpython-310.pyc | Bin 0 -> 12534 bytes .../vcs/__pycache__/mercurial.cpython-310.pyc | Bin 0 -> 5050 bytes .../__pycache__/subversion.cpython-310.pyc | Bin 0 -> 8438 bytes .../versioncontrol.cpython-310.pyc | Bin 0 -> 21133 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 101 + .../site-packages/pip/_internal/vcs/git.py | 526 + .../pip/_internal/vcs/mercurial.py | 163 + .../pip/_internal/vcs/subversion.py | 324 + .../pip/_internal/vcs/versioncontrol.py | 705 ++ .../pip/_internal/wheel_builder.py | 383 + .../Lib/site-packages/pip/_vendor/__init__.py | 120 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3117 bytes .../_vendor/__pycache__/six.cpython-310.pyc | Bin 0 -> 27575 bytes .../typing_extensions.cpython-310.pyc | Bin 0 -> 60715 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 632 bytes .../__pycache__/_cmd.cpython-310.pyc | Bin 0 -> 1570 bytes .../__pycache__/adapter.cpython-310.pyc | Bin 0 -> 3146 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 2680 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 746 bytes .../__pycache__/controller.cpython-310.pyc | Bin 0 -> 8586 bytes .../__pycache__/filewrapper.cpython-310.pyc | Bin 0 -> 2782 bytes .../__pycache__/heuristics.cpython-310.pyc | Bin 0 -> 4706 bytes .../__pycache__/serialize.cpython-310.pyc | Bin 0 -> 4321 bytes .../__pycache__/wrapper.cpython-310.pyc | Bin 0 -> 677 bytes .../pip/_vendor/cachecontrol/_cmd.py | 61 + .../pip/_vendor/cachecontrol/adapter.py | 137 + .../pip/_vendor/cachecontrol/cache.py | 65 + .../_vendor/cachecontrol/caches/__init__.py | 9 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 351 bytes .../__pycache__/file_cache.cpython-310.pyc | Bin 0 -> 4951 bytes .../__pycache__/redis_cache.cpython-310.pyc | Bin 0 -> 1609 bytes .../_vendor/cachecontrol/caches/file_cache.py | 188 + .../cachecontrol/caches/redis_cache.py | 39 + .../pip/_vendor/cachecontrol/compat.py | 32 + .../pip/_vendor/cachecontrol/controller.py | 439 + .../pip/_vendor/cachecontrol/filewrapper.py | 111 + .../pip/_vendor/cachecontrol/heuristics.py | 139 + .../pip/_vendor/cachecontrol/serialize.py | 190 + .../pip/_vendor/cachecontrol/wrapper.py | 33 + .../pip/_vendor/certifi/__init__.py | 4 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 294 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 444 bytes .../certifi/__pycache__/core.cpython-310.pyc | Bin 0 -> 1788 bytes .../pip/_vendor/certifi/cacert.pem | 4685 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 84 + .../pip/_vendor/chardet/__init__.py | 93 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2371 bytes .../__pycache__/big5freq.cpython-310.pyc | Bin 0 -> 27168 bytes .../__pycache__/big5prober.cpython-310.pyc | Bin 0 -> 1110 bytes .../chardistribution.cpython-310.pyc | Bin 0 -> 6213 bytes .../charsetgroupprober.cpython-310.pyc | Bin 0 -> 2204 bytes .../__pycache__/charsetprober.cpython-310.pyc | Bin 0 -> 3392 bytes .../codingstatemachine.cpython-310.pyc | Bin 0 -> 2877 bytes .../__pycache__/cp949prober.cpython-310.pyc | Bin 0 -> 1117 bytes .../chardet/__pycache__/enums.cpython-310.pyc | Bin 0 -> 2553 bytes .../__pycache__/escprober.cpython-310.pyc | Bin 0 -> 2598 bytes .../chardet/__pycache__/escsm.cpython-310.pyc | Bin 0 -> 8367 bytes .../__pycache__/eucjpprober.cpython-310.pyc | Bin 0 -> 2401 bytes .../__pycache__/euckrfreq.cpython-310.pyc | Bin 0 -> 12052 bytes .../__pycache__/euckrprober.cpython-310.pyc | Bin 0 -> 1118 bytes .../__pycache__/euctwfreq.cpython-310.pyc | Bin 0 -> 27172 bytes .../__pycache__/euctwprober.cpython-310.pyc | Bin 0 -> 1118 bytes .../__pycache__/gb2312freq.cpython-310.pyc | Bin 0 -> 19096 bytes .../__pycache__/gb2312prober.cpython-310.pyc | Bin 0 -> 1126 bytes .../__pycache__/hebrewprober.cpython-310.pyc | Bin 0 -> 3009 bytes .../__pycache__/jisfreq.cpython-310.pyc | Bin 0 -> 22124 bytes .../__pycache__/johabfreq.cpython-310.pyc | Bin 0 -> 138748 bytes .../__pycache__/johabprober.cpython-310.pyc | Bin 0 -> 1117 bytes .../__pycache__/jpcntx.cpython-310.pyc | Bin 0 -> 37620 bytes .../langbulgarianmodel.cpython-310.pyc | Bin 0 -> 47916 bytes .../langgreekmodel.cpython-310.pyc | Bin 0 -> 46106 bytes .../langhebrewmodel.cpython-310.pyc | Bin 0 -> 44553 bytes .../langhungarianmodel.cpython-310.pyc | Bin 0 -> 47876 bytes .../langrussianmodel.cpython-310.pyc | Bin 0 -> 61017 bytes .../__pycache__/langthaimodel.cpython-310.pyc | Bin 0 -> 44729 bytes .../langturkishmodel.cpython-310.pyc | Bin 0 -> 44570 bytes .../__pycache__/latin1prober.cpython-310.pyc | Bin 0 -> 4394 bytes .../mbcharsetprober.cpython-310.pyc | Bin 0 -> 2220 bytes .../mbcsgroupprober.cpython-310.pyc | Bin 0 -> 1171 bytes .../__pycache__/mbcssm.cpython-310.pyc | Bin 0 -> 20694 bytes .../sbcharsetprober.cpython-310.pyc | Bin 0 -> 3187 bytes .../sbcsgroupprober.cpython-310.pyc | Bin 0 -> 1710 bytes .../__pycache__/sjisprober.cpython-310.pyc | Bin 0 -> 2439 bytes .../universaldetector.cpython-310.pyc | Bin 0 -> 6456 bytes .../__pycache__/utf1632prober.cpython-310.pyc | Bin 0 -> 5870 bytes .../__pycache__/utf8prober.cpython-310.pyc | Bin 0 -> 1953 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 428 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 259 + .../pip/_vendor/chardet/charsetgroupprober.py | 109 + .../pip/_vendor/chardet/charsetprober.py | 138 + .../pip/_vendor/chardet/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 185 bytes .../__pycache__/chardetect.cpython-310.pyc | Bin 0 -> 2393 bytes .../pip/_vendor/chardet/cli/chardetect.py | 86 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 82 + .../pip/_vendor/chardet/escprober.py | 102 + .../pip/_vendor/chardet/escsm.py | 260 + .../pip/_vendor/chardet/eucjpprober.py | 95 + .../pip/_vendor/chardet/euckrfreq.py | 196 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 388 + .../pip/_vendor/chardet/euctwprober.py | 47 + .../pip/_vendor/chardet/gb2312freq.py | 284 + .../pip/_vendor/chardet/gb2312prober.py | 47 + .../pip/_vendor/chardet/hebrewprober.py | 302 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/johabfreq.py | 2382 +++++ .../pip/_vendor/chardet/johabprober.py | 47 + .../pip/_vendor/chardet/jpcntx.py | 237 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4649 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4397 +++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4380 +++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4649 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5725 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4380 +++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4380 +++++++++ .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 95 + .../pip/_vendor/chardet/mbcsgroupprober.py | 56 + .../pip/_vendor/chardet/mbcssm.py | 660 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 190 bytes .../__pycache__/languages.cpython-310.pyc | Bin 0 -> 7948 bytes .../pip/_vendor/chardet/metadata/languages.py | 351 + .../pip/_vendor/chardet/sbcharsetprober.py | 160 + .../pip/_vendor/chardet/sbcsgroupprober.py | 88 + .../pip/_vendor/chardet/sjisprober.py | 98 + .../pip/_vendor/chardet/universaldetector.py | 328 + .../pip/_vendor/chardet/utf1632prober.py | 223 + .../pip/_vendor/chardet/utf8prober.py | 80 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 433 bytes .../colorama/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 2994 bytes .../__pycache__/ansitowin32.cpython-310.pyc | Bin 0 -> 8196 bytes .../__pycache__/initialise.cpython-310.pyc | Bin 0 -> 1680 bytes .../__pycache__/win32.cpython-310.pyc | Bin 0 -> 3940 bytes .../__pycache__/winterm.cpython-310.pyc | Bin 0 -> 4557 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 266 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1052 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 31398 bytes .../__pycache__/database.cpython-310.pyc | Bin 0 -> 43138 bytes .../distlib/__pycache__/index.cpython-310.pyc | Bin 0 -> 17303 bytes .../__pycache__/locators.cpython-310.pyc | Bin 0 -> 38360 bytes .../__pycache__/manifest.cpython-310.pyc | Bin 0 -> 10220 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 5026 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 26777 bytes .../__pycache__/resources.cpython-310.pyc | Bin 0 -> 11026 bytes .../__pycache__/scripts.cpython-310.pyc | Bin 0 -> 11492 bytes .../distlib/__pycache__/util.cpython-310.pyc | Bin 0 -> 51687 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 20141 bytes .../distlib/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 28121 bytes .../pip/_vendor/distlib/compat.py | 1116 +++ .../pip/_vendor/distlib/database.py | 1350 +++ .../pip/_vendor/distlib/index.py | 508 + .../pip/_vendor/distlib/locators.py | 1300 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 152 + .../pip/_vendor/distlib/metadata.py | 1076 +++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 437 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 97792 bytes .../pip/_vendor/distlib/t64-arm.exe | Bin 0 -> 182784 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 107520 bytes .../site-packages/pip/_vendor/distlib/util.py | 1932 ++++ .../pip/_vendor/distlib/version.py | 739 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 91648 bytes .../pip/_vendor/distlib/w64-arm.exe | Bin 0 -> 168448 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 101888 bytes .../pip/_vendor/distlib/wheel.py | 1082 +++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 905 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 259 bytes .../distro/__pycache__/distro.cpython-310.pyc | Bin 0 -> 41322 bytes .../pip/_vendor/distro/distro.py | 1374 +++ .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 837 bytes .../idna/__pycache__/codec.cpython-310.pyc | Bin 0 -> 2808 bytes .../idna/__pycache__/compat.cpython-310.pyc | Bin 0 -> 737 bytes .../idna/__pycache__/core.cpython-310.pyc | Bin 0 -> 9580 bytes .../idna/__pycache__/idnadata.cpython-310.pyc | Bin 0 -> 38215 bytes .../__pycache__/intranges.cpython-310.pyc | Bin 0 -> 1974 bytes .../__pycache__/package_data.cpython-310.pyc | Bin 0 -> 201 bytes .../__pycache__/uts46data.cpython-310.pyc | Bin 0 -> 150936 bytes .../site-packages/pip/_vendor/idna/codec.py | 112 + .../site-packages/pip/_vendor/idna/compat.py | 13 + .../site-packages/pip/_vendor/idna/core.py | 397 + .../pip/_vendor/idna/idnadata.py | 2137 ++++ .../pip/_vendor/idna/intranges.py | 54 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8512 ++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 57 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1435 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 1798 bytes .../msgpack/__pycache__/ext.cpython-310.pyc | Bin 0 -> 6306 bytes .../__pycache__/fallback.cpython-310.pyc | Bin 0 -> 25473 bytes .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1010 ++ .../pip/_vendor/packaging/__about__.py | 26 + .../pip/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 580 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 436 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7290 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4602 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2695 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9279 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3965 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21517 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12186 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3565 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12915 bytes .../pip/_vendor/packaging/_manylinux.py | 301 + .../pip/_vendor/packaging/_musllinux.py | 136 + .../pip/_vendor/packaging/_structures.py | 61 + .../pip/_vendor/packaging/markers.py | 304 + .../pip/_vendor/packaging/requirements.py | 146 + .../pip/_vendor/packaging/specifiers.py | 802 ++ .../pip/_vendor/packaging/tags.py | 487 + .../pip/_vendor/packaging/utils.py | 136 + .../pip/_vendor/packaging/version.py | 504 + .../pip/_vendor/pep517/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 303 bytes .../pep517/__pycache__/build.cpython-310.pyc | Bin 0 -> 3586 bytes .../pep517/__pycache__/check.cpython-310.pyc | Bin 0 -> 4550 bytes .../__pycache__/colorlog.cpython-310.pyc | Bin 0 -> 2954 bytes .../pep517/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1527 bytes .../__pycache__/dirtools.cpython-310.pyc | Bin 0 -> 1345 bytes .../__pycache__/envbuild.cpython-310.pyc | Bin 0 -> 4368 bytes .../pep517/__pycache__/meta.cpython-310.pyc | Bin 0 -> 2950 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 12296 bytes .../site-packages/pip/_vendor/pep517/build.py | 127 + .../site-packages/pip/_vendor/pep517/check.py | 207 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 51 + .../pip/_vendor/pep517/dirtools.py | 44 + .../pip/_vendor/pep517/envbuild.py | 171 + .../pip/_vendor/pep517/in_process/__init__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 911 bytes .../__pycache__/_in_process.cpython-310.pyc | Bin 0 -> 10058 bytes .../_vendor/pep517/in_process/_in_process.py | 363 + .../site-packages/pip/_vendor/pep517/meta.py | 92 + .../pip/_vendor/pep517/wrappers.py | 375 + .../pip/_vendor/pkg_resources/__init__.py | 3296 +++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 99880 bytes .../__pycache__/py31compat.cpython-310.pyc | Bin 0 -> 650 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/platformdirs/__init__.py | 340 + .../pip/_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 10518 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 1226 bytes .../__pycache__/android.cpython-310.pyc | Bin 0 -> 4316 bytes .../__pycache__/api.cpython-310.pyc | Bin 0 -> 5192 bytes .../__pycache__/macos.cpython-310.pyc | Bin 0 -> 3180 bytes .../__pycache__/unix.cpython-310.pyc | Bin 0 -> 6881 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 283 bytes .../__pycache__/windows.cpython-310.pyc | Bin 0 -> 6424 bytes .../pip/_vendor/platformdirs/android.py | 120 + .../pip/_vendor/platformdirs/api.py | 156 + .../pip/_vendor/platformdirs/macos.py | 64 + .../pip/_vendor/platformdirs/unix.py | 181 + .../pip/_vendor/platformdirs/version.py | 4 + .../pip/_vendor/platformdirs/windows.py | 182 + .../pip/_vendor/pygments/__init__.py | 83 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2990 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 578 bytes .../__pycache__/cmdline.cpython-310.pyc | Bin 0 -> 15443 bytes .../__pycache__/console.cpython-310.pyc | Bin 0 -> 1873 bytes .../__pycache__/filter.cpython-310.pyc | Bin 0 -> 2644 bytes .../__pycache__/formatter.cpython-310.pyc | Bin 0 -> 3000 bytes .../__pycache__/lexer.cpython-310.pyc | Bin 0 -> 24363 bytes .../__pycache__/modeline.cpython-310.pyc | Bin 0 -> 1182 bytes .../__pycache__/plugin.cpython-310.pyc | Bin 0 -> 2034 bytes .../__pycache__/regexopt.cpython-310.pyc | Bin 0 -> 2946 bytes .../__pycache__/scanner.cpython-310.pyc | Bin 0 -> 3548 bytes .../__pycache__/sphinxext.cpython-310.pyc | Bin 0 -> 4532 bytes .../__pycache__/style.cpython-310.pyc | Bin 0 -> 4569 bytes .../__pycache__/token.cpython-310.pyc | Bin 0 -> 4641 bytes .../__pycache__/unistring.cpython-310.pyc | Bin 0 -> 31195 bytes .../pygments/__pycache__/util.cpython-310.pyc | Bin 0 -> 9137 bytes .../pip/_vendor/pygments/cmdline.py | 663 ++ .../pip/_vendor/pygments/console.py | 70 + .../pip/_vendor/pygments/filter.py | 71 + .../pip/_vendor/pygments/filters/__init__.py | 937 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 29507 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 153 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4658 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 5526 bytes .../__pycache__/bbcode.cpython-310.pyc | Bin 0 -> 3075 bytes .../__pycache__/groff.cpython-310.pyc | Bin 0 -> 4388 bytes .../__pycache__/html.cpython-310.pyc | Bin 0 -> 29122 bytes .../__pycache__/img.cpython-310.pyc | Bin 0 -> 17487 bytes .../__pycache__/irc.cpython-310.pyc | Bin 0 -> 4578 bytes .../__pycache__/latex.cpython-310.pyc | Bin 0 -> 13788 bytes .../__pycache__/other.cpython-310.pyc | Bin 0 -> 4794 bytes .../__pycache__/pangomarkup.cpython-310.pyc | Bin 0 -> 2094 bytes .../__pycache__/rtf.cpython-310.pyc | Bin 0 -> 4124 bytes .../__pycache__/svg.cpython-310.pyc | Bin 0 -> 6322 bytes .../__pycache__/terminal.cpython-310.pyc | Bin 0 -> 3989 bytes .../__pycache__/terminal256.cpython-310.pyc | Bin 0 -> 9239 bytes .../_vendor/pygments/formatters/_mapping.py | 84 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 170 + .../pip/_vendor/pygments/formatters/html.py | 989 ++ .../pip/_vendor/pygments/formatters/img.py | 641 ++ .../pip/_vendor/pygments/formatters/irc.py | 179 + .../pip/_vendor/pygments/formatters/latex.py | 521 + .../pip/_vendor/pygments/formatters/other.py | 161 + .../pygments/formatters/pangomarkup.py | 83 + .../pip/_vendor/pygments/formatters/rtf.py | 146 + .../pip/_vendor/pygments/formatters/svg.py | 188 + .../_vendor/pygments/formatters/terminal.py | 127 + .../pygments/formatters/terminal256.py | 338 + .../pip/_vendor/pygments/lexer.py | 882 ++ .../pip/_vendor/pygments/lexers/__init__.py | 345 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9344 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 60139 bytes .../lexers/__pycache__/python.cpython-310.pyc | Bin 0 -> 29347 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 596 ++ .../pip/_vendor/pygments/lexers/python.py | 1191 +++ .../pip/_vendor/pygments/modeline.py | 43 + .../pip/_vendor/pygments/plugin.py | 69 + .../pip/_vendor/pygments/regexopt.py | 91 + .../pip/_vendor/pygments/scanner.py | 104 + .../pip/_vendor/pygments/sphinxext.py | 155 + .../pip/_vendor/pygments/style.py | 197 + .../pip/_vendor/pygments/styles/__init__.py | 93 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3210 bytes .../pip/_vendor/pygments/token.py | 212 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 308 + .../pip/_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7119 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7169 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10095 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 176510 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9053 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 35330 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24777 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12089 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 10048 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8595 bytes .../pip/_vendor/pyparsing/actions.py | 207 + .../pip/_vendor/pyparsing/common.py | 424 + .../pip/_vendor/pyparsing/core.py | 5814 +++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 642 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16583 bytes .../pip/_vendor/pyparsing/exceptions.py | 267 + .../pip/_vendor/pyparsing/helpers.py | 1088 +++ .../pip/_vendor/pyparsing/results.py | 760 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 352 + .../pip/_vendor/pyparsing/util.py | 235 + .../pip/_vendor/requests/__init__.py | 182 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4006 bytes .../__pycache__/__version__.cpython-310.pyc | Bin 0 -> 545 bytes .../_internal_utils.cpython-310.pyc | Bin 0 -> 1555 bytes .../__pycache__/adapters.cpython-310.pyc | Bin 0 -> 16889 bytes .../requests/__pycache__/api.cpython-310.pyc | Bin 0 -> 6644 bytes .../requests/__pycache__/auth.cpython-310.pyc | Bin 0 -> 8112 bytes .../__pycache__/certs.cpython-310.pyc | Bin 0 -> 629 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 1361 bytes .../__pycache__/cookies.cpython-310.pyc | Bin 0 -> 18687 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5731 bytes .../requests/__pycache__/help.cpython-310.pyc | Bin 0 -> 2857 bytes .../__pycache__/hooks.cpython-310.pyc | Bin 0 -> 984 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 24257 bytes .../__pycache__/packages.cpython-310.pyc | Bin 0 -> 498 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 19576 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 4663 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 4428 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 24326 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 48 + .../pip/_vendor/requests/adapters.py | 584 ++ .../site-packages/pip/_vendor/requests/api.py | 157 + .../pip/_vendor/requests/auth.py | 315 + .../pip/_vendor/requests/certs.py | 17 + .../pip/_vendor/requests/compat.py | 67 + .../pip/_vendor/requests/cookies.py | 561 ++ .../pip/_vendor/requests/exceptions.py | 141 + .../pip/_vendor/requests/help.py | 131 + .../pip/_vendor/requests/hooks.py | 33 + .../pip/_vendor/requests/models.py | 1034 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 831 ++ .../pip/_vendor/requests/status_codes.py | 128 + .../pip/_vendor/requests/structures.py | 99 + .../pip/_vendor/requests/utils.py | 1086 +++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 596 bytes .../__pycache__/providers.cpython-310.pyc | Bin 0 -> 6647 bytes .../__pycache__/reporters.cpython-310.pyc | Bin 0 -> 2567 bytes .../__pycache__/resolvers.cpython-310.pyc | Bin 0 -> 15120 bytes .../__pycache__/structs.cpython-310.pyc | Bin 0 -> 7153 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 191 bytes .../collections_abc.cpython-310.pyc | Bin 0 -> 367 bytes .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 133 + .../pip/_vendor/resolvelib/reporters.py | 43 + .../pip/_vendor/resolvelib/resolvers.py | 482 + .../pip/_vendor/resolvelib/structs.py | 165 + .../pip/_vendor/rich/__init__.py | 176 + .../pip/_vendor/rich/__main__.py | 282 + .../rich/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5964 bytes .../rich/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 7286 bytes .../__pycache__/_cell_widths.cpython-310.pyc | Bin 0 -> 7804 bytes .../__pycache__/_emoji_codes.cpython-310.pyc | Bin 0 -> 360044 bytes .../_emoji_replace.cpython-310.pyc | Bin 0 -> 1184 bytes .../_export_format.cpython-310.pyc | Bin 0 -> 2301 bytes .../__pycache__/_extension.cpython-310.pyc | Bin 0 -> 485 bytes .../rich/__pycache__/_inspect.cpython-310.pyc | Bin 0 -> 8662 bytes .../__pycache__/_log_render.cpython-310.pyc | Bin 0 -> 2630 bytes .../rich/__pycache__/_loop.cpython-310.pyc | Bin 0 -> 1282 bytes .../__pycache__/_palettes.cpython-310.pyc | Bin 0 -> 5087 bytes .../rich/__pycache__/_pick.cpython-310.pyc | Bin 0 -> 630 bytes .../rich/__pycache__/_ratio.cpython-310.pyc | Bin 0 -> 5149 bytes .../__pycache__/_spinners.cpython-310.pyc | Bin 0 -> 12261 bytes .../rich/__pycache__/_stack.cpython-310.pyc | Bin 0 -> 828 bytes .../rich/__pycache__/_timer.cpython-310.pyc | Bin 0 -> 677 bytes .../_win32_console.cpython-310.pyc | Bin 0 -> 18997 bytes .../rich/__pycache__/_windows.cpython-310.pyc | Bin 0 -> 1779 bytes .../_windows_renderer.cpython-310.pyc | Bin 0 -> 2033 bytes .../rich/__pycache__/_wrap.cpython-310.pyc | Bin 0 -> 1541 bytes .../rich/__pycache__/abc.cpython-310.pyc | Bin 0 -> 1304 bytes .../rich/__pycache__/align.cpython-310.pyc | Bin 0 -> 7939 bytes .../rich/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 5946 bytes .../rich/__pycache__/bar.cpython-310.pyc | Bin 0 -> 2973 bytes .../rich/__pycache__/box.cpython-310.pyc | Bin 0 -> 8393 bytes .../rich/__pycache__/cells.cpython-310.pyc | Bin 0 -> 3963 bytes .../rich/__pycache__/color.cpython-310.pyc | Bin 0 -> 17451 bytes .../__pycache__/color_triplet.cpython-310.pyc | Bin 0 -> 1427 bytes .../rich/__pycache__/columns.cpython-310.pyc | Bin 0 -> 6187 bytes .../rich/__pycache__/console.cpython-310.pyc | Bin 0 -> 80947 bytes .../__pycache__/constrain.cpython-310.pyc | Bin 0 -> 1744 bytes .../__pycache__/containers.cpython-310.pyc | Bin 0 -> 6476 bytes .../rich/__pycache__/control.cpython-310.pyc | Bin 0 -> 8149 bytes .../default_styles.cpython-310.pyc | Bin 0 -> 6188 bytes .../rich/__pycache__/diagnose.cpython-310.pyc | Bin 0 -> 1211 bytes .../rich/__pycache__/emoji.cpython-310.pyc | Bin 0 -> 3257 bytes .../rich/__pycache__/errors.cpython-310.pyc | Bin 0 -> 1517 bytes .../__pycache__/file_proxy.cpython-310.pyc | Bin 0 -> 2250 bytes .../rich/__pycache__/filesize.cpython-310.pyc | Bin 0 -> 2606 bytes .../__pycache__/highlighter.cpython-310.pyc | Bin 0 -> 8050 bytes .../rich/__pycache__/json.cpython-310.pyc | Bin 0 -> 4737 bytes .../rich/__pycache__/jupyter.cpython-310.pyc | Bin 0 -> 3989 bytes .../rich/__pycache__/layout.cpython-310.pyc | Bin 0 -> 14676 bytes .../rich/__pycache__/live.cpython-310.pyc | Bin 0 -> 11614 bytes .../__pycache__/live_render.cpython-310.pyc | Bin 0 -> 3392 bytes .../rich/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9763 bytes .../rich/__pycache__/markup.cpython-310.pyc | Bin 0 -> 5931 bytes .../rich/__pycache__/measure.cpython-310.pyc | Bin 0 -> 5066 bytes .../rich/__pycache__/padding.cpython-310.pyc | Bin 0 -> 4472 bytes .../rich/__pycache__/pager.cpython-310.pyc | Bin 0 -> 1466 bytes .../rich/__pycache__/palette.cpython-310.pyc | Bin 0 -> 3698 bytes .../rich/__pycache__/panel.cpython-310.pyc | Bin 0 -> 6409 bytes .../rich/__pycache__/pretty.cpython-310.pyc | Bin 0 -> 27393 bytes .../rich/__pycache__/progress.cpython-310.pyc | Bin 0 -> 53892 bytes .../__pycache__/progress_bar.cpython-310.pyc | Bin 0 -> 6897 bytes .../rich/__pycache__/prompt.cpython-310.pyc | Bin 0 -> 11291 bytes .../rich/__pycache__/protocol.cpython-310.pyc | Bin 0 -> 1342 bytes .../rich/__pycache__/region.cpython-310.pyc | Bin 0 -> 517 bytes .../rich/__pycache__/repr.cpython-310.pyc | Bin 0 -> 4105 bytes .../rich/__pycache__/rule.cpython-310.pyc | Bin 0 -> 4299 bytes .../rich/__pycache__/scope.cpython-310.pyc | Bin 0 -> 2978 bytes .../rich/__pycache__/screen.cpython-310.pyc | Bin 0 -> 1869 bytes .../rich/__pycache__/segment.cpython-310.pyc | Bin 0 -> 20747 bytes .../rich/__pycache__/spinner.cpython-310.pyc | Bin 0 -> 4407 bytes .../rich/__pycache__/status.cpython-310.pyc | Bin 0 -> 4583 bytes .../rich/__pycache__/style.cpython-310.pyc | Bin 0 -> 20779 bytes .../rich/__pycache__/styled.cpython-310.pyc | Bin 0 -> 1753 bytes .../rich/__pycache__/syntax.cpython-310.pyc | Bin 0 -> 25352 bytes .../rich/__pycache__/table.cpython-310.pyc | Bin 0 -> 29719 bytes .../terminal_theme.cpython-310.pyc | Bin 0 -> 3006 bytes .../rich/__pycache__/text.cpython-310.pyc | Bin 0 -> 39410 bytes .../rich/__pycache__/theme.cpython-310.pyc | Bin 0 -> 4690 bytes .../rich/__pycache__/themes.cpython-310.pyc | Bin 0 -> 283 bytes .../__pycache__/traceback.cpython-310.pyc | Bin 0 -> 19639 bytes .../rich/__pycache__/tree.cpython-310.pyc | Bin 0 -> 7324 bytes .../pip/_vendor/rich/_cell_widths.py | 451 + .../pip/_vendor/rich/_emoji_codes.py | 3610 +++++++ .../pip/_vendor/rich/_emoji_replace.py | 32 + .../pip/_vendor/rich/_export_format.py | 78 + .../pip/_vendor/rich/_extension.py | 10 + .../pip/_vendor/rich/_inspect.py | 270 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_palettes.py | 309 + .../site-packages/pip/_vendor/rich/_pick.py | 17 + .../site-packages/pip/_vendor/rich/_ratio.py | 160 + .../pip/_vendor/rich/_spinners.py | 482 + .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_win32_console.py | 662 ++ .../pip/_vendor/rich/_windows.py | 72 + .../pip/_vendor/rich/_windows_renderer.py | 56 + .../site-packages/pip/_vendor/rich/_wrap.py | 56 + .../Lib/site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 311 + .../site-packages/pip/_vendor/rich/ansi.py | 237 + .../Lib/site-packages/pip/_vendor/rich/bar.py | 94 + .../Lib/site-packages/pip/_vendor/rich/box.py | 517 + .../site-packages/pip/_vendor/rich/cells.py | 154 + .../site-packages/pip/_vendor/rich/color.py | 615 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2572 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 225 + .../pip/_vendor/rich/default_styles.py | 188 + .../pip/_vendor/rich/diagnose.py | 37 + .../site-packages/pip/_vendor/rich/emoji.py | 96 + .../site-packages/pip/_vendor/rich/errors.py | 34 + .../pip/_vendor/rich/file_proxy.py | 54 + .../pip/_vendor/rich/filesize.py | 89 + .../pip/_vendor/rich/highlighter.py | 232 + .../site-packages/pip/_vendor/rich/json.py | 140 + .../site-packages/pip/_vendor/rich/jupyter.py | 101 + .../site-packages/pip/_vendor/rich/layout.py | 445 + .../site-packages/pip/_vendor/rich/live.py | 373 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 280 + .../site-packages/pip/_vendor/rich/markup.py | 246 + .../site-packages/pip/_vendor/rich/measure.py | 151 + .../site-packages/pip/_vendor/rich/padding.py | 141 + .../site-packages/pip/_vendor/rich/pager.py | 34 + .../site-packages/pip/_vendor/rich/palette.py | 100 + .../site-packages/pip/_vendor/rich/panel.py | 251 + .../site-packages/pip/_vendor/rich/pretty.py | 1010 ++ .../pip/_vendor/rich/progress.py | 1703 ++++ .../pip/_vendor/rich/progress_bar.py | 224 + .../site-packages/pip/_vendor/rich/prompt.py | 376 + .../pip/_vendor/rich/protocol.py | 42 + .../site-packages/pip/_vendor/rich/region.py | 10 + .../site-packages/pip/_vendor/rich/repr.py | 152 + .../site-packages/pip/_vendor/rich/rule.py | 134 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 739 ++ .../site-packages/pip/_vendor/rich/spinner.py | 136 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 771 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 934 ++ .../site-packages/pip/_vendor/rich/table.py | 996 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1286 +++ .../site-packages/pip/_vendor/rich/theme.py | 112 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 679 ++ .../site-packages/pip/_vendor/rich/tree.py | 251 + .venv/Lib/site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 517 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16364 bytes .../__pycache__/_asyncio.cpython-310.pyc | Bin 0 -> 2604 bytes .../__pycache__/_utils.cpython-310.pyc | Bin 0 -> 1217 bytes .../__pycache__/after.cpython-310.pyc | Bin 0 -> 1221 bytes .../__pycache__/before.cpython-310.pyc | Bin 0 -> 1099 bytes .../__pycache__/before_sleep.cpython-310.pyc | Bin 0 -> 1401 bytes .../tenacity/__pycache__/nap.cpython-310.pyc | Bin 0 -> 1189 bytes .../__pycache__/retry.cpython-310.pyc | Bin 0 -> 8419 bytes .../tenacity/__pycache__/stop.cpython-310.pyc | Bin 0 -> 4007 bytes .../__pycache__/tornadoweb.cpython-310.pyc | Bin 0 -> 1754 bytes .../tenacity/__pycache__/wait.cpython-310.pyc | Bin 0 -> 7951 bytes .../pip/_vendor/tenacity/_asyncio.py | 92 + .../pip/_vendor/tenacity/_utils.py | 68 + .../pip/_vendor/tenacity/after.py | 46 + .../pip/_vendor/tenacity/before.py | 41 + .../pip/_vendor/tenacity/before_sleep.py | 58 + .../site-packages/pip/_vendor/tenacity/nap.py | 43 + .../pip/_vendor/tenacity/retry.py | 213 + .../pip/_vendor/tenacity/stop.py | 96 + .../pip/_vendor/tenacity/tornadoweb.py | 59 + .../pip/_vendor/tenacity/wait.py | 191 + .../pip/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 345 bytes .../tomli/__pycache__/_parser.cpython-310.pyc | Bin 0 -> 17059 bytes .../tomli/__pycache__/_re.cpython-310.pyc | Bin 0 -> 2891 bytes .../tomli/__pycache__/_types.cpython-310.pyc | Bin 0 -> 315 bytes .../pip/_vendor/tomli/_parser.py | 691 ++ .../site-packages/pip/_vendor/tomli/_re.py | 107 + .../site-packages/pip/_vendor/tomli/_types.py | 10 + .../pip/_vendor/typing_extensions.py | 2069 ++++ .../pip/_vendor/urllib3/__init__.py | 85 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2179 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 10853 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 204 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 13633 bytes .../connectionpool.cpython-310.pyc | Bin 0 -> 25395 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10984 bytes .../__pycache__/fields.cpython-310.pyc | Bin 0 -> 8175 bytes .../__pycache__/filepost.cpython-310.pyc | Bin 0 -> 2740 bytes .../__pycache__/poolmanager.cpython-310.pyc | Bin 0 -> 15209 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 5616 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 20864 bytes .../pip/_vendor/urllib3/_collections.py | 337 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 567 ++ .../pip/_vendor/urllib3/connectionpool.py | 1110 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 189 bytes .../_appengine_environ.cpython-310.pyc | Bin 0 -> 1369 bytes .../__pycache__/appengine.cpython-310.pyc | Bin 0 -> 8185 bytes .../__pycache__/ntlmpool.cpython-310.pyc | Bin 0 -> 3624 bytes .../__pycache__/pyopenssl.cpython-310.pyc | Bin 0 -> 15528 bytes .../securetransport.cpython-310.pyc | Bin 0 -> 21931 bytes .../contrib/__pycache__/socks.cpython-310.pyc | Bin 0 -> 5591 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 206 bytes .../__pycache__/bindings.cpython-310.pyc | Bin 0 -> 10702 bytes .../__pycache__/low_level.cpython-310.pyc | Bin 0 -> 9089 bytes .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 397 + .../pip/_vendor/urllib3/contrib/appengine.py | 314 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 130 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 510 + .../urllib3/contrib/securetransport.py | 921 ++ .../pip/_vendor/urllib3/contrib/socks.py | 216 + .../pip/_vendor/urllib3/exceptions.py | 323 + .../pip/_vendor/urllib3/fields.py | 274 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 190 bytes .../packages/__pycache__/six.cpython-310.pyc | Bin 0 -> 27650 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 200 bytes .../__pycache__/makefile.cpython-310.pyc | Bin 0 -> 1300 bytes .../urllib3/packages/backports/makefile.py | 51 + .../pip/_vendor/urllib3/packages/six.py | 1076 +++ .../pip/_vendor/urllib3/poolmanager.py | 537 + .../pip/_vendor/urllib3/request.py | 170 + .../pip/_vendor/urllib3/response.py | 818 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1099 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 3427 bytes .../util/__pycache__/proxy.cpython-310.pyc | Bin 0 -> 1334 bytes .../util/__pycache__/queue.cpython-310.pyc | Bin 0 -> 1054 bytes .../util/__pycache__/request.cpython-310.pyc | Bin 0 -> 3361 bytes .../util/__pycache__/response.cpython-310.pyc | Bin 0 -> 2347 bytes .../util/__pycache__/retry.cpython-310.pyc | Bin 0 -> 16132 bytes .../util/__pycache__/ssl_.cpython-310.pyc | Bin 0 -> 11301 bytes .../ssl_match_hostname.cpython-310.pyc | Bin 0 -> 3251 bytes .../__pycache__/ssltransport.cpython-310.pyc | Bin 0 -> 7389 bytes .../util/__pycache__/timeout.cpython-310.pyc | Bin 0 -> 8931 bytes .../util/__pycache__/url.cpython-310.pyc | Bin 0 -> 10687 bytes .../util/__pycache__/wait.cpython-310.pyc | Bin 0 -> 3083 bytes .../pip/_vendor/urllib3/util/connection.py | 149 + .../pip/_vendor/urllib3/util/proxy.py | 57 + .../pip/_vendor/urllib3/util/queue.py | 22 + .../pip/_vendor/urllib3/util/request.py | 137 + .../pip/_vendor/urllib3/util/response.py | 107 + .../pip/_vendor/urllib3/util/retry.py | 620 ++ .../pip/_vendor/urllib3/util/ssl_.py | 495 + .../urllib3/util/ssl_match_hostname.py | 159 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 268 + .../pip/_vendor/urllib3/util/url.py | 435 + .../pip/_vendor/urllib3/util/wait.py | 152 + .../Lib/site-packages/pip/_vendor/vendor.txt | 23 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9736 bytes .../__pycache__/labels.cpython-310.pyc | Bin 0 -> 5226 bytes .../__pycache__/mklabels.cpython-310.pyc | Bin 0 -> 1931 bytes .../__pycache__/tests.cpython-310.pyc | Bin 0 -> 5033 bytes .../x_user_defined.cpython-310.pyc | Bin 0 -> 2582 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .venv/Lib/site-packages/pip/py.typed | 4 + .../site-packages/pkg_resources/__init__.py | 3296 +++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 100565 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 183 bytes .../__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 20244 bytes .../_vendor/__pycache__/zipp.cpython-310.pyc | Bin 0 -> 10226 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 638 bytes .../__pycache__/_adapters.cpython-310.pyc | Bin 0 -> 7346 bytes .../__pycache__/_common.cpython-310.pyc | Bin 0 -> 2636 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 3496 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 883 bytes .../__pycache__/_legacy.cpython-310.pyc | Bin 0 -> 4219 bytes .../__pycache__/abc.cpython-310.pyc | Bin 0 -> 5372 bytes .../__pycache__/readers.cpython-310.pyc | Bin 0 -> 5456 bytes .../__pycache__/simple.cpython-310.pyc | Bin 0 -> 4724 bytes .../_vendor/importlib_resources/_adapters.py | 170 + .../_vendor/importlib_resources/_common.py | 104 + .../_vendor/importlib_resources/_compat.py | 98 + .../_vendor/importlib_resources/_itertools.py | 35 + .../_vendor/importlib_resources/_legacy.py | 121 + .../_vendor/importlib_resources/abc.py | 137 + .../_vendor/importlib_resources/readers.py | 122 + .../_vendor/importlib_resources/simple.py | 116 + .../pkg_resources/_vendor/jaraco/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 190 bytes .../__pycache__/context.cpython-310.pyc | Bin 0 -> 6322 bytes .../__pycache__/functools.cpython-310.pyc | Bin 0 -> 15614 bytes .../pkg_resources/_vendor/jaraco/context.py | 213 + .../pkg_resources/_vendor/jaraco/functools.py | 525 + .../_vendor/jaraco/text/__init__.py | 599 ++ .../text/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 19659 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 265 bytes .../__pycache__/more.cpython-310.pyc | Bin 0 -> 123050 bytes .../__pycache__/recipes.cpython-310.pyc | Bin 0 -> 20326 bytes .../_vendor/more_itertools/more.py | 4316 +++++++++ .../_vendor/more_itertools/recipes.py | 698 ++ .../_vendor/packaging/__about__.py | 26 + .../_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 590 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 446 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7300 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4612 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2705 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9298 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3984 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21527 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12196 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3575 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12925 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 61 + .../_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 802 ++ .../pkg_resources/_vendor/packaging/tags.py | 487 + .../pkg_resources/_vendor/packaging/utils.py | 136 + .../_vendor/packaging/version.py | 504 + .../_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7117 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7182 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10105 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 176394 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9072 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 35249 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24799 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12102 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 9814 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8605 bytes .../_vendor/pyparsing/actions.py | 207 + .../pkg_resources/_vendor/pyparsing/common.py | 424 + .../pkg_resources/_vendor/pyparsing/core.py | 5812 +++++++++++ .../_vendor/pyparsing/diagram/__init__.py | 611 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16063 bytes .../_vendor/pyparsing/exceptions.py | 267 + .../_vendor/pyparsing/helpers.py | 1083 +++ .../_vendor/pyparsing/results.py | 760 ++ .../_vendor/pyparsing/testing.py | 331 + .../_vendor/pyparsing/unicode.py | 332 + .../pkg_resources/_vendor/pyparsing/util.py | 235 + .../pkg_resources/_vendor/zipp.py | 329 + .../pkg_resources/extern/__init__.py | 76 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2936 bytes .../requests-2.31.0.dist-info/INSTALLER | 1 + .../requests-2.31.0.dist-info/LICENSE | 175 + .../requests-2.31.0.dist-info/METADATA | 122 + .../requests-2.31.0.dist-info/RECORD | 43 + .../requests-2.31.0.dist-info/REQUESTED | 0 .../requests-2.31.0.dist-info/WHEEL | 5 + .../requests-2.31.0.dist-info/top_level.txt | 1 + .venv/Lib/site-packages/requests/__init__.py | 180 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3862 bytes .../__pycache__/__version__.cpython-310.pyc | Bin 0 -> 528 bytes .../_internal_utils.cpython-310.pyc | Bin 0 -> 1604 bytes .../__pycache__/adapters.cpython-310.pyc | Bin 0 -> 16130 bytes .../requests/__pycache__/api.cpython-310.pyc | Bin 0 -> 6704 bytes .../requests/__pycache__/auth.cpython-310.pyc | Bin 0 -> 8100 bytes .../__pycache__/certs.cpython-310.pyc | Bin 0 -> 605 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 1502 bytes .../__pycache__/cookies.cpython-310.pyc | Bin 0 -> 18675 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5707 bytes .../requests/__pycache__/help.cpython-310.pyc | Bin 0 -> 2827 bytes .../__pycache__/hooks.cpython-310.pyc | Bin 0 -> 972 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 24174 bytes .../__pycache__/packages.cpython-310.pyc | Bin 0 -> 699 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 19584 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 4651 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 4416 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 24413 bytes .../Lib/site-packages/requests/__version__.py | 14 + .../site-packages/requests/_internal_utils.py | 50 + .venv/Lib/site-packages/requests/adapters.py | 538 ++ .venv/Lib/site-packages/requests/api.py | 157 + .venv/Lib/site-packages/requests/auth.py | 315 + .venv/Lib/site-packages/requests/certs.py | 17 + .venv/Lib/site-packages/requests/compat.py | 79 + .venv/Lib/site-packages/requests/cookies.py | 561 ++ .../Lib/site-packages/requests/exceptions.py | 141 + .venv/Lib/site-packages/requests/help.py | 134 + .venv/Lib/site-packages/requests/hooks.py | 33 + .venv/Lib/site-packages/requests/models.py | 1034 ++ .venv/Lib/site-packages/requests/packages.py | 28 + .venv/Lib/site-packages/requests/sessions.py | 833 ++ .../site-packages/requests/status_codes.py | 128 + .../Lib/site-packages/requests/structures.py | 99 + .venv/Lib/site-packages/requests/utils.py | 1094 +++ .../setuptools-63.2.0.dist-info/INSTALLER | 1 + .../setuptools-63.2.0.dist-info/LICENSE | 19 + .../setuptools-63.2.0.dist-info/METADATA | 140 + .../setuptools-63.2.0.dist-info/RECORD | 468 + .../setuptools-63.2.0.dist-info/REQUESTED | 0 .../setuptools-63.2.0.dist-info/WHEEL | 5 + .../entry_points.txt | 56 + .../setuptools-63.2.0.dist-info/top_level.txt | 3 + .../Lib/site-packages/setuptools/__init__.py | 189 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 6572 bytes .../_deprecation_warning.cpython-310.pyc | Bin 0 -> 544 bytes .../__pycache__/_entry_points.cpython-310.pyc | Bin 0 -> 3007 bytes .../__pycache__/_imp.cpython-310.pyc | Bin 0 -> 2070 bytes .../__pycache__/_importlib.cpython-310.pyc | Bin 0 -> 1340 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 908 bytes .../__pycache__/_path.cpython-310.pyc | Bin 0 -> 420 bytes .../__pycache__/_reqs.cpython-310.pyc | Bin 0 -> 823 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 6174 bytes .../__pycache__/build_meta.cpython-310.pyc | Bin 0 -> 9858 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 851 bytes .../__pycache__/depends.cpython-310.pyc | Bin 0 -> 5290 bytes .../__pycache__/discovery.cpython-310.pyc | Bin 0 -> 20569 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 38398 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 2478 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 5570 bytes .../__pycache__/glob.cpython-310.pyc | Bin 0 -> 3729 bytes .../__pycache__/installer.cpython-310.pyc | Bin 0 -> 2975 bytes .../__pycache__/launch.cpython-310.pyc | Bin 0 -> 901 bytes .../__pycache__/logging.cpython-310.pyc | Bin 0 -> 1204 bytes .../__pycache__/monkey.cpython-310.pyc | Bin 0 -> 4629 bytes .../__pycache__/msvc.cpython-310.pyc | Bin 0 -> 42633 bytes .../__pycache__/namespaces.cpython-310.pyc | Bin 0 -> 3612 bytes .../__pycache__/package_index.cpython-310.pyc | Bin 0 -> 32681 bytes .../__pycache__/py34compat.cpython-310.pyc | Bin 0 -> 476 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 15752 bytes .../__pycache__/unicode_utils.cpython-310.pyc | Bin 0 -> 1106 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 318 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 7368 bytes .../windows_support.cpython-310.pyc | Bin 0 -> 1024 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 24 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 552 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 2053 bytes .../__pycache__/_functools.cpython-310.pyc | Bin 0 -> 683 bytes .../__pycache__/_macos_compat.cpython-310.pyc | Bin 0 -> 447 bytes .../__pycache__/_msvccompiler.cpython-310.pyc | Bin 0 -> 13853 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 6563 bytes .../__pycache__/bcppcompiler.cpython-310.pyc | Bin 0 -> 6573 bytes .../__pycache__/ccompiler.cpython-310.pyc | Bin 0 -> 33358 bytes .../__pycache__/cmd.cpython-310.pyc | Bin 0 -> 13956 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 3578 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 7080 bytes .../cygwinccompiler.cpython-310.pyc | Bin 0 -> 8328 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 246 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 2763 bytes .../__pycache__/dir_util.cpython-310.pyc | Bin 0 -> 5912 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 34118 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 4988 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 7004 bytes .../__pycache__/fancy_getopt.cpython-310.pyc | Bin 0 -> 10634 bytes .../__pycache__/file_util.cpython-310.pyc | Bin 0 -> 5958 bytes .../__pycache__/filelist.cpython-310.pyc | Bin 0 -> 10794 bytes .../__pycache__/log.cpython-310.pyc | Bin 0 -> 2303 bytes .../__pycache__/msvc9compiler.cpython-310.pyc | Bin 0 -> 17525 bytes .../__pycache__/msvccompiler.cpython-310.pyc | Bin 0 -> 14785 bytes .../__pycache__/py38compat.cpython-310.pyc | Bin 0 -> 419 bytes .../__pycache__/py39compat.cpython-310.pyc | Bin 0 -> 728 bytes .../__pycache__/spawn.cpython-310.pyc | Bin 0 -> 2848 bytes .../__pycache__/sysconfig.cpython-310.pyc | Bin 0 -> 12572 bytes .../__pycache__/text_file.cpython-310.pyc | Bin 0 -> 8249 bytes .../__pycache__/unixccompiler.cpython-310.pyc | Bin 0 -> 8640 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 13500 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 7821 bytes .../versionpredicate.cpython-310.pyc | Bin 0 -> 5321 bytes .../setuptools/_distutils/_collections.py | 56 + .../setuptools/_distutils/_functools.py | 20 + .../setuptools/_distutils/_macos_compat.py | 12 + .../setuptools/_distutils/_msvccompiler.py | 591 ++ .../setuptools/_distutils/archive_util.py | 280 + .../setuptools/_distutils/bcppcompiler.py | 398 + .../setuptools/_distutils/ccompiler.py | 1193 +++ .../setuptools/_distutils/cmd.py | 434 + .../setuptools/_distutils/command/__init__.py | 32 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 525 bytes .../_framework_compat.cpython-310.pyc | Bin 0 -> 1917 bytes .../command/__pycache__/bdist.cpython-310.pyc | Bin 0 -> 3640 bytes .../__pycache__/bdist_dumb.cpython-310.pyc | Bin 0 -> 3634 bytes .../__pycache__/bdist_msi.cpython-310.pyc | Bin 0 -> 20189 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 12267 bytes .../__pycache__/bdist_wininst.cpython-310.pyc | Bin 0 -> 8607 bytes .../command/__pycache__/build.cpython-310.pyc | Bin 0 -> 3891 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 4856 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 16220 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 9793 bytes .../__pycache__/build_scripts.cpython-310.pyc | Bin 0 -> 4594 bytes .../command/__pycache__/check.cpython-310.pyc | Bin 0 -> 4547 bytes .../command/__pycache__/clean.cpython-310.pyc | Bin 0 -> 2126 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 10356 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 17212 bytes .../__pycache__/install_data.cpython-310.pyc | Bin 0 -> 2347 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 3306 bytes .../install_headers.cpython-310.pyc | Bin 0 -> 1762 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 5190 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2195 bytes .../__pycache__/py37compat.cpython-310.pyc | Bin 0 -> 1038 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 8562 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 14499 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 5349 bytes .../_distutils/command/_framework_compat.py | 55 + .../setuptools/_distutils/command/bdist.py | 155 + .../_distutils/command/bdist_dumb.py | 142 + .../_distutils/command/bdist_msi.py | 1114 +++ .../_distutils/command/bdist_rpm.py | 607 ++ .../_distutils/command/bdist_wininst.py | 418 + .../setuptools/_distutils/command/build.py | 152 + .../_distutils/command/build_clib.py | 208 + .../_distutils/command/build_ext.py | 780 ++ .../setuptools/_distutils/command/build_py.py | 408 + .../_distutils/command/build_scripts.py | 173 + .../setuptools/_distutils/command/check.py | 153 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 376 + .../setuptools/_distutils/command/install.py | 811 ++ .../_distutils/command/install_data.py | 84 + .../_distutils/command/install_egg_info.py | 87 + .../_distutils/command/install_headers.py | 45 + .../_distutils/command/install_lib.py | 238 + .../_distutils/command/install_scripts.py | 61 + .../_distutils/command/py37compat.py | 31 + .../setuptools/_distutils/command/register.py | 319 + .../setuptools/_distutils/command/sdist.py | 531 + .../setuptools/_distutils/command/upload.py | 205 + .../setuptools/_distutils/config.py | 139 + .../setuptools/_distutils/core.py | 283 + .../setuptools/_distutils/cygwinccompiler.py | 414 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 96 + .../setuptools/_distutils/dir_util.py | 239 + .../setuptools/_distutils/dist.py | 1286 +++ .../setuptools/_distutils/errors.py | 127 + .../setuptools/_distutils/extension.py | 248 + .../setuptools/_distutils/fancy_getopt.py | 468 + .../setuptools/_distutils/file_util.py | 245 + .../setuptools/_distutils/filelist.py | 371 + .../setuptools/_distutils/log.py | 80 + .../setuptools/_distutils/msvc9compiler.py | 820 ++ .../setuptools/_distutils/msvccompiler.py | 683 ++ .../setuptools/_distutils/py38compat.py | 8 + .../setuptools/_distutils/py39compat.py | 22 + .../setuptools/_distutils/spawn.py | 107 + .../setuptools/_distutils/sysconfig.py | 549 ++ .../setuptools/_distutils/text_file.py | 287 + .../setuptools/_distutils/unixccompiler.py | 382 + .../setuptools/_distutils/util.py | 520 + .../setuptools/_distutils/version.py | 358 + .../setuptools/_distutils/versionpredicate.py | 175 + .../site-packages/setuptools/_entry_points.py | 86 + .venv/Lib/site-packages/setuptools/_imp.py | 82 + .../site-packages/setuptools/_importlib.py | 47 + .../site-packages/setuptools/_itertools.py | 23 + .venv/Lib/site-packages/setuptools/_path.py | 7 + .venv/Lib/site-packages/setuptools/_reqs.py | 19 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 180 bytes .../__pycache__/ordered_set.cpython-310.pyc | Bin 0 -> 16316 bytes .../typing_extensions.cpython-310.pyc | Bin 0 -> 66594 bytes .../_vendor/__pycache__/zipp.cpython-310.pyc | Bin 0 -> 10223 bytes .../_vendor/importlib_metadata/__init__.py | 1047 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 37415 bytes .../__pycache__/_adapters.cpython-310.pyc | Bin 0 -> 2400 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 1575 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 2064 bytes .../__pycache__/_functools.cpython-310.pyc | Bin 0 -> 3165 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 2046 bytes .../__pycache__/_meta.cpython-310.pyc | Bin 0 -> 2354 bytes .../__pycache__/_text.cpython-310.pyc | Bin 0 -> 3098 bytes .../_vendor/importlib_metadata/_adapters.py | 68 + .../importlib_metadata/_collections.py | 30 + .../_vendor/importlib_metadata/_compat.py | 71 + .../_vendor/importlib_metadata/_functools.py | 104 + .../_vendor/importlib_metadata/_itertools.py | 73 + .../_vendor/importlib_metadata/_meta.py | 48 + .../_vendor/importlib_metadata/_text.py | 99 + .../_vendor/importlib_resources/__init__.py | 36 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 635 bytes .../__pycache__/_adapters.cpython-310.pyc | Bin 0 -> 7343 bytes .../__pycache__/_common.cpython-310.pyc | Bin 0 -> 2633 bytes .../__pycache__/_compat.cpython-310.pyc | Bin 0 -> 3493 bytes .../__pycache__/_itertools.cpython-310.pyc | Bin 0 -> 880 bytes .../__pycache__/_legacy.cpython-310.pyc | Bin 0 -> 4216 bytes .../__pycache__/abc.cpython-310.pyc | Bin 0 -> 5369 bytes .../__pycache__/readers.cpython-310.pyc | Bin 0 -> 5453 bytes .../__pycache__/simple.cpython-310.pyc | Bin 0 -> 4721 bytes .../_vendor/importlib_resources/_adapters.py | 170 + .../_vendor/importlib_resources/_common.py | 104 + .../_vendor/importlib_resources/_compat.py | 98 + .../_vendor/importlib_resources/_itertools.py | 35 + .../_vendor/importlib_resources/_legacy.py | 121 + .../_vendor/importlib_resources/abc.py | 137 + .../_vendor/importlib_resources/readers.py | 122 + .../_vendor/importlib_resources/simple.py | 116 + .../setuptools/_vendor/jaraco/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 187 bytes .../__pycache__/context.cpython-310.pyc | Bin 0 -> 6319 bytes .../__pycache__/functools.cpython-310.pyc | Bin 0 -> 15605 bytes .../setuptools/_vendor/jaraco/context.py | 213 + .../setuptools/_vendor/jaraco/functools.py | 525 + .../_vendor/jaraco/text/__init__.py | 599 ++ .../text/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 19647 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 261 bytes .../__pycache__/more.cpython-310.pyc | Bin 0 -> 109994 bytes .../__pycache__/recipes.cpython-310.pyc | Bin 0 -> 17961 bytes .../setuptools/_vendor/more_itertools/more.py | 3824 ++++++++ .../_vendor/more_itertools/recipes.py | 620 ++ .../setuptools/_vendor/ordered_set.py | 488 + .../setuptools/_vendor/packaging/__about__.py | 26 + .../setuptools/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 587 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 443 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7297 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4609 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2702 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9292 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3978 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21524 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12193 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3572 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12922 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 61 + .../setuptools/_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 802 ++ .../setuptools/_vendor/packaging/tags.py | 487 + .../setuptools/_vendor/packaging/utils.py | 136 + .../setuptools/_vendor/packaging/version.py | 504 + .../setuptools/_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7114 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7179 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10102 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 176391 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9069 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 35246 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24796 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12099 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 9811 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8602 bytes .../setuptools/_vendor/pyparsing/actions.py | 207 + .../setuptools/_vendor/pyparsing/common.py | 424 + .../setuptools/_vendor/pyparsing/core.py | 5812 +++++++++++ .../_vendor/pyparsing/diagram/__init__.py | 611 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16060 bytes .../_vendor/pyparsing/exceptions.py | 267 + .../setuptools/_vendor/pyparsing/helpers.py | 1083 +++ .../setuptools/_vendor/pyparsing/results.py | 760 ++ .../setuptools/_vendor/pyparsing/testing.py | 331 + .../setuptools/_vendor/pyparsing/unicode.py | 332 + .../setuptools/_vendor/pyparsing/util.py | 235 + .../setuptools/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 352 bytes .../tomli/__pycache__/_parser.cpython-310.pyc | Bin 0 -> 17066 bytes .../tomli/__pycache__/_re.cpython-310.pyc | Bin 0 -> 2898 bytes .../tomli/__pycache__/_types.cpython-310.pyc | Bin 0 -> 322 bytes .../setuptools/_vendor/tomli/_parser.py | 691 ++ .../setuptools/_vendor/tomli/_re.py | 107 + .../setuptools/_vendor/tomli/_types.py | 10 + .../setuptools/_vendor/typing_extensions.py | 2296 +++++ .../site-packages/setuptools/_vendor/zipp.py | 329 + .../site-packages/setuptools/archive_util.py | 213 + .../site-packages/setuptools/build_meta.py | 304 + .venv/Lib/site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .venv/Lib/site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli-arm64.exe | Bin 0 -> 137216 bytes .venv/Lib/site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 8 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 369 bytes .../command/__pycache__/alias.cpython-310.pyc | Bin 0 -> 2371 bytes .../__pycache__/bdist_egg.cpython-310.pyc | Bin 0 -> 13121 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 1584 bytes .../command/__pycache__/build.cpython-310.pyc | Bin 0 -> 1214 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 2460 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 9887 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 10666 bytes .../__pycache__/develop.cpython-310.pyc | Bin 0 -> 6147 bytes .../__pycache__/dist_info.cpython-310.pyc | Bin 0 -> 2628 bytes .../__pycache__/easy_install.cpython-310.pyc | Bin 0 -> 64420 bytes .../__pycache__/egg_info.cpython-310.pyc | Bin 0 -> 22889 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 4280 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 2454 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 4166 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2448 bytes .../__pycache__/py36compat.cpython-310.pyc | Bin 0 -> 4531 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 835 bytes .../__pycache__/rotate.cpython-310.pyc | Bin 0 -> 2502 bytes .../__pycache__/saveopts.cpython-310.pyc | Bin 0 -> 921 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 6979 bytes .../__pycache__/setopt.cpython-310.pyc | Bin 0 -> 4683 bytes .../command/__pycache__/test.cpython-310.pyc | Bin 0 -> 8225 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 808 bytes .../__pycache__/upload_docs.cpython-310.pyc | Bin 0 -> 6398 bytes .../site-packages/setuptools/command/alias.py | 78 + .../setuptools/command/bdist_egg.py | 457 + .../setuptools/command/bdist_rpm.py | 40 + .../site-packages/setuptools/command/build.py | 24 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_py.py | 298 + .../setuptools/command/develop.py | 193 + .../setuptools/command/dist_info.py | 69 + .../setuptools/command/easy_install.py | 2312 +++++ .../setuptools/command/egg_info.py | 752 ++ .../setuptools/command/install.py | 139 + .../setuptools/command/install_egg_info.py | 63 + .../setuptools/command/install_lib.py | 122 + .../setuptools/command/install_scripts.py | 70 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 134 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 64 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 196 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 251 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 212 + .../setuptools/config/__init__.py | 35 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1437 bytes .../_apply_pyprojecttoml.cpython-310.pyc | Bin 0 -> 13520 bytes .../config/__pycache__/expand.cpython-310.pyc | Bin 0 -> 18087 bytes .../__pycache__/pyprojecttoml.cpython-310.pyc | Bin 0 -> 16150 bytes .../__pycache__/setupcfg.cpython-310.pyc | Bin 0 -> 19669 bytes .../setuptools/config/_apply_pyprojecttoml.py | 377 + .../config/_validate_pyproject/__init__.py | 34 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1512 bytes .../error_reporting.cpython-310.pyc | Bin 0 -> 11573 bytes .../extra_validations.cpython-310.pyc | Bin 0 -> 1426 bytes .../fastjsonschema_exceptions.cpython-310.pyc | Bin 0 -> 2444 bytes ...fastjsonschema_validations.cpython-310.pyc | Bin 0 -> 68685 bytes .../__pycache__/formats.cpython-310.pyc | Bin 0 -> 8492 bytes .../_validate_pyproject/error_reporting.py | 318 + .../_validate_pyproject/extra_validations.py | 36 + .../fastjsonschema_exceptions.py | 51 + .../fastjsonschema_validations.py | 1035 ++ .../config/_validate_pyproject/formats.py | 257 + .../site-packages/setuptools/config/expand.py | 479 + .../setuptools/config/pyprojecttoml.py | 484 + .../setuptools/config/setupcfg.py | 713 ++ .../Lib/site-packages/setuptools/dep_util.py | 25 + .venv/Lib/site-packages/setuptools/depends.py | 176 + .../Lib/site-packages/setuptools/discovery.py | 588 ++ .venv/Lib/site-packages/setuptools/dist.py | 1222 +++ .venv/Lib/site-packages/setuptools/errors.py | 58 + .../Lib/site-packages/setuptools/extension.py | 140 + .../setuptools/extern/__init__.py | 76 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3011 bytes .venv/Lib/site-packages/setuptools/glob.py | 167 + .venv/Lib/site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .venv/Lib/site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui-arm64.exe | Bin 0 -> 137728 bytes .venv/Lib/site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../Lib/site-packages/setuptools/installer.py | 104 + .venv/Lib/site-packages/setuptools/launch.py | 36 + .venv/Lib/site-packages/setuptools/logging.py | 36 + .venv/Lib/site-packages/setuptools/monkey.py | 177 + .venv/Lib/site-packages/setuptools/msvc.py | 1805 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1126 +++ .../site-packages/setuptools/py34compat.py | 13 + .venv/Lib/site-packages/setuptools/sandbox.py | 530 + .../setuptools/script (dev).tmpl | 6 + .../Lib/site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/unicode_utils.py | 42 + .venv/Lib/site-packages/setuptools/version.py | 6 + .venv/Lib/site-packages/setuptools/wheel.py | 213 + .../setuptools/windows_support.py | 29 + .../urllib3-2.0.7.dist-info/INSTALLER | 1 + .../urllib3-2.0.7.dist-info/METADATA | 158 + .../urllib3-2.0.7.dist-info/RECORD | 70 + .../urllib3-2.0.7.dist-info/WHEEL | 4 + .../licenses/LICENSE.txt | 21 + .venv/Lib/site-packages/urllib3/__init__.py | 166 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4191 bytes .../_base_connection.cpython-310.pyc | Bin 0 -> 5709 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 16223 bytes .../_request_methods.cpython-310.pyc | Bin 0 -> 6910 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 241 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 21819 bytes .../connectionpool.cpython-310.pyc | Bin 0 -> 29185 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 13178 bytes .../__pycache__/fields.cpython-310.pyc | Bin 0 -> 9786 bytes .../__pycache__/filepost.cpython-310.pyc | Bin 0 -> 2344 bytes .../__pycache__/poolmanager.cpython-310.pyc | Bin 0 -> 18176 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 30813 bytes .../site-packages/urllib3/_base_connection.py | 173 + .../Lib/site-packages/urllib3/_collections.py | 481 + .../site-packages/urllib3/_request_methods.py | 217 + .venv/Lib/site-packages/urllib3/_version.py | 4 + .venv/Lib/site-packages/urllib3/connection.py | 906 ++ .../site-packages/urllib3/connectionpool.py | 1183 +++ .../site-packages/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 177 bytes .../__pycache__/pyopenssl.cpython-310.pyc | Bin 0 -> 17138 bytes .../securetransport.cpython-310.pyc | Bin 0 -> 22169 bytes .../contrib/__pycache__/socks.cpython-310.pyc | Bin 0 -> 6214 bytes .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 194 bytes .../__pycache__/bindings.cpython-310.pyc | Bin 0 -> 7745 bytes .../__pycache__/low_level.cpython-310.pyc | Bin 0 -> 11447 bytes .../contrib/_securetransport/bindings.py | 430 + .../contrib/_securetransport/low_level.py | 474 + .../urllib3/contrib/pyopenssl.py | 548 ++ .../urllib3/contrib/securetransport.py | 913 ++ .../site-packages/urllib3/contrib/socks.py | 233 + .venv/Lib/site-packages/urllib3/exceptions.py | 318 + .venv/Lib/site-packages/urllib3/fields.py | 345 + .venv/Lib/site-packages/urllib3/filepost.py | 89 + .../Lib/site-packages/urllib3/poolmanager.py | 637 ++ .venv/Lib/site-packages/urllib3/py.typed | 2 + .venv/Lib/site-packages/urllib3/response.py | 1132 +++ .../site-packages/urllib3/util/__init__.py | 44 + .../util/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 991 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 3480 bytes .../util/__pycache__/proxy.cpython-310.pyc | Bin 0 -> 1089 bytes .../util/__pycache__/request.cpython-310.pyc | Bin 0 -> 6235 bytes .../util/__pycache__/response.cpython-310.pyc | Bin 0 -> 2343 bytes .../util/__pycache__/retry.cpython-310.pyc | Bin 0 -> 15678 bytes .../util/__pycache__/ssl_.cpython-310.pyc | Bin 0 -> 12407 bytes .../ssl_match_hostname.cpython-310.pyc | Bin 0 -> 3712 bytes .../__pycache__/ssltransport.cpython-310.pyc | Bin 0 -> 9622 bytes .../util/__pycache__/timeout.cpython-310.pyc | Bin 0 -> 9807 bytes .../util/__pycache__/url.cpython-310.pyc | Bin 0 -> 11252 bytes .../util/__pycache__/util.cpython-310.pyc | Bin 0 -> 1217 bytes .../util/__pycache__/wait.cpython-310.pyc | Bin 0 -> 2396 bytes .../site-packages/urllib3/util/connection.py | 137 + .venv/Lib/site-packages/urllib3/util/proxy.py | 43 + .../Lib/site-packages/urllib3/util/request.py | 256 + .../site-packages/urllib3/util/response.py | 101 + .venv/Lib/site-packages/urllib3/util/retry.py | 529 + .venv/Lib/site-packages/urllib3/util/ssl_.py | 515 + .../urllib3/util/ssl_match_hostname.py | 159 + .../urllib3/util/ssltransport.py | 280 + .../Lib/site-packages/urllib3/util/timeout.py | 279 + .venv/Lib/site-packages/urllib3/util/url.py | 471 + .venv/Lib/site-packages/urllib3/util/util.py | 42 + .venv/Lib/site-packages/urllib3/util/wait.py | 124 + .../werkzeug-3.0.0.dist-info/INSTALLER | 1 + .../werkzeug-3.0.0.dist-info/LICENSE.rst | 28 + .../werkzeug-3.0.0.dist-info/METADATA | 118 + .../werkzeug-3.0.0.dist-info/RECORD | 125 + .../werkzeug-3.0.0.dist-info/WHEEL | 4 + .venv/Lib/site-packages/werkzeug/__init__.py | 25 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 928 bytes .../__pycache__/_internal.cpython-310.pyc | Bin 0 -> 7050 bytes .../__pycache__/_reloader.cpython-310.pyc | Bin 0 -> 12630 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 27320 bytes .../__pycache__/formparser.cpython-310.pyc | Bin 0 -> 12648 bytes .../werkzeug/__pycache__/http.cpython-310.pyc | Bin 0 -> 38887 bytes .../__pycache__/local.cpython-310.pyc | Bin 0 -> 20916 bytes .../__pycache__/security.cpython-310.pyc | Bin 0 -> 5357 bytes .../__pycache__/serving.cpython-310.pyc | Bin 0 -> 30457 bytes .../werkzeug/__pycache__/test.cpython-310.pyc | Bin 0 -> 42885 bytes .../__pycache__/testapp.cpython-310.pyc | Bin 0 -> 6389 bytes .../werkzeug/__pycache__/urls.cpython-310.pyc | Bin 0 -> 6441 bytes .../__pycache__/user_agent.cpython-310.pyc | Bin 0 -> 1856 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 22280 bytes .../werkzeug/__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 19948 bytes .venv/Lib/site-packages/werkzeug/_internal.py | 214 + .venv/Lib/site-packages/werkzeug/_reloader.py | 458 + .../werkzeug/datastructures/__init__.py | 34 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1550 bytes .../__pycache__/accept.cpython-310.pyc | Bin 0 -> 10642 bytes .../__pycache__/auth.cpython-310.pyc | Bin 0 -> 10465 bytes .../__pycache__/cache_control.cpython-310.pyc | Bin 0 -> 6609 bytes .../__pycache__/csp.cpython-310.pyc | Bin 0 -> 4145 bytes .../__pycache__/etag.cpython-310.pyc | Bin 0 -> 3909 bytes .../__pycache__/file_storage.cpython-310.pyc | Bin 0 -> 6058 bytes .../__pycache__/headers.cpython-310.pyc | Bin 0 -> 17740 bytes .../__pycache__/mixins.cpython-310.pyc | Bin 0 -> 9045 bytes .../__pycache__/range.cpython-310.pyc | Bin 0 -> 6012 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 35929 bytes .../werkzeug/datastructures/accept.py | 326 + .../werkzeug/datastructures/accept.pyi | 54 + .../werkzeug/datastructures/auth.py | 318 + .../werkzeug/datastructures/cache_control.py | 175 + .../werkzeug/datastructures/cache_control.pyi | 109 + .../werkzeug/datastructures/csp.py | 94 + .../werkzeug/datastructures/csp.pyi | 169 + .../werkzeug/datastructures/etag.py | 95 + .../werkzeug/datastructures/etag.pyi | 30 + .../werkzeug/datastructures/file_storage.py | 196 + .../werkzeug/datastructures/file_storage.pyi | 47 + .../werkzeug/datastructures/headers.py | 515 + .../werkzeug/datastructures/headers.pyi | 109 + .../werkzeug/datastructures/mixins.py | 242 + .../werkzeug/datastructures/mixins.pyi | 97 + .../werkzeug/datastructures/range.py | 180 + .../werkzeug/datastructures/range.pyi | 57 + .../werkzeug/datastructures/structures.py | 1006 ++ .../werkzeug/datastructures/structures.pyi | 208 + .../site-packages/werkzeug/debug/__init__.py | 534 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 14370 bytes .../debug/__pycache__/console.cpython-310.pyc | Bin 0 -> 8314 bytes .../debug/__pycache__/repr.cpython-310.pyc | Bin 0 -> 9065 bytes .../debug/__pycache__/tbtools.cpython-310.pyc | Bin 0 -> 11796 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../Lib/site-packages/werkzeug/debug/repr.py | 283 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 360 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/style.css | 150 + .../site-packages/werkzeug/debug/tbtools.py | 437 + .../Lib/site-packages/werkzeug/exceptions.py | 879 ++ .../Lib/site-packages/werkzeug/formparser.py | 421 + .venv/Lib/site-packages/werkzeug/http.py | 1372 +++ .venv/Lib/site-packages/werkzeug/local.py | 643 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 181 bytes .../__pycache__/dispatcher.cpython-310.pyc | Bin 0 -> 2830 bytes .../__pycache__/http_proxy.cpython-310.pyc | Bin 0 -> 6925 bytes .../__pycache__/lint.cpython-310.pyc | Bin 0 -> 12984 bytes .../__pycache__/profiler.cpython-310.pyc | Bin 0 -> 5622 bytes .../__pycache__/proxy_fix.cpython-310.pyc | Bin 0 -> 6023 bytes .../__pycache__/shared_data.cpython-310.pyc | Bin 0 -> 9275 bytes .../werkzeug/middleware/dispatcher.py | 80 + .../werkzeug/middleware/http_proxy.py | 235 + .../site-packages/werkzeug/middleware/lint.py | 420 + .../werkzeug/middleware/profiler.py | 154 + .../werkzeug/middleware/proxy_fix.py | 182 + .../werkzeug/middleware/shared_data.py | 282 + .venv/Lib/site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 133 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4619 bytes .../__pycache__/converters.cpython-310.pyc | Bin 0 -> 9152 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5635 bytes .../routing/__pycache__/map.cpython-310.pyc | Bin 0 -> 30927 bytes .../__pycache__/matcher.cpython-310.pyc | Bin 0 -> 5132 bytes .../routing/__pycache__/rules.cpython-310.pyc | Bin 0 -> 27662 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 148 + .../Lib/site-packages/werkzeug/routing/map.py | 946 ++ .../site-packages/werkzeug/routing/matcher.py | 202 + .../site-packages/werkzeug/routing/rules.py | 909 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 177 bytes .../sansio/__pycache__/http.cpython-310.pyc | Bin 0 -> 4127 bytes .../__pycache__/multipart.cpython-310.pyc | Bin 0 -> 7430 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 17292 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 24511 bytes .../sansio/__pycache__/utils.cpython-310.pyc | Bin 0 -> 4616 bytes .../Lib/site-packages/werkzeug/sansio/http.py | 171 + .../werkzeug/sansio/multipart.py | 313 + .../site-packages/werkzeug/sansio/request.py | 536 + .../site-packages/werkzeug/sansio/response.py | 751 ++ .../site-packages/werkzeug/sansio/utils.py | 159 + .venv/Lib/site-packages/werkzeug/security.py | 157 + .venv/Lib/site-packages/werkzeug/serving.py | 1109 +++ .venv/Lib/site-packages/werkzeug/test.py | 1462 +++ .venv/Lib/site-packages/werkzeug/testapp.py | 181 + .venv/Lib/site-packages/werkzeug/urls.py | 216 + .../Lib/site-packages/werkzeug/user_agent.py | 47 + .venv/Lib/site-packages/werkzeug/utils.py | 690 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 296 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 21644 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 28440 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 835 ++ .venv/Lib/site-packages/werkzeug/wsgi.py | 595 ++ .venv/Scripts/Activate.ps1 | 472 + .venv/Scripts/activate | 69 + .venv/Scripts/activate.bat | 34 + .venv/Scripts/deactivate.bat | 22 + .venv/Scripts/flask.exe | Bin 0 -> 107891 bytes .venv/Scripts/normalizer.exe | Bin 0 -> 107916 bytes .venv/Scripts/pip.exe | Bin 0 -> 107904 bytes .venv/Scripts/pip3.10.exe | Bin 0 -> 107904 bytes .venv/Scripts/pip3.exe | Bin 0 -> 107904 bytes .venv/Scripts/python.exe | Bin 0 -> 266624 bytes .venv/Scripts/pythonw.exe | Bin 0 -> 254848 bytes .venv/pyvenv.cfg | 3 + __pycache__/app.cpython-310.pyc | Bin 0 -> 1706 bytes app.py | 52 + requirements.txt | Bin 0 -> 452 bytes static/styles/style.css | 50 + templates/home.html | 73 + 2018 files changed, 370553 insertions(+) create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/_distutils_hack/__init__.py create mode 100644 .venv/Lib/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/_distutils_hack/override.py create mode 100644 .venv/Lib/site-packages/blinker-1.6.3.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/blinker-1.6.3.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/blinker-1.6.3.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/blinker-1.6.3.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/blinker-1.6.3.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/blinker/__init__.py create mode 100644 .venv/Lib/site-packages/blinker/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/blinker/__pycache__/_saferef.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/blinker/__pycache__/base.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/blinker/_saferef.py create mode 100644 .venv/Lib/site-packages/blinker/_utilities.py create mode 100644 .venv/Lib/site-packages/blinker/base.py create mode 100644 .venv/Lib/site-packages/blinker/py.typed create mode 100644 .venv/Lib/site-packages/certifi-2023.7.22.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/certifi-2023.7.22.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/certifi-2023.7.22.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/certifi-2023.7.22.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/certifi-2023.7.22.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/certifi-2023.7.22.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/certifi/__init__.py create mode 100644 .venv/Lib/site-packages/certifi/__main__.py create mode 100644 .venv/Lib/site-packages/certifi/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/certifi/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/certifi/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/certifi/cacert.pem create mode 100644 .venv/Lib/site-packages/certifi/core.py create mode 100644 .venv/Lib/site-packages/certifi/py.typed create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/charset_normalizer/__init__.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/__main__.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/api.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/cd.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/constant.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/md.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/models.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/api.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/cd.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/cli/__init__.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/cli/__main__.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/charset_normalizer/constant.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/legacy.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/md.cp310-win_amd64.pyd create mode 100644 .venv/Lib/site-packages/charset_normalizer/md.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/md__mypyc.cp310-win_amd64.pyd create mode 100644 .venv/Lib/site-packages/charset_normalizer/models.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/py.typed create mode 100644 .venv/Lib/site-packages/charset_normalizer/utils.py create mode 100644 .venv/Lib/site-packages/charset_normalizer/version.py create mode 100644 .venv/Lib/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/click/__init__.py create mode 100644 .venv/Lib/site-packages/click/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/_textwrap.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/_winconsole.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/decorators.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/formatting.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/globals.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/parser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/shell_completion.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/termui.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/testing.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/types.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/click/_compat.py create mode 100644 .venv/Lib/site-packages/click/_termui_impl.py create mode 100644 .venv/Lib/site-packages/click/_textwrap.py create mode 100644 .venv/Lib/site-packages/click/_winconsole.py create mode 100644 .venv/Lib/site-packages/click/core.py create mode 100644 .venv/Lib/site-packages/click/decorators.py create mode 100644 .venv/Lib/site-packages/click/exceptions.py create mode 100644 .venv/Lib/site-packages/click/formatting.py create mode 100644 .venv/Lib/site-packages/click/globals.py create mode 100644 .venv/Lib/site-packages/click/parser.py create mode 100644 .venv/Lib/site-packages/click/py.typed create mode 100644 .venv/Lib/site-packages/click/shell_completion.py create mode 100644 .venv/Lib/site-packages/click/termui.py create mode 100644 .venv/Lib/site-packages/click/testing.py create mode 100644 .venv/Lib/site-packages/click/types.py create mode 100644 .venv/Lib/site-packages/click/utils.py create mode 100644 .venv/Lib/site-packages/colorama-0.4.6.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/colorama-0.4.6.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/colorama-0.4.6.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/colorama-0.4.6.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/colorama-0.4.6.dist-info/licenses/LICENSE.txt create mode 100644 .venv/Lib/site-packages/colorama/__init__.py create mode 100644 .venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/__pycache__/ansitowin32.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/__pycache__/initialise.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/__pycache__/win32.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/ansi.py create mode 100644 .venv/Lib/site-packages/colorama/ansitowin32.py create mode 100644 .venv/Lib/site-packages/colorama/initialise.py create mode 100644 .venv/Lib/site-packages/colorama/tests/__init__.py create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/ansi_test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/ansitowin32_test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/initialise_test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/isatty_test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/__pycache__/winterm_test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/colorama/tests/ansi_test.py create mode 100644 .venv/Lib/site-packages/colorama/tests/ansitowin32_test.py create mode 100644 .venv/Lib/site-packages/colorama/tests/initialise_test.py create mode 100644 .venv/Lib/site-packages/colorama/tests/isatty_test.py create mode 100644 .venv/Lib/site-packages/colorama/tests/utils.py create mode 100644 .venv/Lib/site-packages/colorama/tests/winterm_test.py create mode 100644 .venv/Lib/site-packages/colorama/win32.py create mode 100644 .venv/Lib/site-packages/colorama/winterm.py create mode 100644 .venv/Lib/site-packages/distutils-precedence.pth create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/REQUESTED create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/flask-3.0.0.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/flask/__init__.py create mode 100644 .venv/Lib/site-packages/flask/__main__.py create mode 100644 .venv/Lib/site-packages/flask/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/app.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/blueprints.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/cli.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/config.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/ctx.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/globals.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/helpers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/logging.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/sessions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/signals.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/templating.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/testing.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/typing.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/views.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/__pycache__/wrappers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/app.py create mode 100644 .venv/Lib/site-packages/flask/blueprints.py create mode 100644 .venv/Lib/site-packages/flask/cli.py create mode 100644 .venv/Lib/site-packages/flask/config.py create mode 100644 .venv/Lib/site-packages/flask/ctx.py create mode 100644 .venv/Lib/site-packages/flask/debughelpers.py create mode 100644 .venv/Lib/site-packages/flask/globals.py create mode 100644 .venv/Lib/site-packages/flask/helpers.py create mode 100644 .venv/Lib/site-packages/flask/json/__init__.py create mode 100644 .venv/Lib/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/json/__pycache__/provider.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/json/__pycache__/tag.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/json/provider.py create mode 100644 .venv/Lib/site-packages/flask/json/tag.py create mode 100644 .venv/Lib/site-packages/flask/logging.py create mode 100644 .venv/Lib/site-packages/flask/py.typed create mode 100644 .venv/Lib/site-packages/flask/sansio/README.md create mode 100644 .venv/Lib/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/flask/sansio/app.py create mode 100644 .venv/Lib/site-packages/flask/sansio/blueprints.py create mode 100644 .venv/Lib/site-packages/flask/sansio/scaffold.py create mode 100644 .venv/Lib/site-packages/flask/sessions.py create mode 100644 .venv/Lib/site-packages/flask/signals.py create mode 100644 .venv/Lib/site-packages/flask/templating.py create mode 100644 .venv/Lib/site-packages/flask/testing.py create mode 100644 .venv/Lib/site-packages/flask/typing.py create mode 100644 .venv/Lib/site-packages/flask/views.py create mode 100644 .venv/Lib/site-packages/flask/wrappers.py create mode 100644 .venv/Lib/site-packages/idna-3.4.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/idna-3.4.dist-info/LICENSE.md create mode 100644 .venv/Lib/site-packages/idna-3.4.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/idna-3.4.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/idna-3.4.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/idna/__init__.py create mode 100644 .venv/Lib/site-packages/idna/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/codec.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/intranges.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/package_data.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/__pycache__/uts46data.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/idna/codec.py create mode 100644 .venv/Lib/site-packages/idna/compat.py create mode 100644 .venv/Lib/site-packages/idna/core.py create mode 100644 .venv/Lib/site-packages/idna/idnadata.py create mode 100644 .venv/Lib/site-packages/idna/intranges.py create mode 100644 .venv/Lib/site-packages/idna/package_data.py create mode 100644 .venv/Lib/site-packages/idna/py.typed create mode 100644 .venv/Lib/site-packages/idna/uts46data.py create mode 100644 .venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/itsdangerous/__init__.py create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/_json.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/signer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/itsdangerous/_json.py create mode 100644 .venv/Lib/site-packages/itsdangerous/encoding.py create mode 100644 .venv/Lib/site-packages/itsdangerous/exc.py create mode 100644 .venv/Lib/site-packages/itsdangerous/py.typed create mode 100644 .venv/Lib/site-packages/itsdangerous/serializer.py create mode 100644 .venv/Lib/site-packages/itsdangerous/signer.py create mode 100644 .venv/Lib/site-packages/itsdangerous/timed.py create mode 100644 .venv/Lib/site-packages/itsdangerous/url_safe.py create mode 100644 .venv/Lib/site-packages/jinja2/__init__.py create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/_identifier.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/constants.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/debug.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/environment.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/ext.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/filters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/meta.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/nodes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/parser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/sandbox.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/tests.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/jinja2/_identifier.py create mode 100644 .venv/Lib/site-packages/jinja2/async_utils.py create mode 100644 .venv/Lib/site-packages/jinja2/bccache.py create mode 100644 .venv/Lib/site-packages/jinja2/compiler.py create mode 100644 .venv/Lib/site-packages/jinja2/constants.py create mode 100644 .venv/Lib/site-packages/jinja2/debug.py create mode 100644 .venv/Lib/site-packages/jinja2/defaults.py create mode 100644 .venv/Lib/site-packages/jinja2/environment.py create mode 100644 .venv/Lib/site-packages/jinja2/exceptions.py create mode 100644 .venv/Lib/site-packages/jinja2/ext.py create mode 100644 .venv/Lib/site-packages/jinja2/filters.py create mode 100644 .venv/Lib/site-packages/jinja2/idtracking.py create mode 100644 .venv/Lib/site-packages/jinja2/lexer.py create mode 100644 .venv/Lib/site-packages/jinja2/loaders.py create mode 100644 .venv/Lib/site-packages/jinja2/meta.py create mode 100644 .venv/Lib/site-packages/jinja2/nativetypes.py create mode 100644 .venv/Lib/site-packages/jinja2/nodes.py create mode 100644 .venv/Lib/site-packages/jinja2/optimizer.py create mode 100644 .venv/Lib/site-packages/jinja2/parser.py create mode 100644 .venv/Lib/site-packages/jinja2/py.typed create mode 100644 .venv/Lib/site-packages/jinja2/runtime.py create mode 100644 .venv/Lib/site-packages/jinja2/sandbox.py create mode 100644 .venv/Lib/site-packages/jinja2/tests.py create mode 100644 .venv/Lib/site-packages/jinja2/utils.py create mode 100644 .venv/Lib/site-packages/jinja2/visitor.py create mode 100644 .venv/Lib/site-packages/markupsafe/__init__.py create mode 100644 .venv/Lib/site-packages/markupsafe/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/markupsafe/__pycache__/_native.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/markupsafe/_native.py create mode 100644 .venv/Lib/site-packages/markupsafe/_speedups.c create mode 100644 .venv/Lib/site-packages/markupsafe/_speedups.cp310-win_amd64.pyd create mode 100644 .venv/Lib/site-packages/markupsafe/_speedups.pyi create mode 100644 .venv/Lib/site-packages/markupsafe/py.typed create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/LICENSE.txt create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/REQUESTED create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/pip-22.2.2.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/pip/__init__.py create mode 100644 .venv/Lib/site-packages/pip/__main__.py create mode 100644 .venv/Lib/site-packages/pip/__pip-runner__.py create mode 100644 .venv/Lib/site-packages/pip/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/__pycache__/__pip-runner__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/build_env.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cache.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/base_command.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/command_context.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/main.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/main_parser.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/parser.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/req_command.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/spinners.py create mode 100644 .venv/Lib/site-packages/pip/_internal/cli/status_codes.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/cache.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/check.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/completion.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/configuration.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/debug.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/download.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/freeze.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/hash.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/help.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/index.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/inspect.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/install.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/list.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/search.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/show.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/uninstall.py create mode 100644 .venv/Lib/site-packages/pip/_internal/commands/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/configuration.py create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/base.py create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/installed.py create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/sdist.py create mode 100644 .venv/Lib/site-packages/pip/_internal/distributions/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/exceptions.py create mode 100644 .venv/Lib/site-packages/pip/_internal/index/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/index/collector.py create mode 100644 .venv/Lib/site-packages/pip/_internal/index/package_finder.py create mode 100644 .venv/Lib/site-packages/pip/_internal/index/sources.py create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/_distutils.py create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 .venv/Lib/site-packages/pip/_internal/locations/base.py create mode 100644 .venv/Lib/site-packages/pip/_internal/main.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/_json.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/base.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 .venv/Lib/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/models/candidate.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/direct_url.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/format_control.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/index.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/installation_report.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/link.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/scheme.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/search_scope.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/target_python.py create mode 100644 .venv/Lib/site-packages/pip/_internal/models/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/network/auth.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/cache.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/download.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/session.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/utils.py create mode 100644 .venv/Lib/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/check.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/freeze.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/operations/prepare.py create mode 100644 .venv/Lib/site-packages/pip/_internal/pyproject.py create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/req/constructors.py create mode 100644 .venv/Lib/site-packages/pip/_internal/req/req_file.py create mode 100644 .venv/Lib/site-packages/pip/_internal/req/req_install.py create mode 100644 .venv/Lib/site-packages/pip/_internal/req/req_set.py create mode 100644 .venv/Lib/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/base.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 .venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 .venv/Lib/site-packages/pip/_internal/self_outdated_check.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/_log.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/appdirs.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/compat.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/datetime.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/deprecation.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/egg_link.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/encoding.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/filesystem.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/filetypes.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/glibc.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/hashes.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/logging.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/misc.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/models.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/packaging.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/subprocess.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/unpacking.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/urls.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 .venv/Lib/site-packages/pip/_internal/utils/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/git.py create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/subversion.py create mode 100644 .venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 .venv/Lib/site-packages/pip/_internal/wheel_builder.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/__pycache__/six.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 .venv/Lib/site-packages/pip/_vendor/certifi/core.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/enums.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/johabfreq.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/johabprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/utf1632prober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/chardet/version.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/win32.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/compat.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/database.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/index.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/locators.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/markers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/resources.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/t64-arm.exe create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/util.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/version.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/w64-arm.exe create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 .venv/Lib/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distro/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distro/__main__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/distro/distro.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/codec.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/compat.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/core.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/intranges.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/package_data.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/markers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/tags.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/utils.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/packaging/version.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/build.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/check.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/compat.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/dirtools.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/in_process/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/in_process/_in_process.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/meta.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/console.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/filter.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/style.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/token.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pygments/util.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/help.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/__version__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/adapters.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/api.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/auth.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/certs.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/compat.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/cookies.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/help.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/hooks.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/models.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/packages.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/sessions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/structures.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/requests/utils.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__main__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/json.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/status.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_export_format.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_extension.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_loop.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_pick.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_stack.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_timer.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_windows.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/abc.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/align.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/ansi.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/bar.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/box.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/cells.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/color.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/columns.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/console.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/constrain.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/containers.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/control.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/emoji.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/errors.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/filesize.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/json.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/layout.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/live.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/live_render.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/logging.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/markup.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/measure.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/padding.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/pager.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/palette.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/panel.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/pretty.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/progress.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/prompt.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/protocol.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/region.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/repr.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/rule.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/scope.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/screen.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/segment.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/spinner.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/status.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/style.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/styled.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/syntax.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/table.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/text.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/theme.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/themes.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/traceback.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/rich/tree.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/six.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/after.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/before.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/_re.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/tomli/_types.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/typing_extensions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/request.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/response.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/vendor.txt create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 .venv/Lib/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 .venv/Lib/site-packages/pip/py.typed create mode 100644 .venv/Lib/site-packages/pkg_resources/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/__pycache__/zipp.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_adapters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_common.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_itertools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/_legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/abc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/readers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__pycache__/simple.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_adapters.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_common.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_compat.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_itertools.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_legacy.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/abc.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/readers.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/simple.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/__pycache__/context.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/__pycache__/functools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/context.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/functools.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/text/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/jaraco/text/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/more.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/__pycache__/recipes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/more.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/recipes.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/_manylinux.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/_musllinux.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/actions.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/common.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/core.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/diagram/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/exceptions.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/helpers.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/results.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/testing.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/unicode.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/util.py create mode 100644 .venv/Lib/site-packages/pkg_resources/_vendor/zipp.py create mode 100644 .venv/Lib/site-packages/pkg_resources/extern/__init__.py create mode 100644 .venv/Lib/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/REQUESTED create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/requests-2.31.0.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/requests/__init__.py create mode 100644 .venv/Lib/site-packages/requests/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/__version__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/_internal_utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/adapters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/api.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/auth.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/certs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/cookies.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/help.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/hooks.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/models.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/packages.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/sessions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/status_codes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/structures.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/requests/__version__.py create mode 100644 .venv/Lib/site-packages/requests/_internal_utils.py create mode 100644 .venv/Lib/site-packages/requests/adapters.py create mode 100644 .venv/Lib/site-packages/requests/api.py create mode 100644 .venv/Lib/site-packages/requests/auth.py create mode 100644 .venv/Lib/site-packages/requests/certs.py create mode 100644 .venv/Lib/site-packages/requests/compat.py create mode 100644 .venv/Lib/site-packages/requests/cookies.py create mode 100644 .venv/Lib/site-packages/requests/exceptions.py create mode 100644 .venv/Lib/site-packages/requests/help.py create mode 100644 .venv/Lib/site-packages/requests/hooks.py create mode 100644 .venv/Lib/site-packages/requests/models.py create mode 100644 .venv/Lib/site-packages/requests/packages.py create mode 100644 .venv/Lib/site-packages/requests/sessions.py create mode 100644 .venv/Lib/site-packages/requests/status_codes.py create mode 100644 .venv/Lib/site-packages/requests/structures.py create mode 100644 .venv/Lib/site-packages/requests/utils.py create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/REQUESTED create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/setuptools-63.2.0.dist-info/top_level.txt create mode 100644 .venv/Lib/site-packages/setuptools/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_entry_points.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_imp.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_importlib.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_itertools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_path.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/_reqs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/archive_util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/build_meta.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/dep_util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/depends.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/discovery.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/dist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/errors.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/extension.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/glob.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/installer.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/launch.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/logging.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/monkey.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/msvc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/namespaces.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/package_index.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/py34compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/sandbox.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/wheel.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/__pycache__/windows_support.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_deprecation_warning.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/_collections.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/_functools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/_macos_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/config.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/debug.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/dist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/errors.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/extension.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/log.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/py39compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/_collections.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/_functools.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/_macos_compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/archive_util.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/cmd.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/_framework_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/_framework_compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/bdist_msi.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/bdist_wininst.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/build.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/check.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/clean.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/config.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/install.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/register.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/command/upload.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/config.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/core.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/debug.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/dep_util.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/dir_util.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/dist.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/errors.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/extension.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/file_util.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/filelist.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/log.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/py38compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/py39compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/spawn.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/text_file.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/util.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/version.py create mode 100644 .venv/Lib/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 .venv/Lib/site-packages/setuptools/_entry_points.py create mode 100644 .venv/Lib/site-packages/setuptools/_imp.py create mode 100644 .venv/Lib/site-packages/setuptools/_importlib.py create mode 100644 .venv/Lib/site-packages/setuptools/_itertools.py create mode 100644 .venv/Lib/site-packages/setuptools/_path.py create mode 100644 .venv/Lib/site-packages/setuptools/_reqs.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/__pycache__/typing_extensions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/__pycache__/zipp.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_adapters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_collections.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_functools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_itertools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_meta.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__pycache__/_text.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_adapters.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_collections.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_functools.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_itertools.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_meta.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_text.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_adapters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_common.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_itertools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/_legacy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/abc.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/readers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__pycache__/simple.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_adapters.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_common.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_compat.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_itertools.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_legacy.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/abc.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/readers.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/importlib_resources/simple.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/__pycache__/context.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/__pycache__/functools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/context.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/functools.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/text/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/jaraco/text/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/more_itertools/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/more_itertools/more.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/more_itertools/recipes.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/_manylinux.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/_musllinux.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/actions.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/common.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/core.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/diagram/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/exceptions.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/helpers.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/results.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/testing.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/unicode.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/pyparsing/util.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/__pycache__/_parser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/__pycache__/_re.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/__pycache__/_types.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/_parser.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/_re.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/tomli/_types.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/typing_extensions.py create mode 100644 .venv/Lib/site-packages/setuptools/_vendor/zipp.py create mode 100644 .venv/Lib/site-packages/setuptools/archive_util.py create mode 100644 .venv/Lib/site-packages/setuptools/build_meta.py create mode 100644 .venv/Lib/site-packages/setuptools/cli-32.exe create mode 100644 .venv/Lib/site-packages/setuptools/cli-64.exe create mode 100644 .venv/Lib/site-packages/setuptools/cli-arm64.exe create mode 100644 .venv/Lib/site-packages/setuptools/cli.exe create mode 100644 .venv/Lib/site-packages/setuptools/command/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/alias.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/build.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/build_py.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/develop.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/dist_info.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/easy_install.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/egg_info.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/install.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/py36compat.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/register.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/rotate.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/saveopts.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/sdist.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/setopt.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/upload.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/__pycache__/upload_docs.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/command/alias.py create mode 100644 .venv/Lib/site-packages/setuptools/command/bdist_egg.py create mode 100644 .venv/Lib/site-packages/setuptools/command/bdist_rpm.py create mode 100644 .venv/Lib/site-packages/setuptools/command/build.py create mode 100644 .venv/Lib/site-packages/setuptools/command/build_clib.py create mode 100644 .venv/Lib/site-packages/setuptools/command/build_ext.py create mode 100644 .venv/Lib/site-packages/setuptools/command/build_py.py create mode 100644 .venv/Lib/site-packages/setuptools/command/develop.py create mode 100644 .venv/Lib/site-packages/setuptools/command/dist_info.py create mode 100644 .venv/Lib/site-packages/setuptools/command/easy_install.py create mode 100644 .venv/Lib/site-packages/setuptools/command/egg_info.py create mode 100644 .venv/Lib/site-packages/setuptools/command/install.py create mode 100644 .venv/Lib/site-packages/setuptools/command/install_egg_info.py create mode 100644 .venv/Lib/site-packages/setuptools/command/install_lib.py create mode 100644 .venv/Lib/site-packages/setuptools/command/install_scripts.py create mode 100644 .venv/Lib/site-packages/setuptools/command/launcher manifest.xml create mode 100644 .venv/Lib/site-packages/setuptools/command/py36compat.py create mode 100644 .venv/Lib/site-packages/setuptools/command/register.py create mode 100644 .venv/Lib/site-packages/setuptools/command/rotate.py create mode 100644 .venv/Lib/site-packages/setuptools/command/saveopts.py create mode 100644 .venv/Lib/site-packages/setuptools/command/sdist.py create mode 100644 .venv/Lib/site-packages/setuptools/command/setopt.py create mode 100644 .venv/Lib/site-packages/setuptools/command/test.py create mode 100644 .venv/Lib/site-packages/setuptools/command/upload.py create mode 100644 .venv/Lib/site-packages/setuptools/command/upload_docs.py create mode 100644 .venv/Lib/site-packages/setuptools/config/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/config/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/__pycache__/_apply_pyprojecttoml.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/__pycache__/expand.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/__pycache__/pyprojecttoml.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/__pycache__/setupcfg.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_apply_pyprojecttoml.py create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__pycache__/error_reporting.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__pycache__/extra_validations.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_validations.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/__pycache__/formats.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/error_reporting.py create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/extra_validations.py create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_validations.py create mode 100644 .venv/Lib/site-packages/setuptools/config/_validate_pyproject/formats.py create mode 100644 .venv/Lib/site-packages/setuptools/config/expand.py create mode 100644 .venv/Lib/site-packages/setuptools/config/pyprojecttoml.py create mode 100644 .venv/Lib/site-packages/setuptools/config/setupcfg.py create mode 100644 .venv/Lib/site-packages/setuptools/dep_util.py create mode 100644 .venv/Lib/site-packages/setuptools/depends.py create mode 100644 .venv/Lib/site-packages/setuptools/discovery.py create mode 100644 .venv/Lib/site-packages/setuptools/dist.py create mode 100644 .venv/Lib/site-packages/setuptools/errors.py create mode 100644 .venv/Lib/site-packages/setuptools/extension.py create mode 100644 .venv/Lib/site-packages/setuptools/extern/__init__.py create mode 100644 .venv/Lib/site-packages/setuptools/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/setuptools/glob.py create mode 100644 .venv/Lib/site-packages/setuptools/gui-32.exe create mode 100644 .venv/Lib/site-packages/setuptools/gui-64.exe create mode 100644 .venv/Lib/site-packages/setuptools/gui-arm64.exe create mode 100644 .venv/Lib/site-packages/setuptools/gui.exe create mode 100644 .venv/Lib/site-packages/setuptools/installer.py create mode 100644 .venv/Lib/site-packages/setuptools/launch.py create mode 100644 .venv/Lib/site-packages/setuptools/logging.py create mode 100644 .venv/Lib/site-packages/setuptools/monkey.py create mode 100644 .venv/Lib/site-packages/setuptools/msvc.py create mode 100644 .venv/Lib/site-packages/setuptools/namespaces.py create mode 100644 .venv/Lib/site-packages/setuptools/package_index.py create mode 100644 .venv/Lib/site-packages/setuptools/py34compat.py create mode 100644 .venv/Lib/site-packages/setuptools/sandbox.py create mode 100644 .venv/Lib/site-packages/setuptools/script (dev).tmpl create mode 100644 .venv/Lib/site-packages/setuptools/script.tmpl create mode 100644 .venv/Lib/site-packages/setuptools/unicode_utils.py create mode 100644 .venv/Lib/site-packages/setuptools/version.py create mode 100644 .venv/Lib/site-packages/setuptools/wheel.py create mode 100644 .venv/Lib/site-packages/setuptools/windows_support.py create mode 100644 .venv/Lib/site-packages/urllib3-2.0.7.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/urllib3-2.0.7.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/urllib3-2.0.7.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/urllib3-2.0.7.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/urllib3-2.0.7.dist-info/licenses/LICENSE.txt create mode 100644 .venv/Lib/site-packages/urllib3/__init__.py create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/_base_connection.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/_collections.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/_request_methods.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/_version.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/connection.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/connectionpool.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/fields.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/filepost.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/poolmanager.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/__pycache__/response.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/_base_connection.py create mode 100644 .venv/Lib/site-packages/urllib3/_collections.py create mode 100644 .venv/Lib/site-packages/urllib3/_request_methods.py create mode 100644 .venv/Lib/site-packages/urllib3/_version.py create mode 100644 .venv/Lib/site-packages/urllib3/connection.py create mode 100644 .venv/Lib/site-packages/urllib3/connectionpool.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/__init__.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/__pycache__/socks.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/_securetransport/__init__.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/contrib/_securetransport/bindings.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/_securetransport/low_level.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/pyopenssl.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/securetransport.py create mode 100644 .venv/Lib/site-packages/urllib3/contrib/socks.py create mode 100644 .venv/Lib/site-packages/urllib3/exceptions.py create mode 100644 .venv/Lib/site-packages/urllib3/fields.py create mode 100644 .venv/Lib/site-packages/urllib3/filepost.py create mode 100644 .venv/Lib/site-packages/urllib3/poolmanager.py create mode 100644 .venv/Lib/site-packages/urllib3/py.typed create mode 100644 .venv/Lib/site-packages/urllib3/response.py create mode 100644 .venv/Lib/site-packages/urllib3/util/__init__.py create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/connection.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/proxy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/request.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/response.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/retry.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/ssl_.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/ssltransport.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/timeout.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/url.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/util.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/__pycache__/wait.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/urllib3/util/connection.py create mode 100644 .venv/Lib/site-packages/urllib3/util/proxy.py create mode 100644 .venv/Lib/site-packages/urllib3/util/request.py create mode 100644 .venv/Lib/site-packages/urllib3/util/response.py create mode 100644 .venv/Lib/site-packages/urllib3/util/retry.py create mode 100644 .venv/Lib/site-packages/urllib3/util/ssl_.py create mode 100644 .venv/Lib/site-packages/urllib3/util/ssl_match_hostname.py create mode 100644 .venv/Lib/site-packages/urllib3/util/ssltransport.py create mode 100644 .venv/Lib/site-packages/urllib3/util/timeout.py create mode 100644 .venv/Lib/site-packages/urllib3/util/url.py create mode 100644 .venv/Lib/site-packages/urllib3/util/util.py create mode 100644 .venv/Lib/site-packages/urllib3/util/wait.py create mode 100644 .venv/Lib/site-packages/werkzeug-3.0.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/werkzeug-3.0.0.dist-info/LICENSE.rst create mode 100644 .venv/Lib/site-packages/werkzeug-3.0.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/werkzeug-3.0.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/werkzeug-3.0.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/werkzeug/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/_internal.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/_reloader.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/formparser.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/http.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/local.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/security.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/serving.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/test.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/testapp.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/urls.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/user_agent.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/__pycache__/wsgi.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/_internal.py create mode 100644 .venv/Lib/site-packages/werkzeug/_reloader.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/range.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/accept.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/accept.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/auth.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/cache_control.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/csp.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/csp.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/etag.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/etag.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/file_storage.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/headers.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/headers.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/mixins.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/mixins.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/range.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/range.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/structures.py create mode 100644 .venv/Lib/site-packages/werkzeug/datastructures/structures.pyi create mode 100644 .venv/Lib/site-packages/werkzeug/debug/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/debug/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/debug/__pycache__/console.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/debug/__pycache__/repr.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/debug/console.py create mode 100644 .venv/Lib/site-packages/werkzeug/debug/repr.py create mode 100644 .venv/Lib/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 .venv/Lib/site-packages/werkzeug/debug/shared/console.png create mode 100644 .venv/Lib/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 .venv/Lib/site-packages/werkzeug/debug/shared/less.png create mode 100644 .venv/Lib/site-packages/werkzeug/debug/shared/more.png create mode 100644 .venv/Lib/site-packages/werkzeug/debug/shared/style.css create mode 100644 .venv/Lib/site-packages/werkzeug/debug/tbtools.py create mode 100644 .venv/Lib/site-packages/werkzeug/exceptions.py create mode 100644 .venv/Lib/site-packages/werkzeug/formparser.py create mode 100644 .venv/Lib/site-packages/werkzeug/http.py create mode 100644 .venv/Lib/site-packages/werkzeug/local.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/lint.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/lint.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/profiler.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 .venv/Lib/site-packages/werkzeug/middleware/shared_data.py create mode 100644 .venv/Lib/site-packages/werkzeug/py.typed create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__pycache__/converters.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__pycache__/map.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__pycache__/matcher.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/routing/__pycache__/rules.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/routing/converters.py create mode 100644 .venv/Lib/site-packages/werkzeug/routing/exceptions.py create mode 100644 .venv/Lib/site-packages/werkzeug/routing/map.py create mode 100644 .venv/Lib/site-packages/werkzeug/routing/matcher.py create mode 100644 .venv/Lib/site-packages/werkzeug/routing/rules.py create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__pycache__/http.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__pycache__/request.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__pycache__/response.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/__pycache__/utils.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/http.py create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/multipart.py create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/request.py create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/response.py create mode 100644 .venv/Lib/site-packages/werkzeug/sansio/utils.py create mode 100644 .venv/Lib/site-packages/werkzeug/security.py create mode 100644 .venv/Lib/site-packages/werkzeug/serving.py create mode 100644 .venv/Lib/site-packages/werkzeug/test.py create mode 100644 .venv/Lib/site-packages/werkzeug/testapp.py create mode 100644 .venv/Lib/site-packages/werkzeug/urls.py create mode 100644 .venv/Lib/site-packages/werkzeug/user_agent.py create mode 100644 .venv/Lib/site-packages/werkzeug/utils.py create mode 100644 .venv/Lib/site-packages/werkzeug/wrappers/__init__.py create mode 100644 .venv/Lib/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/wrappers/__pycache__/request.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/wrappers/__pycache__/response.cpython-310.pyc create mode 100644 .venv/Lib/site-packages/werkzeug/wrappers/request.py create mode 100644 .venv/Lib/site-packages/werkzeug/wrappers/response.py create mode 100644 .venv/Lib/site-packages/werkzeug/wsgi.py create mode 100644 .venv/Scripts/Activate.ps1 create mode 100644 .venv/Scripts/activate create mode 100644 .venv/Scripts/activate.bat create mode 100644 .venv/Scripts/deactivate.bat create mode 100644 .venv/Scripts/flask.exe create mode 100644 .venv/Scripts/normalizer.exe create mode 100644 .venv/Scripts/pip.exe create mode 100644 .venv/Scripts/pip3.10.exe create mode 100644 .venv/Scripts/pip3.exe create mode 100644 .venv/Scripts/python.exe create mode 100644 .venv/Scripts/pythonw.exe create mode 100644 .venv/pyvenv.cfg create mode 100644 __pycache__/app.cpython-310.pyc create mode 100644 app.py create mode 100644 requirements.txt create mode 100644 static/styles/style.css create mode 100644 templates/home.html diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/INSTALLER b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA new file mode 100644 index 0000000..f54bb5c --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/METADATA @@ -0,0 +1,113 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.2 +Summary: A very fast and expressive template engine. +Home-page: https://palletsprojects.com/p/jinja/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/jinja/ +Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: MarkupSafe (>=2.0) +Provides-Extra: i18n +Requires-Dist: Babel (>=2.7) ; extra == 'i18n' + +Jinja +===== + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Jinja2 + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +In A Nutshell +------------- + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +Donate +------ + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://jinja.palletsprojects.com/ +- Changes: https://jinja.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Jinja2/ +- Source Code: https://github.com/pallets/jinja/ +- Issue Tracker: https://github.com/pallets/jinja/issues/ +- Website: https://palletsprojects.com/p/jinja/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD new file mode 100644 index 0000000..af42ee3 --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/RECORD @@ -0,0 +1,58 @@ +Jinja2-3.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-3.1.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Jinja2-3.1.2.dist-info/METADATA,sha256=PZ6v2SIidMNixR7MRUX9f7ZWsPwtXanknqiZUmRbh4U,3539 +Jinja2-3.1.2.dist-info/RECORD,, +Jinja2-3.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Jinja2-3.1.2.dist-info/entry_points.txt,sha256=zRd62fbqIyfUpsRtU7EVIFyiu1tPwfgO7EvPErnxgTE,59 +Jinja2-3.1.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=8vGduD8ytwgD6GDSqpYc2m3aU-T7PKOAddvVXgGr_Fs,1927 +jinja2/__pycache__/__init__.cpython-310.pyc,, +jinja2/__pycache__/_identifier.cpython-310.pyc,, +jinja2/__pycache__/async_utils.cpython-310.pyc,, +jinja2/__pycache__/bccache.cpython-310.pyc,, +jinja2/__pycache__/compiler.cpython-310.pyc,, +jinja2/__pycache__/constants.cpython-310.pyc,, +jinja2/__pycache__/debug.cpython-310.pyc,, +jinja2/__pycache__/defaults.cpython-310.pyc,, +jinja2/__pycache__/environment.cpython-310.pyc,, +jinja2/__pycache__/exceptions.cpython-310.pyc,, +jinja2/__pycache__/ext.cpython-310.pyc,, +jinja2/__pycache__/filters.cpython-310.pyc,, +jinja2/__pycache__/idtracking.cpython-310.pyc,, +jinja2/__pycache__/lexer.cpython-310.pyc,, +jinja2/__pycache__/loaders.cpython-310.pyc,, +jinja2/__pycache__/meta.cpython-310.pyc,, +jinja2/__pycache__/nativetypes.cpython-310.pyc,, +jinja2/__pycache__/nodes.cpython-310.pyc,, +jinja2/__pycache__/optimizer.cpython-310.pyc,, +jinja2/__pycache__/parser.cpython-310.pyc,, +jinja2/__pycache__/runtime.cpython-310.pyc,, +jinja2/__pycache__/sandbox.cpython-310.pyc,, +jinja2/__pycache__/tests.cpython-310.pyc,, +jinja2/__pycache__/utils.cpython-310.pyc,, +jinja2/__pycache__/visitor.cpython-310.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=dHlbTeaxFPtAOQEYOGYh_PHcDT0rsDaUJAFDl_0XtTg,2472 +jinja2/bccache.py,sha256=mhz5xtLxCcHRAa56azOhphIAe19u1we0ojifNMClDio,14061 +jinja2/compiler.py,sha256=Gs-N8ThJ7OWK4-reKoO8Wh1ZXz95MVphBKNVf75qBr8,72172 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=6uHIcc7ZblqOMdx_uYNKqRnnwAF0_nzbyeMP9FFtuh4,61349 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=ivr3P7LKbddiXDVez20EflcO3q2aHQwz9P_PgWGHVqE,31502 +jinja2/filters.py,sha256=9js1V-h2RlyW90IhLiBGLM2U-k6SCy2F4BUUMgB3K9Q,53509 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=DW2nX9zk-6MWp65YR2bqqj0xqCvLtD-u9NWT8AnFRxQ,29726 +jinja2/loaders.py,sha256=BfptfvTVpClUd-leMkHczdyPNYFzp_n7PKOJ98iyHOg,23207 +jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 +jinja2/nativetypes.py,sha256=DXgORDPRmVWgy034H0xL8eF7qYoK3DrMxs-935d0Fzk,4226 +jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550 +jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 +jinja2/parser.py,sha256=nHd-DFHbiygvfaPtm9rcQXJChZG7DPsWfiEsqfwKerY,39595 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=5CmD5BjbEJxSiDNTFBeKCaq8qU4aYD2v6q2EluyExms,33476 +jinja2/sandbox.py,sha256=Y0xZeXQnH6EX5VjaV2YixESxoepnRbW_3UeQosaBU3M,14584 +jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 +jinja2/utils.py,sha256=u9jXESxGn8ATZNVolwmkjUVu4SA-tLgV0W7PcSfPfdQ,23965 +jinja2/visitor.py,sha256=MH14C6yq24G_KVtWzjwaI7Wg14PCJIYlWW1kpkxYak0,3568 diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt new file mode 100644 index 0000000..7b9666c --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[babel.extractors] +jinja2 = jinja2.ext:babel_extract[i18n] diff --git a/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/.venv/Lib/site-packages/Jinja2-3.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/METADATA b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/METADATA new file mode 100644 index 0000000..bced165 --- /dev/null +++ b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/METADATA @@ -0,0 +1,93 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.3 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/markupsafe/ +Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + + >>> # escape replaces special characters and wraps in Markup + >>> escape("") + Markup('<script>alert(document.cookie);</script>') + + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup("Hello") + Markup('hello') + + >>> escape(Markup("Hello")) + Markup('hello') + + >>> # Markup is a str subclass + >>> # methods and operators escape their arguments + >>> template = Markup("Hello {name}") + >>> template.format(name='"World"') + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://markupsafe.palletsprojects.com/ +- Changes: https://markupsafe.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/MarkupSafe/ +- Source Code: https://github.com/pallets/markupsafe/ +- Issue Tracker: https://github.com/pallets/markupsafe/issues/ +- Chat: https://discord.gg/pallets diff --git a/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/RECORD b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/RECORD new file mode 100644 index 0000000..c62bb43 --- /dev/null +++ b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.3.dist-info/LICENSE.rst,sha256=RjHsDbX9kKVH4zaBcmTGeYIUM4FG-KyUtKV_lu6MnsQ,1503 +MarkupSafe-2.1.3.dist-info/METADATA,sha256=5gU_TQw6eHpTaqkI6SPeZje6KTPlJPAV82uNiL3naKE,3096 +MarkupSafe-2.1.3.dist-info/RECORD,, +MarkupSafe-2.1.3.dist-info/WHEEL,sha256=jrOhEbqKwvzRFSJcbYXlJCyVkgVdHg4_7__YHrdTUfw,102 +MarkupSafe-2.1.3.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=GsRaSTjrhvg6c88PnPJNqm4MafU_mFatfXz4-h80-Qc,10642 +markupsafe/__pycache__/__init__.cpython-310.pyc,, +markupsafe/__pycache__/_native.cpython-310.pyc,, +markupsafe/_native.py,sha256=_Q7UsXCOvgdonCgqG3l5asANI6eo50EKnDM-mlwEC5M,1776 +markupsafe/_speedups.c,sha256=n3jzzaJwXcoN8nTFyA53f3vSqsWK2vujI-v6QYifjhQ,7403 +markupsafe/_speedups.cp310-win_amd64.pyd,sha256=nlgDO0l-guuFD-w6o7YZey0yek5iNTBpKjJrVebhZpI,15872 +markupsafe/_speedups.pyi,sha256=f5QtwIOP0eLrxh2v5p6SmaYmlcHIGIfmz0DovaqL0OU,238 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL new file mode 100644 index 0000000..b30c5d9 --- /dev/null +++ b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.40.0) +Root-Is-Purelib: false +Tag: cp310-cp310-win_amd64 + diff --git a/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/.venv/Lib/site-packages/MarkupSafe-2.1.3.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/.venv/Lib/site-packages/_distutils_hack/__init__.py b/.venv/Lib/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..f987a53 --- /dev/null +++ b/.venv/Lib/site-packages/_distutils_hack/__init__.py @@ -0,0 +1,222 @@ +# don't import any costly modules +import sys +import os + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +def warn_distutils_present(): + if 'distutils' not in sys.modules: + return + if is_pypy and sys.version_info < (3, 7): + # PyPy for 3.6 unconditionally imports distutils, so bypass the warning + # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250 + return + import warnings + + warnings.warn( + "Distutils was imported before Setuptools, but importing Setuptools " + "also replaces the `distutils` module in `sys.modules`. This may lead " + "to undesirable behaviors or errors. To avoid these issues, avoid " + "using distutils directly, ensure that setuptools is installed in the " + "traditional way (e.g. not an editable install), and/or make sure " + "that setuptools is always imported before distutils." + ) + + +def clear_distutils(): + if 'distutils' not in sys.modules: + return + import warnings + + warnings.warn("Setuptools is replacing distutils.") + mods = [ + name + for name in sys.modules + if name == "distutils" or name.startswith("distutils.") + ] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local') + return which == 'local' + + +def ensure_local_distutils(): + import importlib + + clear_distutils() + + # With the DistutilsMetaFinder in place, + # perform an import to cause distutils to be + # loaded from setuptools._distutils. Ref #2906. + with shim(): + importlib.import_module('distutils') + + # check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + assert 'setuptools._distutils.log' not in sys.modules + + +def do_override(): + """ + Ensure that the local copy of distutils is preferred over stdlib. + + See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 + for more motivation. + """ + if enabled(): + warn_distutils_present() + ensure_local_distutils() + + +class _TrivialRe: + def __init__(self, *patterns): + self._patterns = patterns + + def match(self, string): + return all(pat in string for pat in self._patterns) + + +class DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + # optimization: only consider top level modules and those + # found in the CPython test suite. + if path is not None and not fullname.startswith('test.'): + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + if self.is_cpython(): + return + + import importlib + import importlib.abc + import importlib.util + + try: + mod = importlib.import_module('setuptools._distutils') + except Exception: + # There are a couple of cases where setuptools._distutils + # may not be present: + # - An older Setuptools without a local distutils is + # taking precedence. Ref #2957. + # - Path manipulation during sitecustomize removes + # setuptools from the path but only after the hook + # has been loaded. Ref #2980. + # In either case, fall back to stdlib behavior. + return + + class DistutilsLoader(importlib.abc.Loader): + def create_module(self, spec): + mod.__name__ = 'distutils' + return mod + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader( + 'distutils', DistutilsLoader(), origin=mod.__file__ + ) + + @staticmethod + def is_cpython(): + """ + Suppress supplying distutils for CPython (build and tests). + Ref #2965 and #3007. + """ + return os.path.isfile('pybuilddir.txt') + + def spec_for_pip(self): + """ + Ensure stdlib distutils when running under pip. + See pypa/pip#8761 for rationale. + """ + if self.pip_imported_during_build(): + return + clear_distutils() + self.spec_for_distutils = lambda: None + + @classmethod + def pip_imported_during_build(cls): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + + return any( + cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None) + ) + + @staticmethod + def frame_file_is_setup(frame): + """ + Return True if the indicated frame suggests a setup.py file. + """ + # some frames may not have __file__ (#2940) + return frame.f_globals.get('__file__', '').endswith('setup.py') + + def spec_for_sensitive_tests(self): + """ + Ensure stdlib distutils when running select tests under CPython. + + python/cpython#91169 + """ + clear_distutils() + self.spec_for_distutils = lambda: None + + sensitive_tests = ( + [ + 'test.test_distutils', + 'test.test_peg_generator', + 'test.test_importlib', + ] + if sys.version_info < (3, 10) + else [ + 'test.test_distutils', + ] + ) + + +for name in DistutilsMetaFinder.sensitive_tests: + setattr( + DistutilsMetaFinder, + f'spec_for_{name}', + DistutilsMetaFinder.spec_for_sensitive_tests, + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + DISTUTILS_FINDER in sys.meta_path or insert_shim() + + +class shim: + def __enter__(self): + insert_shim() + + def __exit__(self, exc, value, tb): + remove_shim() + + +def insert_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass diff --git a/.venv/Lib/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a316eaa2936cd786fe5cf8dff56628ea60ac10f GIT binary patch literal 7581 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 Dr4}2c literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc b/.venv/Lib/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72612cb89385d93871a2a86ae196d86e94f00029 GIT binary patch literal 228 zcmd1j<>g`kg8mA_R2?Aw7{oyaOhAqU5ElyoiByIZhGxbEj0+hU8B!R788n%q_~TPD zi%UvNGINUKGZK@t{WO_wamB}H<`(1^mBhzKai`?R=a;1x6=kNRu4E_z83!hQg*aQq zgche36~`3k<(H?#I0qY>8OAu578RxDC09BY6vXJ2rRJ5z_+%!<6la#C>J|V^PfSlO gjzP0gA7;E>LFFwDo80`A(wtN~Mv$99wh1r*0Ey~A2mk;8 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/_distutils_hack/override.py b/.venv/Lib/site-packages/_distutils_hack/override.py new file mode 100644 index 0000000..2cc433a --- /dev/null +++ b/.venv/Lib/site-packages/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/.venv/Lib/site-packages/blinker-1.6.3.dist-info/INSTALLER b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/blinker-1.6.3.dist-info/LICENSE.rst b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/LICENSE.rst new file mode 100644 index 0000000..79c9825 --- /dev/null +++ b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/LICENSE.rst @@ -0,0 +1,20 @@ +Copyright 2010 Jason Kirtland + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/.venv/Lib/site-packages/blinker-1.6.3.dist-info/METADATA b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/METADATA new file mode 100644 index 0000000..91e090f --- /dev/null +++ b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/METADATA @@ -0,0 +1,62 @@ +Metadata-Version: 2.1 +Name: blinker +Version: 1.6.3 +Summary: Fast, simple object-to-object and broadcast signaling +Keywords: signal,emit,events,broadcast +Author-email: Jason Kirtland +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Software Development :: Libraries +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Homepage, https://blinker.readthedocs.io +Project-URL: Issue Tracker, https://github.com/pallets-eco/blinker/issues/ +Project-URL: Source Code, https://github.com/pallets-eco/blinker/ + +Blinker +======= + +Blinker provides a fast dispatching system that allows any number of +interested parties to subscribe to events, or "signals". + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +.. code-block:: pycon + + >>> from blinker import signal + >>> started = signal('round-started') + >>> def each(round): + ... print(f"Round {round}") + ... + >>> started.connect(each) + + >>> def round_two(round): + ... print("This is round two.") + ... + >>> started.connect(round_two, sender=2) + + >>> for round in range(1, 4): + ... started.send(round) + ... + Round 1! + Round 2! + This is round two. + Round 3! + + +Links +----- + +- Documentation: https://blinker.readthedocs.io/ +- Changes: https://blinker.readthedocs.io/#changes +- PyPI Releases: https://pypi.org/project/blinker/ +- Source Code: https://github.com/pallets-eco/blinker/ +- Issue Tracker: https://github.com/pallets-eco/blinker/issues/ + diff --git a/.venv/Lib/site-packages/blinker-1.6.3.dist-info/RECORD b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/RECORD new file mode 100644 index 0000000..386c90d --- /dev/null +++ b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/RECORD @@ -0,0 +1,14 @@ +blinker-1.6.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.6.3.dist-info/LICENSE.rst,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.6.3.dist-info/METADATA,sha256=yDLuXpi6nLMwYYWJlGDIBvbZxFZH23JHbdxPGzIU4vg,1918 +blinker-1.6.3.dist-info/RECORD,, +blinker-1.6.3.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +blinker/__init__.py,sha256=E7dbyl7JyaK4RbWHlGrWY3mQ8d3BEnxRCeKQnqMa0bw,408 +blinker/__pycache__/__init__.cpython-310.pyc,, +blinker/__pycache__/_saferef.cpython-310.pyc,, +blinker/__pycache__/_utilities.cpython-310.pyc,, +blinker/__pycache__/base.cpython-310.pyc,, +blinker/_saferef.py,sha256=kWOTIWnCY3kOb8lZP74Rbx7bR_BLVg4TjwzNCRLhKHs,9096 +blinker/_utilities.py,sha256=GPXtJzykzVotoxHC79mgFQMPJtICwpVDCCpus4_JtsA,4110 +blinker/base.py,sha256=ZfN6L36P0BzPaQAcAF0tSNAicxiG4f7xLPug6iLsjjE,20293 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/Lib/site-packages/blinker-1.6.3.dist-info/WHEEL b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/.venv/Lib/site-packages/blinker-1.6.3.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/blinker/__init__.py b/.venv/Lib/site-packages/blinker/__init__.py new file mode 100644 index 0000000..0d7a6bc --- /dev/null +++ b/.venv/Lib/site-packages/blinker/__init__.py @@ -0,0 +1,19 @@ +from blinker.base import ANY +from blinker.base import NamedSignal +from blinker.base import Namespace +from blinker.base import receiver_connected +from blinker.base import Signal +from blinker.base import signal +from blinker.base import WeakNamespace + +__all__ = [ + "ANY", + "NamedSignal", + "Namespace", + "Signal", + "WeakNamespace", + "receiver_connected", + "signal", +] + +__version__ = "1.6.3" diff --git a/.venv/Lib/site-packages/blinker/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/blinker/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48717ab7d83fdf1c7b732fc45016d355e1ce64df GIT binary patch literal 492 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc b/.venv/Lib/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c3fd68df61e7143bb4ec191493413c89f07565f GIT binary patch literal 4231 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 a^M={9s*R@QUU%kNmgzL!x%16>bK!r(3dgYk literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/blinker/__pycache__/base.cpython-310.pyc b/.venv/Lib/site-packages/blinker/__pycache__/base.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5d5024348ab6f9f95eed1e2b2874c3d327eb7a2 GIT binary patch literal 17411 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 L)a2Au`Plye8n0SN literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/blinker/_saferef.py b/.venv/Lib/site-packages/blinker/_saferef.py new file mode 100644 index 0000000..dcb70c1 --- /dev/null +++ b/.venv/Lib/site-packages/blinker/_saferef.py @@ -0,0 +1,230 @@ +# extracted from Louie, http://pylouie.org/ +# updated for Python 3 +# +# Copyright (c) 2006 Patrick K. O'Brien, Mike C. Fletcher, +# Matthew R. Scott +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +"""Refactored 'safe reference from dispatcher.py""" +import operator +import sys +import traceback +import weakref + + +get_self = operator.attrgetter("__self__") +get_func = operator.attrgetter("__func__") + + +def safe_ref(target, on_delete=None): + """Return a *safe* weak reference to a callable target. + + - ``target``: The object to be weakly referenced, if it's a bound + method reference, will create a BoundMethodWeakref, otherwise + creates a simple weakref. + + - ``on_delete``: If provided, will have a hard reference stored to + the callable to be called after the safe reference goes out of + scope with the reference object, (either a weakref or a + BoundMethodWeakref) as argument. + """ + try: + im_self = get_self(target) + except AttributeError: + if callable(on_delete): + return weakref.ref(target, on_delete) + else: + return weakref.ref(target) + else: + if im_self is not None: + # Turn a bound method into a BoundMethodWeakref instance. + # Keep track of these instances for lookup by disconnect(). + assert hasattr(target, "im_func") or hasattr(target, "__func__"), ( + f"safe_ref target {target!r} has im_self, but no im_func, " + "don't know how to create reference" + ) + reference = BoundMethodWeakref(target=target, on_delete=on_delete) + return reference + + +class BoundMethodWeakref: + """'Safe' and reusable weak references to instance methods. + + BoundMethodWeakref objects provide a mechanism for referencing a + bound method without requiring that the method object itself + (which is normally a transient object) is kept alive. Instead, + the BoundMethodWeakref object keeps weak references to both the + object and the function which together define the instance method. + + Attributes: + + - ``key``: The identity key for the reference, calculated by the + class's calculate_key method applied to the target instance method. + + - ``deletion_methods``: Sequence of callable objects taking single + argument, a reference to this object which will be called when + *either* the target object or target function is garbage + collected (i.e. when this object becomes invalid). These are + specified as the on_delete parameters of safe_ref calls. + + - ``weak_self``: Weak reference to the target object. + + - ``weak_func``: Weak reference to the target function. + + Class Attributes: + + - ``_all_instances``: Class attribute pointing to all live + BoundMethodWeakref objects indexed by the class's + calculate_key(target) method applied to the target objects. + This weak value dictionary is used to short-circuit creation so + that multiple references to the same (object, function) pair + produce the same BoundMethodWeakref instance. + """ + + _all_instances = weakref.WeakValueDictionary() # type: ignore[var-annotated] + + def __new__(cls, target, on_delete=None, *arguments, **named): + """Create new instance or return current instance. + + Basically this method of construction allows us to + short-circuit creation of references to already-referenced + instance methods. The key corresponding to the target is + calculated, and if there is already an existing reference, + that is returned, with its deletion_methods attribute updated. + Otherwise the new instance is created and registered in the + table of already-referenced methods. + """ + key = cls.calculate_key(target) + current = cls._all_instances.get(key) + if current is not None: + current.deletion_methods.append(on_delete) + return current + else: + base = super().__new__(cls) + cls._all_instances[key] = base + base.__init__(target, on_delete, *arguments, **named) + return base + + def __init__(self, target, on_delete=None): + """Return a weak-reference-like instance for a bound method. + + - ``target``: The instance-method target for the weak reference, + must have im_self and im_func attributes and be + reconstructable via the following, which is true of built-in + instance methods:: + + target.im_func.__get__( target.im_self ) + + - ``on_delete``: Optional callback which will be called when + this weak reference ceases to be valid (i.e. either the + object or the function is garbage collected). Should take a + single argument, which will be passed a pointer to this + object. + """ + + def remove(weak, self=self): + """Set self.isDead to True when method or instance is destroyed.""" + methods = self.deletion_methods[:] + del self.deletion_methods[:] + try: + del self.__class__._all_instances[self.key] + except KeyError: + pass + for function in methods: + try: + if callable(function): + function(self) + except Exception: + try: + traceback.print_exc() + except AttributeError: + e = sys.exc_info()[1] + print( + f"Exception during saferef {self} " + f"cleanup function {function}: {e}" + ) + + self.deletion_methods = [on_delete] + self.key = self.calculate_key(target) + im_self = get_self(target) + im_func = get_func(target) + self.weak_self = weakref.ref(im_self, remove) + self.weak_func = weakref.ref(im_func, remove) + self.self_name = str(im_self) + self.func_name = str(im_func.__name__) + + @classmethod + def calculate_key(cls, target): + """Calculate the reference key for this reference. + + Currently this is a two-tuple of the id()'s of the target + object and the target function respectively. + """ + return (id(get_self(target)), id(get_func(target))) + + def __str__(self): + """Give a friendly representation of the object.""" + return "{}({}.{})".format( + self.__class__.__name__, + self.self_name, + self.func_name, + ) + + __repr__ = __str__ + + def __hash__(self): + return hash((self.self_name, self.key)) + + def __nonzero__(self): + """Whether we are still a valid reference.""" + return self() is not None + + def __eq__(self, other): + """Compare with another reference.""" + if not isinstance(other, self.__class__): + return operator.eq(self.__class__, type(other)) + return operator.eq(self.key, other.key) + + def __call__(self): + """Return a strong reference to the bound method. + + If the target cannot be retrieved, then will return None, + otherwise returns a bound instance method for our object and + function. + + Note: You may call this method any number of times, as it does + not invalidate the reference. + """ + target = self.weak_self() + if target is not None: + function = self.weak_func() + if function is not None: + return function.__get__(target) + return None diff --git a/.venv/Lib/site-packages/blinker/_utilities.py b/.venv/Lib/site-packages/blinker/_utilities.py new file mode 100644 index 0000000..068d94c --- /dev/null +++ b/.venv/Lib/site-packages/blinker/_utilities.py @@ -0,0 +1,142 @@ +from __future__ import annotations + +import asyncio +import inspect +import sys +import typing as t +from functools import partial +from weakref import ref + +from blinker._saferef import BoundMethodWeakref + +IdentityType = t.Union[t.Tuple[int, int], str, int] + + +class _symbol: + def __init__(self, name): + """Construct a new named symbol.""" + self.__name__ = self.name = name + + def __reduce__(self): + return symbol, (self.name,) + + def __repr__(self): + return self.name + + +_symbol.__name__ = "symbol" + + +class symbol: + """A constant symbol. + + >>> symbol('foo') is symbol('foo') + True + >>> symbol('foo') + foo + + A slight refinement of the MAGICCOOKIE=object() pattern. The primary + advantage of symbol() is its repr(). They are also singletons. + + Repeated calls of symbol('name') will all return the same instance. + + """ + + symbols = {} # type: ignore[var-annotated] + + def __new__(cls, name): + try: + return cls.symbols[name] + except KeyError: + return cls.symbols.setdefault(name, _symbol(name)) + + +def hashable_identity(obj: object) -> IdentityType: + if hasattr(obj, "__func__"): + return (id(obj.__func__), id(obj.__self__)) # type: ignore[attr-defined] + elif hasattr(obj, "im_func"): + return (id(obj.im_func), id(obj.im_self)) # type: ignore[attr-defined] + elif isinstance(obj, (int, str)): + return obj + else: + return id(obj) + + +WeakTypes = (ref, BoundMethodWeakref) + + +class annotatable_weakref(ref): + """A weakref.ref that supports custom instance attributes.""" + + receiver_id: t.Optional[IdentityType] + sender_id: t.Optional[IdentityType] + + +def reference( # type: ignore[no-untyped-def] + object, callback=None, **annotations +) -> annotatable_weakref: + """Return an annotated weak ref.""" + if callable(object): + weak = callable_reference(object, callback) + else: + weak = annotatable_weakref(object, callback) + for key, value in annotations.items(): + setattr(weak, key, value) + return weak # type: ignore[no-any-return] + + +def callable_reference(object, callback=None): + """Return an annotated weak ref, supporting bound instance methods.""" + if hasattr(object, "im_self") and object.im_self is not None: + return BoundMethodWeakref(target=object, on_delete=callback) + elif hasattr(object, "__self__") and object.__self__ is not None: + return BoundMethodWeakref(target=object, on_delete=callback) + return annotatable_weakref(object, callback) + + +class lazy_property: + """A @property that is only evaluated once.""" + + def __init__(self, deferred): + self._deferred = deferred + self.__doc__ = deferred.__doc__ + + def __get__(self, obj, cls): + if obj is None: + return self + value = self._deferred(obj) + setattr(obj, self._deferred.__name__, value) + return value + + +def is_coroutine_function(func: t.Any) -> bool: + # Python < 3.8 does not correctly determine partially wrapped + # coroutine functions are coroutine functions, hence the need for + # this to exist. Code taken from CPython. + if sys.version_info >= (3, 8): + return asyncio.iscoroutinefunction(func) + else: + # Note that there is something special about the AsyncMock + # such that it isn't determined as a coroutine function + # without an explicit check. + try: + from unittest.mock import AsyncMock # type: ignore[attr-defined] + + if isinstance(func, AsyncMock): + return True + except ImportError: + # Not testing, no asynctest to import + pass + + while inspect.ismethod(func): + func = func.__func__ + while isinstance(func, partial): + func = func.func + if not inspect.isfunction(func): + return False + + if func.__code__.co_flags & inspect.CO_COROUTINE: + return True + + acic = asyncio.coroutines._is_coroutine # type: ignore[attr-defined] + return getattr(func, "_is_coroutine", None) is acic diff --git a/.venv/Lib/site-packages/blinker/base.py b/.venv/Lib/site-packages/blinker/base.py new file mode 100644 index 0000000..337ebc2 --- /dev/null +++ b/.venv/Lib/site-packages/blinker/base.py @@ -0,0 +1,548 @@ +"""Signals and events. + +A small implementation of signals, inspired by a snippet of Django signal +API client code seen in a blog post. Signals are first-class objects and +each manages its own receivers and message emission. + +The :func:`signal` function provides singleton behavior for named signals. + +""" +from __future__ import annotations + +import typing as t +from collections import defaultdict +from contextlib import contextmanager +from warnings import warn +from weakref import WeakValueDictionary + +from blinker._utilities import annotatable_weakref +from blinker._utilities import hashable_identity +from blinker._utilities import IdentityType +from blinker._utilities import is_coroutine_function +from blinker._utilities import lazy_property +from blinker._utilities import reference +from blinker._utilities import symbol +from blinker._utilities import WeakTypes + +if t.TYPE_CHECKING: + import typing_extensions as te + + T_callable = t.TypeVar("T_callable", bound=t.Callable[..., t.Any]) + + T = t.TypeVar("T") + P = te.ParamSpec("P") + + AsyncWrapperType = t.Callable[[t.Callable[P, t.Awaitable[T]]], t.Callable[P, T]] + SyncWrapperType = t.Callable[[t.Callable[P, T]], t.Callable[P, t.Awaitable[T]]] + +ANY = symbol("ANY") +ANY.__doc__ = 'Token for "any sender".' +ANY_ID = 0 + + +class Signal: + """A notification emitter.""" + + #: An :obj:`ANY` convenience synonym, allows ``Signal.ANY`` + #: without an additional import. + ANY = ANY + + @lazy_property + def receiver_connected(self) -> Signal: + """Emitted after each :meth:`connect`. + + The signal sender is the signal instance, and the :meth:`connect` + arguments are passed through: *receiver*, *sender*, and *weak*. + + .. versionadded:: 1.2 + + """ + return Signal(doc="Emitted after a receiver connects.") + + @lazy_property + def receiver_disconnected(self) -> Signal: + """Emitted after :meth:`disconnect`. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: *receiver* and *sender*. + + Note, this signal is emitted **only** when :meth:`disconnect` is + called explicitly. + + The disconnect signal can not be emitted by an automatic disconnect + (due to a weakly referenced receiver or sender going out of scope), + as the receiver and/or sender instances are no longer available for + use at the time this signal would be emitted. + + An alternative approach is available by subscribing to + :attr:`receiver_connected` and setting up a custom weakref cleanup + callback on weak receivers and senders. + + .. versionadded:: 1.2 + + """ + return Signal(doc="Emitted after a receiver disconnects.") + + def __init__(self, doc: str | None = None) -> None: + """ + :param doc: optional. If provided, will be assigned to the signal's + __doc__ attribute. + + """ + if doc: + self.__doc__ = doc + #: A mapping of connected receivers. + #: + #: The values of this mapping are not meaningful outside of the + #: internal :class:`Signal` implementation, however the boolean value + #: of the mapping is useful as an extremely efficient check to see if + #: any receivers are connected to the signal. + self.receivers: dict[IdentityType, t.Callable | annotatable_weakref] = {} + self.is_muted = False + self._by_receiver: dict[IdentityType, set[IdentityType]] = defaultdict(set) + self._by_sender: dict[IdentityType, set[IdentityType]] = defaultdict(set) + self._weak_senders: dict[IdentityType, annotatable_weakref] = {} + + def connect( + self, receiver: T_callable, sender: t.Any = ANY, weak: bool = True + ) -> T_callable: + """Connect *receiver* to signal events sent by *sender*. + + :param receiver: A callable. Will be invoked by :meth:`send` with + `sender=` as a single positional argument and any ``kwargs`` that + were provided to a call to :meth:`send`. + + :param sender: Any object or :obj:`ANY`, defaults to ``ANY``. + Restricts notifications delivered to *receiver* to only those + :meth:`send` emissions sent by *sender*. If ``ANY``, the receiver + will always be notified. A *receiver* may be connected to + multiple *sender* values on the same Signal through multiple calls + to :meth:`connect`. + + :param weak: If true, the Signal will hold a weakref to *receiver* + and automatically disconnect when *receiver* goes out of scope or + is garbage collected. Defaults to True. + + """ + receiver_id = hashable_identity(receiver) + receiver_ref: T_callable | annotatable_weakref + + if weak: + receiver_ref = reference(receiver, self._cleanup_receiver) + receiver_ref.receiver_id = receiver_id + else: + receiver_ref = receiver + sender_id: IdentityType + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = hashable_identity(sender) + + self.receivers.setdefault(receiver_id, receiver_ref) + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + del receiver_ref + + if sender is not ANY and sender_id not in self._weak_senders: + # wire together a cleanup for weakref-able senders + try: + sender_ref = reference(sender, self._cleanup_sender) + sender_ref.sender_id = sender_id + except TypeError: + pass + else: + self._weak_senders.setdefault(sender_id, sender_ref) + del sender_ref + + # broadcast this connection. if receivers raise, disconnect. + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: + try: + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) + except TypeError as e: + self.disconnect(receiver, sender) + raise e + if receiver_connected.receivers and self is not receiver_connected: + try: + receiver_connected.send( + self, receiver_arg=receiver, sender_arg=sender, weak_arg=weak + ) + except TypeError as e: + self.disconnect(receiver, sender) + raise e + return receiver + + def connect_via( + self, sender: t.Any, weak: bool = False + ) -> t.Callable[[T_callable], T_callable]: + """Connect the decorated function as a receiver for *sender*. + + :param sender: Any object or :obj:`ANY`. The decorated function + will only receive :meth:`send` emissions sent by *sender*. If + ``ANY``, the receiver will always be notified. A function may be + decorated multiple times with differing *sender* values. + + :param weak: If true, the Signal will hold a weakref to the + decorated function and automatically disconnect when *receiver* + goes out of scope or is garbage collected. Unlike + :meth:`connect`, this defaults to False. + + The decorated function will be invoked by :meth:`send` with + `sender=` as a single positional argument and any ``kwargs`` that + were provided to the call to :meth:`send`. + + + .. versionadded:: 1.1 + + """ + + def decorator(fn: T_callable) -> T_callable: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: t.Callable, sender: t.Any = ANY + ) -> t.Generator[None, None, None]: + """Execute a block with the signal temporarily connected to *receiver*. + + :param receiver: a receiver callable + :param sender: optional, a sender to filter on + + This is a context manager for use in the ``with`` statement. It can + be useful in unit tests. *receiver* is connected to the signal for + the duration of the ``with`` block, and will be disconnected + automatically when exiting the block: + + .. code-block:: python + + with on_ready.connected_to(receiver): + # do stuff + on_ready.send(123) + + .. versionadded:: 1.1 + + """ + self.connect(receiver, sender=sender, weak=False) + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> t.Generator[None, None, None]: + """Context manager for temporarily disabling signal. + Useful for test purposes. + """ + self.is_muted = True + try: + yield None + except Exception as e: + raise e + finally: + self.is_muted = False + + def temporarily_connected_to( + self, receiver: t.Callable, sender: t.Any = ANY + ) -> t.ContextManager[None]: + """An alias for :meth:`connected_to`. + + :param receiver: a receiver callable + :param sender: optional, a sender to filter on + + .. versionadded:: 0.9 + + .. versionchanged:: 1.1 + Renamed to :meth:`connected_to`. ``temporarily_connected_to`` was + deprecated in 1.2 and will be removed in a subsequent version. + + """ + warn( + "temporarily_connected_to is deprecated; use connected_to instead.", + DeprecationWarning, + ) + return self.connected_to(receiver, sender) + + def send( + self, + *sender: t.Any, + _async_wrapper: AsyncWrapperType | None = None, + **kwargs: t.Any, + ) -> list[tuple[t.Callable, t.Any]]: + """Emit this signal on behalf of *sender*, passing on ``kwargs``. + + Returns a list of 2-tuples, pairing receivers with their return + value. The ordering of receiver notification is undefined. + + :param sender: Any object or ``None``. If omitted, synonymous + with ``None``. Only accepts one positional argument. + :param _async_wrapper: A callable that should wrap a coroutine + receiver and run it when called synchronously. + + :param kwargs: Data to be sent to receivers. + """ + if self.is_muted: + return [] + + sender = self._extract_sender(sender) + results = [] + for receiver in self.receivers_for(sender): + if is_coroutine_function(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function") + receiver = _async_wrapper(receiver) + result = receiver(sender, **kwargs) + results.append((receiver, result)) + return results + + async def send_async( + self, + *sender: t.Any, + _sync_wrapper: SyncWrapperType | None = None, + **kwargs: t.Any, + ) -> list[tuple[t.Callable, t.Any]]: + """Emit this signal on behalf of *sender*, passing on ``kwargs``. + + Returns a list of 2-tuples, pairing receivers with their return + value. The ordering of receiver notification is undefined. + + :param sender: Any object or ``None``. If omitted, synonymous + with ``None``. Only accepts one positional argument. + :param _sync_wrapper: A callable that should wrap a synchronous + receiver and run it when awaited. + + :param kwargs: Data to be sent to receivers. + """ + if self.is_muted: + return [] + + sender = self._extract_sender(sender) + results = [] + for receiver in self.receivers_for(sender): + if not is_coroutine_function(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function") + receiver = _sync_wrapper(receiver) + result = await receiver(sender, **kwargs) + results.append((receiver, result)) + return results + + def _extract_sender(self, sender: t.Any) -> t.Any: + if not self.receivers: + # Ensure correct signature even on no-op sends, disable with -O + # for lowest possible cost. + if __debug__ and sender and len(sender) > 1: + raise TypeError( + f"send() accepts only one positional argument, {len(sender)} given" + ) + return [] + + # Using '*sender' rather than 'sender=None' allows 'sender' to be + # used as a keyword argument- i.e. it's an invisible name in the + # function signature. + if len(sender) == 0: + sender = None + elif len(sender) > 1: + raise TypeError( + f"send() accepts only one positional argument, {len(sender)} given" + ) + else: + sender = sender[0] + return sender + + def has_receivers_for(self, sender: t.Any) -> bool: + """True if there is probably a receiver for *sender*. + + Performs an optimistic check only. Does not guarantee that all + weakly referenced receivers are still alive. See + :meth:`receivers_for` for a stronger search. + + """ + if not self.receivers: + return False + if self._by_sender[ANY_ID]: + return True + if sender is ANY: + return False + return hashable_identity(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> t.Generator[t.Callable[[t.Any], t.Any], None, None]: + """Iterate all live receivers listening for *sender*.""" + # TODO: test receivers_for(ANY) + if self.receivers: + sender_id = hashable_identity(sender) + if sender_id in self._by_sender: + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] + else: + ids = self._by_sender[ANY_ID].copy() + for receiver_id in ids: + receiver = self.receivers.get(receiver_id) + if receiver is None: + continue + if isinstance(receiver, WeakTypes): + strong = receiver() + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + receiver = strong + yield receiver # type: ignore[misc] + + def disconnect(self, receiver: t.Callable, sender: t.Any = ANY) -> None: + """Disconnect *receiver* from this signal's events. + + :param receiver: a previously :meth:`connected` callable + + :param sender: a specific sender to disconnect from, or :obj:`ANY` + to disconnect from all senders. Defaults to ``ANY``. + + """ + sender_id: IdentityType + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = hashable_identity(sender) + receiver_id = hashable_identity(receiver) + self._disconnect(receiver_id, sender_id) + + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) + + def _disconnect(self, receiver_id: IdentityType, sender_id: IdentityType) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, False): + for bucket in self._by_sender.values(): + bucket.discard(receiver_id) + self.receivers.pop(receiver_id, None) + else: + self._by_sender[sender_id].discard(receiver_id) + self._by_receiver[receiver_id].discard(sender_id) + + def _cleanup_receiver(self, receiver_ref: annotatable_weakref) -> None: + """Disconnect a receiver from all senders.""" + self._disconnect(t.cast(IdentityType, receiver_ref.receiver_id), ANY_ID) + + def _cleanup_sender(self, sender_ref: annotatable_weakref) -> None: + """Disconnect all receivers from a sender.""" + sender_id = t.cast(IdentityType, sender_ref.sender_id) + assert sender_id != ANY_ID + self._weak_senders.pop(sender_id, None) + for receiver_id in self._by_sender.pop(sender_id, ()): + self._by_receiver[receiver_id].discard(sender_id) + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leave behind a small amount of bookkeeping + for the receiver and sender values. Typical workloads using Blinker, + for example in most web apps, Flask, CLI scripts, etc., are not + adversely affected by this bookkeeping. + + With a long-running Python process performing dynamic signal routing + with high volume- e.g. connecting to function closures, "senders" are + all unique object instances, and doing all of this over and over- you + may see memory usage will grow due to extraneous bookkeeping. (An empty + set() for each stale sender/receiver pair.) + + This method will prune that bookkeeping away, with the caveat that such + pruning is not threadsafe. The risk is that cleanup of a fully + disconnected receiver/sender pair occurs while another thread is + connecting that same pair. If you are in the highly dynamic, unique + receiver/sender situation that has lead you to this method, that + failure mode is perhaps not a big deal for you. + """ + for mapping in (self._by_sender, self._by_receiver): + for _id, bucket in list(mapping.items()): + if not bucket: + mapping.pop(_id, None) + + def _clear_state(self) -> None: + """Throw away all signal state. Useful for unit tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +receiver_connected = Signal( + """\ +Sent by a :class:`Signal` after a receiver connects. + +:argument: the Signal that was connected to +:keyword receiver_arg: the connected receiver +:keyword sender_arg: the sender to connect to +:keyword weak_arg: true if the connection to receiver_arg is a weak reference + +.. deprecated:: 1.2 + +As of 1.2, individual signals have their own private +:attr:`~Signal.receiver_connected` and +:attr:`~Signal.receiver_disconnected` signals with a slightly simplified +call signature. This global signal is planned to be removed in 1.6. + +""" +) + + +class NamedSignal(Signal): + """A named generic notification emitter.""" + + def __init__(self, name: str, doc: str | None = None) -> None: + Signal.__init__(self, doc) + + #: The name of this signal. + self.name = name + + def __repr__(self) -> str: + base = Signal.__repr__(self) + return f"{base[:-1]}; {self.name!r}>" + + +class Namespace(dict): + """A mapping of signal names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` *name*, creating it if required. + + Repeated calls to this function will return the same signal object. + + """ + try: + return self[name] # type: ignore[no-any-return] + except KeyError: + result = self.setdefault(name, NamedSignal(name, doc)) + return result # type: ignore[no-any-return] + + +class WeakNamespace(WeakValueDictionary): + """A weak mapping of signal names to signals. + + Automatically cleans up unused Signals when the last reference goes out + of scope. This namespace implementation exists for a measure of legacy + compatibility with Blinker <= 1.2, and may be dropped in the future. + + .. versionadded:: 1.3 + + """ + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` *name*, creating it if required. + + Repeated calls to this function will return the same signal object. + + """ + try: + return self[name] # type: ignore[no-any-return] + except KeyError: + result = self.setdefault(name, NamedSignal(name, doc)) + return result # type: ignore[no-any-return] + + +signal = Namespace().signal diff --git a/.venv/Lib/site-packages/blinker/py.typed b/.venv/Lib/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/INSTALLER b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/LICENSE b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/LICENSE new file mode 100644 index 0000000..0a64774 --- /dev/null +++ b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/LICENSE @@ -0,0 +1,21 @@ +This package contains a modified version of ca-bundle.crt: + +ca-bundle.crt -- Bundle of CA Root Certificates + +Certificate data from Mozilla as of: Thu Nov 3 19:04:19 2011# +This is a bundle of X.509 certificates of public Certificate Authorities +(CA). These were automatically extracted from Mozilla's root certificates +file (certdata.txt). This file can be found in the mozilla source tree: +https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt +It contains the certificates in PEM format and therefore +can be directly used with curl / libcurl / php_curl, or with +an Apache+mod_ssl webserver for SSL client authentication. +Just configure this file as the SSLCACertificateFile.# + +***** BEGIN LICENSE BLOCK ***** +This Source Code Form is subject to the terms of the Mozilla Public License, +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain +one at http://mozilla.org/MPL/2.0/. + +***** END LICENSE BLOCK ***** +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $ diff --git a/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/METADATA b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/METADATA new file mode 100644 index 0000000..07f4991 --- /dev/null +++ b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/METADATA @@ -0,0 +1,69 @@ +Metadata-Version: 2.1 +Name: certifi +Version: 2023.7.22 +Summary: Python package for providing Mozilla's CA Bundle. +Home-page: https://github.com/certifi/python-certifi +Author: Kenneth Reitz +Author-email: me@kennethreitz.com +License: MPL-2.0 +Project-URL: Source, https://github.com/certifi/python-certifi +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0) +Classifier: Natural Language :: English +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Requires-Python: >=3.6 +License-File: LICENSE + +Certifi: Python SSL Certificates +================================ + +Certifi provides Mozilla's carefully curated collection of Root Certificates for +validating the trustworthiness of SSL certificates while verifying the identity +of TLS hosts. It has been extracted from the `Requests`_ project. + +Installation +------------ + +``certifi`` is available on PyPI. Simply install it with ``pip``:: + + $ pip install certifi + +Usage +----- + +To reference the installed certificate authority (CA) bundle, you can use the +built-in function:: + + >>> import certifi + + >>> certifi.where() + '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem' + +Or from the command line:: + + $ python -m certifi + /usr/local/lib/python3.7/site-packages/certifi/cacert.pem + +Enjoy! + +.. _`Requests`: https://requests.readthedocs.io/en/master/ + +Addition/Removal of Certificates +-------------------------------- + +Certifi does not support any addition/removal or other modification of the +CA trust store content. This project is intended to provide a reliable and +highly portable root of trust to python deployments. Look to upstream projects +for methods to use alternate trust. + + diff --git a/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/RECORD b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/RECORD new file mode 100644 index 0000000..057a83f --- /dev/null +++ b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/RECORD @@ -0,0 +1,14 @@ +certifi-2023.7.22.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +certifi-2023.7.22.dist-info/LICENSE,sha256=oC9sY4-fuE0G93ZMOrCF2K9-2luTwWbaVDEkeQd8b7A,1052 +certifi-2023.7.22.dist-info/METADATA,sha256=oyc8gd32SOVo0IGolt8-bR7FnZ9Z99GoHoGE6ACcvFA,2191 +certifi-2023.7.22.dist-info/RECORD,, +certifi-2023.7.22.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92 +certifi-2023.7.22.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8 +certifi/__init__.py,sha256=L_j-d0kYuA_MzA2_2hraF1ovf6KT6DTquRdV3paQwOk,94 +certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243 +certifi/__pycache__/__init__.cpython-310.pyc,, +certifi/__pycache__/__main__.cpython-310.pyc,, +certifi/__pycache__/core.cpython-310.pyc,, +certifi/cacert.pem,sha256=eU0Dn_3yd8BH4m8sfVj4Glhl2KDrcCSg-sEWT-pNJ88,281617 +certifi/core.py,sha256=lhewz0zFb2b4ULsQurElmloYwQoecjWzPqY67P8T7iM,4219 +certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/WHEEL b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/WHEEL new file mode 100644 index 0000000..5bad85f --- /dev/null +++ b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/top_level.txt b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/top_level.txt new file mode 100644 index 0000000..963eac5 --- /dev/null +++ b/.venv/Lib/site-packages/certifi-2023.7.22.dist-info/top_level.txt @@ -0,0 +1 @@ +certifi diff --git a/.venv/Lib/site-packages/certifi/__init__.py b/.venv/Lib/site-packages/certifi/__init__.py new file mode 100644 index 0000000..8ce89ce --- /dev/null +++ b/.venv/Lib/site-packages/certifi/__init__.py @@ -0,0 +1,4 @@ +from .core import contents, where + +__all__ = ["contents", "where"] +__version__ = "2023.07.22" diff --git a/.venv/Lib/site-packages/certifi/__main__.py b/.venv/Lib/site-packages/certifi/__main__.py new file mode 100644 index 0000000..8945b5d --- /dev/null +++ b/.venv/Lib/site-packages/certifi/__main__.py @@ -0,0 +1,12 @@ +import argparse + +from certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/.venv/Lib/site-packages/certifi/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/certifi/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2108db2cbf58bf84bbb62dabe3c07953d7a00ddf GIT binary patch literal 282 zcmYk0!AiqG5QcX*NgFB!AHi!5rfmueBBJD4yc92CaY(acT}*bv?lz^qfY0J9?bVa7 z;K|LcKg>7${KL=a`Fuu#*w+eQ!~Pk~xmYldVeD0aAcD4}qZRE~#V8R>M0-|6BCcYQ zY)LlxrQs}NK5evesGRl5@f{7CvByLKpR;0Ftn=kw=ICb02t6% zsTIICG1IYN#NVd8<1aQu+$wz(yxgvDR=hkIgQ___^*zrAR0H409kMAsT9G3h*)|pA`~xSA;j!hQ=32RZd%%F51xF7di0g{ z>dCV=PfmiU1M>~vH?u#s8Vr1b#h%CTiSxZR|I0;ljjdx8NhDp7xSec83l_7&i5*IS z9D1)LcEMeG(vdysO7Er3-9sO94t&Yf2^<02lRc$KnGzY^RbvV zN~z4XAx}pa1{> literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/certifi/__pycache__/core.cpython-310.pyc b/.venv/Lib/site-packages/certifi/__pycache__/core.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbcb01595c1536b3d789d4214b4251a4a6463605 GIT binary patch literal 1890 zcmZ`(TW{Mo6ecOkmgQUGT-vm|co(41fO-fD3_~#t3%mh&$bzCtvCT6es3M&xu_c3~ zlch`dk^*}w_7~#E{3X8bDbIV$x^?HsPMt0(1s)!f($ROm?~qxw>Jw<}_f`4p93g+= zhtD;RCnhQX*JXfL;`?^mz5UjoS7v_> z?mm-#ER{)mNo#oI|MsT&{`PL7n}bY@`m(8{8L3n^&8}=FsWwr+ADJXeoBb@FI9ab5 zM;NI!l!Iobnu*cPI7^L8jc)npD8^>M&K(%fQH_AvVx+@f(wEjnt8HQOn;74{+Bi(w z(Di3v49GVkYQa#$1U;drj$mULBW_&7PYYuLKD@O>&YVqKoF;eS&(H-$TM651?e89M zhmY2_*A>QBE*R_WWl1`W%&sk8zR}+P(K^~FTM9$SMXE47BdU&{pt)FYKkPoyQt7Tv zvqRBsZ$0>8wc8#kCDZt5Z8+?<4rF@J-AJBxbzTL+mR;BLswv`s%UCx-smvHn)CGlHm5B56=d-m z9Ml^L{0rkCfdcLUAkNt$ssT%9G*9EkKVae;_${VhqXD(2if1f@6rGC*&9^{w4dP z@|+*@Q#K|)5C*4#!*k+LsQ6W)mk%i=`1}N2z*@jI)gnX)9LuwzOmliHN4W!6eFQrS z1y3BC50+uQ4JKz|yM^8c8F?~Mq`7tm( zhFcS1VO<8UWtmnh;M$@{R2mJW^}_sK2t&*9KmxzC_kTcmDtgd0{;)!8?^amdg*S3d z)qCjOR5PgPK5o7b25S04^qc4}*w0B0Sv4wJN(*@a{<%#`UTPg|F& z>e+pw@@mBjo|G(N&QDFAuR?|zbn>-hwc|=~N%!n*V)%0dK>OEk2su9M*e$ zSwJ_WV!f{>m-g4FhW-`|CtksK<``!jcxv3f;;(qzqsU%`vJ#{G6{GAmW9(n%uz%o# MSIqVQu9X|^e~aCXPyhe` literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/certifi/cacert.pem b/.venv/Lib/site-packages/certifi/cacert.pem new file mode 100644 index 0000000..0212369 --- /dev/null +++ b/.venv/Lib/site-packages/certifi/cacert.pem @@ -0,0 +1,4635 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: 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" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE +BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu +IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow +RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY +U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv +Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br +YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF +nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH +6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt +eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ +c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ +MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH +HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf +jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 +5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB +rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c +wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 +cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB +AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp +WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 +xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ +2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ +IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 +aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X +em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR +dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ +OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ +hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy +tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=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" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 +MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 +ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD +VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j +b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq +scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO +xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H +LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX +uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD +yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ +JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q +rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN +BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L +hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB +QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ +HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu +Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg +QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB +BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx +MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA +A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb +laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 +awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo +JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw +LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT +VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk +LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb +UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ +QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ +naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls +QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- + +# Issuer: CN=UCA Global G2 Root O=UniTrust +# Subject: CN=UCA Global G2 Root O=UniTrust +# Label: "UCA Global G2 Root" +# Serial: 124779693093741543919145257850076631279 +# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 +# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a +# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH +bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x +CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds +b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr +b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 +kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm +VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R +VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc +C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj +tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY +D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv +j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl +NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 +iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP +O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV +ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj +L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 +1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl +1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU +b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV +PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj +y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb +EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg +DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI ++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy +YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX +UB+K+wb1whnw0A== +-----END CERTIFICATE----- + +# Issuer: CN=UCA Extended Validation Root O=UniTrust +# Subject: CN=UCA Extended Validation Root O=UniTrust +# Label: "UCA Extended Validation Root" +# Serial: 106100277556486529736699587978573607008 +# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 +# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a +# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH +MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF +eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx +MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV +BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog +D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS +sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop +O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk +sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi +c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj +VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz +KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ +TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G +sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs +1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD +fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN +l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR +ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ +VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 +c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp +4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s +t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj +2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO +vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C +xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx +cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM +fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax +-----END CERTIFICATE----- + +# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 +# Label: "Certigna Root CA" +# Serial: 269714418870597844693661054334862075617 +# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 +# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 +# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 +-----BEGIN CERTIFICATE----- +MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw +WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw +MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x +MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD +VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX +BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO +ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M +CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu +I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm +TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh +C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf +ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz +IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT +Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k +JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 +hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB +GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of +1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov +L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo +dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr +aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq +hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L +6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG +HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 +0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB +lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi +o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 +gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v +faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 +Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh +jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw +3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign Root CA - G1" +# Serial: 235931866688319308814040 +# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac +# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c +# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 +-----BEGIN CERTIFICATE----- +MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD +VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU +ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH +MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO +MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv +Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz +f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO +8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq +d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM +tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt +Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB +o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x +PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM +wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d +GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH +6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby +RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx +iN66zB+Afko= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI +# Label: "emSign ECC Root CA - G3" +# Serial: 287880440101571086945156 +# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 +# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 +# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b +-----BEGIN CERTIFICATE----- +MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG +EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo +bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g +RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ +TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s +b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw +djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 +WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS +fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB +zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq +hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB +CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD ++JbNR6iC8hZVdyR+EhCVBCyj +-----END CERTIFICATE----- + +# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI +# Label: "emSign Root CA - C1" +# Serial: 825510296613316004955058 +# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 +# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 +# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f +-----BEGIN CERTIFICATE----- +MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG +A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg +SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v +dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ +BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ +HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH +3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH +GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c +xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 +aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq +TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 +/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 +kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG +YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT ++xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo +WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= +-----END CERTIFICATE----- + +# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI +# Label: "emSign ECC Root CA - C3" +# Serial: 582948710642506000014504 +# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 +# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 +# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 +-----BEGIN CERTIFICATE----- +MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG +EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx +IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw +MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln +biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND +IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci +MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti +sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O +BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB +Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c +3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J +0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post +# Label: "Hongkong Post Root CA 3" +# Serial: 46170865288971385588281144162979347873371282084 +# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 +# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 +# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 +-----BEGIN CERTIFICATE----- +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 +mpv0 +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global Certification Authority" +# Serial: 1846098327275375458322922162 +# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e +# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 +# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 +-----BEGIN CERTIFICATE----- +MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw +CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x +ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 +c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx +OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI +SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI +b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn +swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu +7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 +1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW +80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP +JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l +RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw +hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 +coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc +BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n +twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud +DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W +0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe +uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q +lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB +aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE +sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT +MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe +qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh +VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 +h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 +EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK +yeC2nOnOcXHebD8WpHk= +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P256 Certification Authority" +# Serial: 4151900041497450638097112925 +# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 +# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf +# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 +-----BEGIN CERTIFICATE----- +MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG +SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN +FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw +CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh +DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 +-----END CERTIFICATE----- + +# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. +# Label: "Trustwave Global ECC P384 Certification Authority" +# Serial: 2704997926503831671788816187 +# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 +# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 +# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 +-----BEGIN CERTIFICATE----- +MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD +VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf +BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 +YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G +A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 +d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF +Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB +BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ +j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF +1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G +A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 +AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC +MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu +Sw== +-----END CERTIFICATE----- + +# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. +# Label: "NAVER Global Root Certification Authority" +# Serial: 9013692873798656336226253319739695165984492813 +# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b +# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 +# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 +-----BEGIN CERTIFICATE----- +MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM +BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG +T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx +CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD +b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA +iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH +38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE +HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz +kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP +szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq +vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf +nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG +YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo +0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a +CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K +AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I +36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB +Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN +qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj +cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm ++LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL +hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe +lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 +p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 +piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR +LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX +5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO +dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul +9XXeifdy +-----END CERTIFICATE----- + +# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres +# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" +# Serial: 131542671362353147877283741781055151509 +# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb +# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a +# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb +-----BEGIN CERTIFICATE----- +MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw +CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw +FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S +Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 +MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL +DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS +QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH +sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK +Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu +SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC +MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy +v+c= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa +# Label: "GlobalSign Root R46" +# Serial: 1552617688466950547958867513931858518042577 +# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef +# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 +# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 +-----BEGIN CERTIFICATE----- +MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA +MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD +VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy +MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt +c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ +OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG +vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud +316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo +0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE +y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF +zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE ++cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN +I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs +x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa +ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC +4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 +7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg +JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti +2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk +pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF +FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt +rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk +ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 +u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP +4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 +N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 +vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa +# Label: "GlobalSign Root E46" +# Serial: 1552617690338932563915843282459653771421763 +# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f +# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 +# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 +-----BEGIN CERTIFICATE----- +MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx +CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD +ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw +MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex +HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq +R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd +yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud +DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ +7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 ++RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= +-----END CERTIFICATE----- + +# Issuer: CN=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" +# Serial: 996390341000653745 +# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 +# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 +# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum EC-384 CA" +# Serial: 160250656287871593594747141429395092468 +# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 +# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed +# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 +-----BEGIN CERTIFICATE----- +MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw +CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw +JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT +EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 +WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT +LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX +BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE +KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm +Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 +EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J +UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn +nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Root CA" +# Serial: 40870380103424195783807378461123655149 +# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 +# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 +# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique +# Label: "TunTrust Root CA" +# Serial: 108534058042236574382096126452369648152337120275 +# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 +# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb +# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 +-----BEGIN CERTIFICATE----- +MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL +BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg +Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv +b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG +EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u +IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ +n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd +2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF +VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ +GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF +li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU +r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 +eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb +MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg +jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB +7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW +5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE +ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 +90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z +xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu +QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 +FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH +22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP +xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn +dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 +Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b +nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ +CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH +u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj +d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS RSA Root CA 2021" +# Serial: 76817823531813593706434026085292783742 +# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 +# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d +# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg +Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL +MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl +YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv +b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l +mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE +4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv +a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M +pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw +Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b +LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY +AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB +AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq +E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr +W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ +CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU +X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 +f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja +H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP +JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P +zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt +jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 +/L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT +BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 +aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW +xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU +63ZTGI0RmLo= +-----END CERTIFICATE----- + +# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA +# Label: "HARICA TLS ECC Root CA 2021" +# Serial: 137515985548005187474074462014555733966 +# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 +# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 +# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 +-----BEGIN CERTIFICATE----- +MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw +CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh +cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v +dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG +A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj +aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg +Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 +KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y +STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD +AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw +SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN +nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 1977337328857672817 +# MD5 Fingerprint: 4e:6e:9b:54:4c:ca:b7:fa:48:e4:90:b1:15:4b:1c:a3 +# SHA1 Fingerprint: 0b:be:c2:27:22:49:cb:39:aa:db:35:5c:53:e3:8c:ae:78:ff:b6:fe +# SHA256 Fingerprint: 57:de:05:83:ef:d2:b2:6e:03:61:da:99:da:9d:f4:64:8d:ef:7e:e8:44:1c:3b:72:8a:fa:9b:cd:e0:f9:b2:6a +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1 +MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1UdDgQWBBRlzeurNR4APn7VdMAc +tHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4wgZswgZgGBFUd +IAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j +b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABC +AG8AbgBhAG4AbwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAw +ADEANzAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9m +iWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL4QjbEwj4KKE1soCzC1HA01aajTNF +Sa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDbLIpgD7dvlAceHabJ +hfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1ilI45P +Vf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZE +EAEeiGaPcjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV +1aUsIC+nmCjuRfzxuIgALI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2t +CsvMo2ebKHTEm9caPARYpoKdrcd7b/+Alun4jWq9GJAd/0kakFI3ky88Al2CdgtR +5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH9IBk9W6VULgRfhVwOEqw +f9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpfNIbnYrX9 +ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNK +GbqEZycPvEJdvSRUDewdcAZfpLz6IHxV +-----END CERTIFICATE----- + +# Issuer: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus ECC Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus ECC Root CA" +# Serial: 630369271402956006249506845124680065938238527194 +# MD5 Fingerprint: de:4b:c1:f5:52:8c:9b:43:e1:3e:8f:55:54:17:8d:85 +# SHA1 Fingerprint: f6:9c:db:b0:fc:f6:02:13:b6:52:32:a6:a3:91:3f:16:70:da:c3:e1 +# SHA256 Fingerprint: 30:fb:ba:2c:32:23:8e:2a:98:54:7a:f9:79:31:e5:50:42:8b:9b:3f:1c:8e:eb:66:33:dc:fa:86:c5:b2:7d:d3 +-----BEGIN CERTIFICATE----- +MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMw +RzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAY +BgNVBAMTEXZUcnVzIEVDQyBSb290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDcz +MTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28u +LEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+cToL0 +v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUd +e4BdS49nTPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIw +V53dVvHH4+m4SVBrm2nDb+zDfSXkV5UTQJtS0zvzQBm8JsctBp61ezaf9SXUY2sA +AjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQLYgmRWAD5Tfs0aNoJrSEG +GJTO +-----END CERTIFICATE----- + +# Issuer: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Subject: CN=vTrus Root CA O=iTrusChina Co.,Ltd. +# Label: "vTrus Root CA" +# Serial: 387574501246983434957692974888460947164905180485 +# MD5 Fingerprint: b8:c9:37:df:fa:6b:31:84:64:c5:ea:11:6a:1b:75:fc +# SHA1 Fingerprint: 84:1a:69:fb:f5:cd:1a:25:34:13:3d:e3:f8:fc:b8:99:d0:c9:14:b7 +# SHA256 Fingerprint: 8a:71:de:65:59:33:6f:42:6c:26:e5:38:80:d0:0d:88:a1:8d:a4:c6:a9:1f:0d:cb:61:94:e2:06:c5:c9:63:87 +-----BEGIN CERTIFICATE----- +MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQEL +BQAwQzELMAkGA1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4x +FjAUBgNVBAMTDXZUcnVzIFJvb3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMx +MDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoGA1UEChMTaVRydXNDaGluYSBDby4s +THRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZotsSKYc +IrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykU +AyyNJJrIZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+ +GrPSbcKvdmaVayqwlHeFXgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z9 +8Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KAYPxMvDVTAWqXcoKv8R1w6Jz1717CbMdH +flqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70kLJrxLT5ZOrpGgrIDajt +J8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2AXPKBlim +0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZN +pGvu/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQ +UqqzApVg+QxMaPnu1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHW +OXSuTEGC2/KmSNGzm/MzqvOmwMVO9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMB +AAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYgscasGrz2iTAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAKbqSSaet +8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd +nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1j +bhd47F18iMjrjld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvM +Kar5CKXiNxTKsbhm7xqC5PD48acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIiv +TDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJnxDHO2zTlJQNgJXtxmOTAGytfdELS +S8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554WgicEFOwE30z9J4nfr +I8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4sEb9 +b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNB +UvupLnKWnyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1P +Ti07NEPhmg4NpGaXutIcSkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929ven +sBxXVsFy6K2ir40zSbofitzmdHxghm+Hl3s= +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X2 O=Internet Security Research Group +# Subject: CN=ISRG Root X2 O=Internet Security Research Group +# Label: "ISRG Root X2" +# Serial: 87493402998870891108772069816698636114 +# MD5 Fingerprint: d3:9e:c4:1e:23:3c:a6:df:cf:a3:7e:6d:e0:14:e6:e5 +# SHA1 Fingerprint: bd:b1:b9:3c:d5:97:8d:45:c6:26:14:55:f8:db:95:c7:5a:d1:53:af +# SHA256 Fingerprint: 69:72:9b:8e:15:a8:6e:fc:17:7a:57:af:b7:17:1d:fc:64:ad:d2:8c:2f:ca:8c:f1:50:7e:34:45:3c:cb:14:70 +-----BEGIN CERTIFICATE----- +MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQsw +CQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2gg +R3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00 +MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5ldCBT +ZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgyMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0HttwW ++1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9 +ItgKbppbd9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZI +zj0EAwMDaAAwZQIwe3lORlCEwkSHRhtFcP9Ymd70/aTSVaYgLXTWNLxBo1BfASdW +tL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5U6VR5CmD1/iQMVtCnwr1 +/q4AaOeMSQ+2b1tbFfLn +-----END CERTIFICATE----- + +# Issuer: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Subject: CN=HiPKI Root CA - G1 O=Chunghwa Telecom Co., Ltd. +# Label: "HiPKI Root CA - G1" +# Serial: 60966262342023497858655262305426234976 +# MD5 Fingerprint: 69:45:df:16:65:4b:e8:68:9a:8f:76:5f:ff:80:9e:d3 +# SHA1 Fingerprint: 6a:92:e4:a8:ee:1b:ec:96:45:37:e3:29:57:49:cd:96:e3:e5:d2:60 +# SHA256 Fingerprint: f0:15:ce:3c:c2:39:bf:ef:06:4b:e9:f1:d2:c4:17:e1:a0:26:4a:0a:94:be:1f:0c:8d:12:18:64:eb:69:49:cc +-----BEGIN CERTIFICATE----- +MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBP +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xGzAZBgNVBAMMEkhpUEtJIFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRa +Fw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3 +YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kgUm9vdCBDQSAtIEcx +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0o9Qw +qNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twv +Vcg3Px+kwJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6 +lZgRZq2XNdZ1AYDgr/SEYYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnz +Qs7ZngyzsHeXZJzA9KMuH5UHsBffMNsAGJZMoYFL3QRtU6M9/Aes1MU3guvklQgZ +KILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfdhSi8MEyr48KxRURHH+CK +FgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj1jOXTyFj +HluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDr +y+K49a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ +/W3c1pzAtH2lsN0/Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgM +a/aOEmem8rJY5AIJEzypuxC00jBF8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6 +fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQDAgGGMA0GCSqG +SIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi +7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqc +SE5XCV0vrPSltJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6Fza +ZsT0pPBWGTMpWmWSBUdGSquEwx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9Tc +XzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07QJNBAsNB1CI69aO4I1258EHBGG3zg +iLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv5wiZqAxeJoBF1Pho +L5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+GpzjLrF +Ne85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wr +kkVbbiVghUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+ +vhV4nYWBSipX3tUZQ9rbyltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQU +YDksswBVLuT1sw5XxJFBAJw/6KXf6vb/yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 159662223612894884239637590694 +# MD5 Fingerprint: 26:29:f8:6d:e1:88:bf:a2:65:7f:aa:c4:cd:0f:7f:fc +# SHA1 Fingerprint: 6b:a0:b0:98:e1:71:ef:5a:ad:fe:48:15:80:77:10:f4:bd:6f:0b:28 +# SHA256 Fingerprint: b0:85:d7:0b:96:4f:19:1a:73:e4:af:0d:54:ae:7a:0e:07:aa:fd:af:9b:71:dd:08:62:13:8a:b7:32:5a:24:a2 +-----BEGIN CERTIFICATE----- +MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD +VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw +MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g +UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx +uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV +HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/ ++wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147 +bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R1 O=Google Trust Services LLC +# Subject: CN=GTS Root R1 O=Google Trust Services LLC +# Label: "GTS Root R1" +# Serial: 159662320309726417404178440727 +# MD5 Fingerprint: 05:fe:d0:bf:71:a8:a3:76:63:da:01:e0:d8:52:dc:40 +# SHA1 Fingerprint: e5:8c:1c:c4:91:3b:38:63:4b:e9:10:6e:e3:ad:8e:6b:9d:d9:81:4a +# SHA256 Fingerprint: d9:47:43:2a:bd:e7:b7:fa:90:fc:2e:6b:59:10:1b:12:80:e0:e1:c7:e4:e4:0f:a3:c6:88:7f:ff:57:a7:f4:cf +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R2 O=Google Trust Services LLC +# Subject: CN=GTS Root R2 O=Google Trust Services LLC +# Label: "GTS Root R2" +# Serial: 159662449406622349769042896298 +# MD5 Fingerprint: 1e:39:c0:53:e6:1e:29:82:0b:ca:52:55:36:5d:57:dc +# SHA1 Fingerprint: 9a:44:49:76:32:db:de:fa:d0:bc:fb:5a:7b:17:bd:9e:56:09:24:94 +# SHA256 Fingerprint: 8d:25:cd:97:22:9d:bf:70:35:6b:da:4e:b3:cc:73:40:31:e2:4c:f0:0f:af:cf:d3:2d:c7:6e:b5:84:1c:7e:a8 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3LvCvpt +nfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY +6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAu +MC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7k +RXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXuPuWg +f9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1mKPV ++3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K8Yzo +dDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RW +Ir9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKa +G73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCq +gc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBAB/Kzt3H +vqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 +0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyC +B19m3H0Q/gxhswWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2u +NmSRXbBoGOqKYcl3qJfEycel/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMg +yALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVnjWQye+mew4K6Ki3pHrTgSAai/Gev +HyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y59PYjJbigapordwj6 +xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M7YNR +TOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924Sg +JPFI/2R80L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV +7LXTWtiBmelDGDfrs7vRWGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl +6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R3 O=Google Trust Services LLC +# Subject: CN=GTS Root R3 O=Google Trust Services LLC +# Label: "GTS Root R3" +# Serial: 159662495401136852707857743206 +# MD5 Fingerprint: 3e:e7:9d:58:02:94:46:51:94:e5:e0:22:4a:8b:e7:73 +# SHA1 Fingerprint: ed:e5:71:80:2b:c8:92:b9:5b:83:3c:d2:32:68:3f:09:cd:a0:1e:46 +# SHA256 Fingerprint: 34:d8:a7:3e:e2:08:d9:bc:db:0d:95:65:20:93:4b:4e:40:e6:94:82:59:6e:8b:6f:73:c8:42:6b:01:0a:6f:48 +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout736G +jOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL2 +4CejQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7 +VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azTL818+FsuVbu/3ZL3pAzcMeGiAjEA/Jdm +ZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV11RZt+cRLInUue4X +-----END CERTIFICATE----- + +# Issuer: CN=GTS Root R4 O=Google Trust Services LLC +# Subject: CN=GTS Root R4 O=Google Trust Services LLC +# Label: "GTS Root R4" +# Serial: 159662532700760215368942768210 +# MD5 Fingerprint: 43:96:83:77:19:4d:76:b3:9d:65:52:e4:1d:22:a5:e8 +# SHA1 Fingerprint: 77:d3:03:67:b5:e0:0c:15:f6:0c:38:61:df:7c:e1:3b:92:46:4d:47 +# SHA256 Fingerprint: 34:9d:fa:40:58:c5:e2:63:12:3b:39:8a:e7:95:57:3c:4e:13:13:c8:3f:e6:8f:93:55:6c:d5:e8:03:1b:3c:7d +-----BEGIN CERTIFICATE----- +MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD +VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG +A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw +WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz +IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi +QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR +HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D +9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8 +p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD +-----END CERTIFICATE----- + +# Issuer: CN=Telia Root CA v2 O=Telia Finland Oyj +# Subject: CN=Telia Root CA v2 O=Telia Finland Oyj +# Label: "Telia Root CA v2" +# Serial: 7288924052977061235122729490515358 +# MD5 Fingerprint: 0e:8f:ac:aa:82:df:85:b1:f4:dc:10:1c:fc:99:d9:48 +# SHA1 Fingerprint: b9:99:cd:d1:73:50:8a:c4:47:05:08:9c:8c:88:fb:be:a0:2b:40:cd +# SHA256 Fingerprint: 24:2b:69:74:2f:cb:1e:5b:2a:bf:98:89:8b:94:57:21:87:54:4e:5b:4d:99:11:78:65:73:62:1f:6a:74:b8:2c +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQx +CzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UE +AwwQVGVsaWEgUm9vdCBDQSB2MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1 +NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZ +MBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ76zBq +AMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9 +vVYiQJ3q9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9 +lRdU2HhE8Qx3FZLgmEKnpNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTOD +n3WhUidhOPFZPY5Q4L15POdslv5e2QJltI5c0BE0312/UqeBAMN/mUWZFdUXyApT +7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW5olWK8jjfN7j/4nlNW4o +6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNrRBH0pUPC +TEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6 +WT0EBXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63R +DolUK5X6wK0dmBR4M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZI +pEYslOqodmJHixBTB0hXbOKSTbauBcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGj +YzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7Wxy+G2CQ5MB0GA1UdDgQWBBRy +rOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw +AwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ +8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi +0f6X+J8wfBj5tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMM +A8iZGok1GTzTyVR8qPAs5m4HeW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBS +SRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+Cy748fdHif64W1lZYudogsYMVoe+K +TTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygCQMez2P2ccGrGKMOF +6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15h2Er +3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMt +Ty3EHD70sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pT +VmBds9hCG1xLEooc6+t9xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAW +ysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQraVplI/owd8k+BsHMYeB2F326CjYSlKA +rBPuUBQemMc= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST BR Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST BR Root CA 1 2020" +# Serial: 165870826978392376648679885835942448534 +# MD5 Fingerprint: b5:aa:4b:d5:ed:f7:e3:55:2e:8f:72:0a:f3:75:b8:ed +# SHA1 Fingerprint: 1f:5b:98:f0:e3:b5:f7:74:3c:ed:e6:b0:36:7d:32:cd:f4:09:41:67 +# SHA256 Fingerprint: e5:9a:aa:81:60:09:c2:2b:ff:5b:25:ba:d3:7d:f3:06:f0:49:79:7c:1f:81:d8:5a:b0:89:e6:57:bd:8f:00:44 +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEJSIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5 +NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7dPYS +zuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0 +QVK5buXuQqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/ +VbNafAkl1bK6CKBrqx9tMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2JyX3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFW +wKrY7RjEsK70PvomAjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHV +dWNbFJWcHwHP2NVypw87 +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Subject: CN=D-TRUST EV Root CA 1 2020 O=D-Trust GmbH +# Label: "D-TRUST EV Root CA 1 2020" +# Serial: 126288379621884218666039612629459926992 +# MD5 Fingerprint: 8c:2d:9d:70:9f:48:99:11:06:11:fb:e9:cb:30:c0:6e +# SHA1 Fingerprint: 61:db:8c:21:59:69:03:90:d8:7c:9c:12:86:54:cf:9d:3d:f4:dd:07 +# SHA256 Fingerprint: 08:17:0d:1a:a3:64:53:90:1a:2f:95:92:45:e3:47:db:0c:8d:37:ab:aa:bc:56:b8:1a:a1:00:dc:95:89:70:db +-----BEGIN CERTIFICATE----- +MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQsw +CQYDVQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRS +VVNUIEVWIFJvb3QgQ0EgMSAyMDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5 +NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAG +A1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAGByqGSM49AgEGBSuB +BAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8ZRCC +/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rD +wpdhQntJraOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3 +OqQo5FD4pPfsazK2/umLMA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6g +PKA6hjhodHRwOi8vY3JsLmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X2V2X3Jvb3Rf +Y2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVjdG9yeS5kLXRydXN0Lm5l +dC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxPPUQtVHJ1 +c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjO +PQQDAwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CA +y/m0sRtW9XLS/BnRAjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJb +gfM0agPnIjhQW+0ZT0MW +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS ECC P384 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS ECC P384 Root G5" +# Serial: 13129116028163249804115411775095713523 +# MD5 Fingerprint: d3:71:04:6a:43:1c:db:a6:59:e1:a8:a3:aa:c5:71:ed +# SHA1 Fingerprint: 17:f3:de:5e:9f:0f:19:e9:8e:f6:1f:32:26:6e:20:c4:07:ae:30:ee +# SHA256 Fingerprint: 01:8e:13:f0:77:25:32:cf:80:9b:d1:b1:72:81:86:72:83:fc:48:c6:e1:3b:e9:c6:98:12:85:4a:49:0c:1b:05 +-----BEGIN CERTIFICATE----- +MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp +Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 +MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ +bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS +7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp +0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS +B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 +BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ +LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 +DXZDjC5Ty3zfDBeWUA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Subject: CN=DigiCert TLS RSA4096 Root G5 O=DigiCert, Inc. +# Label: "DigiCert TLS RSA4096 Root G5" +# Serial: 11930366277458970227240571539258396554 +# MD5 Fingerprint: ac:fe:f7:34:96:a9:f2:b3:b4:12:4b:e4:27:41:6f:e1 +# SHA1 Fingerprint: a7:88:49:dc:5d:7c:75:8c:8c:de:39:98:56:b3:aa:d0:b2:a5:71:35 +# SHA256 Fingerprint: 37:1a:00:dc:05:33:b3:72:1a:7e:eb:40:e8:41:9e:70:79:9d:2b:0a:0f:2c:1d:80:69:31:65:f7:ce:c4:ad:75 +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBN +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMT +HERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcN +NDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQs +IEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2IFJvb3QgRzUwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS87IE+ +ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG0 +2C+JFvuUAT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgp +wgscONyfMXdcvyej/Cestyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZM +pG2T6T867jp8nVid9E6P/DsjyG244gXazOvswzH016cpVIDPRFtMbzCe88zdH5RD +nU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnVDdXifBBiqmvwPXbzP6Po +sMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9qTXeXAaDx +Zre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cd +Lvvyz6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvX +KyY//SovcfXWJL5/MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNe +XoVPzthwiHvOAbWWl9fNff2C+MIkwcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPL +tgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4EFgQUUTMc7TZArxfTJc1paPKv +TiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN +AQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw +GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7H +PNtQOa27PShNlnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLF +O4uJ+DQtpBflF+aZfTCIITfNMBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQ +REtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/u4cnYiWB39yhL/btp/96j1EuMPik +AdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9GOUrYU9DzLjtxpdRv +/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh47a+ +p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilw +MUc/dNAUFvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WF +qUITVuwhd4GTWgzqltlJyqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCK +ovfepEWFJqgejF0pW8hL2JpqA15w8oVPbEtoL8pU9ozaMv7Da4M/OMZ+ +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root R1 O=Certainly +# Subject: CN=Certainly Root R1 O=Certainly +# Label: "Certainly Root R1" +# Serial: 188833316161142517227353805653483829216 +# MD5 Fingerprint: 07:70:d4:3e:82:87:a0:fa:33:36:13:f4:fa:33:e7:12 +# SHA1 Fingerprint: a0:50:ee:0f:28:71:f4:27:b2:12:6d:6f:50:96:25:ba:cc:86:42:af +# SHA256 Fingerprint: 77:b8:2c:d8:64:4c:43:05:f7:ac:c5:cb:15:6b:45:67:50:04:03:3d:51:c6:0c:62:02:a8:e0:c3:34:67:d3:a0 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw +PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy +dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9 +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0 +YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2 +1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT +vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed +aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0 +1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5 +r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5 +cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ +wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ +6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA +2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH +Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR +eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u +d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr +PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d +8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi +1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd +rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di +taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7 +lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj +yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn +Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy +yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n +wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6 +OV+KmalBWQewLK8= +-----END CERTIFICATE----- + +# Issuer: CN=Certainly Root E1 O=Certainly +# Subject: CN=Certainly Root E1 O=Certainly +# Label: "Certainly Root E1" +# Serial: 8168531406727139161245376702891150584 +# MD5 Fingerprint: 0a:9e:ca:cd:3e:52:50:c6:36:f3:4b:a3:ed:a7:53:e9 +# SHA1 Fingerprint: f9:e1:6d:dc:01:89:cf:d5:82:45:63:3e:c5:37:7d:c2:eb:93:6f:2b +# SHA256 Fingerprint: b4:58:5f:22:e4:ac:75:6a:4e:86:12:a1:36:1c:5d:9d:03:1a:93:fd:84:fe:bb:77:8f:a3:06:8b:0f:c4:2d:c2 +-----BEGIN CERTIFICATE----- +MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw +CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu +bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ +BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s +eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK ++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2 +QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4 +hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm +ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG +BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication RootCA3 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication RootCA3" +# Serial: 16247922307909811815 +# MD5 Fingerprint: 1c:9a:16:ff:9e:5c:e0:4d:8a:14:01:f4:35:5d:29:26 +# SHA1 Fingerprint: c3:03:c8:22:74:92:e5:61:a2:9c:5f:79:91:2b:1e:44:13:91:30:3a +# SHA256 Fingerprint: 24:a5:5c:2a:b0:51:44:2d:06:17:76:65:41:23:9a:4a:d0:32:d7:c5:51:75:aa:34:ff:de:2f:bc:4f:5c:52:94 +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQDEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2 +MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UEAxMeU2VjdXJpdHkg +Q29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4r +CmDvu20rhvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzA +lrenfna84xtSGc4RHwsENPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MG +TfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF7 +9+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGmnpjKIG58u4iFW/vAEGK7 +8vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtYXLVqAvO4 +g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3we +GVPKp7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst ++3A7caoreyYn8xrC3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M +0V9hvqG8OmpI6iZVIhZdXw3/JzOfGAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQ +T9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0VcwCBEF/VfR2ccCAwEAAaNCMEAw +HQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PA +FNr0Y/Dq9HHuTofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd +9XbXv8S2gVj/yP9kaWJ5rW4OH3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQI +UYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASxYfQAW0q3nHE3GYV5v4GwxxMOdnE+ +OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZXSEIx2C/pHF7uNke +gr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml+LLf +iAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUV +nuiZIesnKwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD +2NCcnWXL0CsnMQMeNuE9dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI// +1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm6Vwdp6POXiUyK+OVrCoHzrQoeIY8Laad +TdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +# Issuer: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Subject: CN=Security Communication ECC RootCA1 O=SECOM Trust Systems CO.,LTD. +# Label: "Security Communication ECC RootCA1" +# Serial: 15446673492073852651 +# MD5 Fingerprint: 7e:43:b0:92:68:ec:05:43:4c:98:ab:5d:35:2e:7e:86 +# SHA1 Fingerprint: b8:0e:26:a9:bf:d2:b2:3b:c0:ef:46:c9:ba:c7:bb:f6:1d:0d:41:41 +# SHA256 Fingerprint: e7:4f:bd:a5:5b:d5:64:c4:73:a3:6b:44:1a:a7:99:c8:a6:8e:07:74:40:e8:28:8b:9f:a1:e5:0e:4b:ba:ca:11 +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYT +AkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYD +VQQDEyJTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYx +NjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTELMAkGA1UEBhMCSlAxJTAjBgNVBAoT +HFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNVBAMTIlNlY3VyaXR5 +IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNi +AASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+Cnnfdl +dB9sELLo5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpK +ULGjQjBAMB0GA1UdDgQWBBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu +9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3LsnNdo4gIxwwCMQDAqy0O +be0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70eN9k= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA1 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA1" +# Serial: 113562791157148395269083148143378328608 +# MD5 Fingerprint: 42:32:99:76:43:33:36:24:35:07:82:9b:28:f9:d0:90 +# SHA1 Fingerprint: d5:ec:8d:7b:4c:ba:79:f4:e7:e8:cb:9d:6b:ae:77:83:10:03:21:6a +# SHA256 Fingerprint: f3:89:6f:88:fe:7c:0a:88:27:66:a7:fa:6a:d2:74:9f:b5:7a:7f:3e:98:fb:76:9c:1f:a7:b0:9c:2c:44:d5:ae +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBU +MQswCQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRI +T1JJVFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAz +MTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJF +SUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2Jh +bCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFmCL3Z +xRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZ +spDyRhySsTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O5 +58dnJCNPYwpj9mZ9S1WnP3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgR +at7GGPZHOiJBhyL8xIkoVNiMpTAK+BcWyqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll +5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRjeulumijWML3mG90Vr4Tq +nMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNnMoH1V6XK +V0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/ +pj+bOT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZO +z2nxbkRs1CTqjSShGL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXn +jSXWgXSHRtQpdaJCbPdzied9v3pKH9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+ +WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMBAAGjQjBAMB0GA1UdDgQWBBTF +7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 +YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3Kli +awLwQ8hOnThJdMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u ++2D2/VnGKhs/I0qUJDAnyIm860Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88 +X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuhTaRjAv04l5U/BXCga99igUOLtFkN +SoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW4AB+dAb/OMRyHdOo +P2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmpGQrI ++pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRz +znfSxqxx4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9 +eVzYH6Eze9mCUAyTF6ps3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2 +YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4SSPfSKcOYKMryMguTjClPPGAyzQWWYezy +r/6zcCwupvI= +-----END CERTIFICATE----- + +# Issuer: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Subject: CN=BJCA Global Root CA2 O=BEIJING CERTIFICATE AUTHORITY +# Label: "BJCA Global Root CA2" +# Serial: 58605626836079930195615843123109055211 +# MD5 Fingerprint: 5e:0a:f6:47:5f:a6:14:e8:11:01:95:3f:4d:01:eb:3c +# SHA1 Fingerprint: f4:27:86:eb:6e:b8:6d:88:31:67:02:fb:ba:66:a4:53:00:aa:7a:a6 +# SHA256 Fingerprint: 57:4d:f6:93:1e:27:80:39:66:7b:72:0a:fd:c1:60:0f:c2:7e:b6:6d:d3:09:29:79:fb:73:85:64:87:21:28:82 +-----BEGIN CERTIFICATE----- +MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQsw +CQYDVQQGEwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJ +VFkxHTAbBgNVBAMMFEJKQ0EgR2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgy +MVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJ +TkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRCSkNBIEdsb2JhbCBS +b290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jlSR9B +IgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK+ ++kpRuDCK/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJK +sVF/BvDRgh9Obl+rg/xI1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA +94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8gUXOQwKhbYdDFUDn9hf7B +43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root E46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root E46" +# Serial: 88989738453351742415770396670917916916 +# MD5 Fingerprint: 28:23:f8:b2:98:5c:37:16:3b:3e:46:13:4e:b0:b3:01 +# SHA1 Fingerprint: ec:8a:39:6c:40:f0:2e:bc:42:75:d4:9f:ab:1c:1a:5b:67:be:d2:9a +# SHA256 Fingerprint: c9:0f:26:f0:fb:1b:40:18:b2:22:27:51:9b:5c:a2:b5:3e:2c:a5:b3:be:5c:f1:8e:fe:1b:ef:47:38:0c:53:83 +-----BEGIN CERTIFICATE----- +MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQsw +CQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T +ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcN +MjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYG +A1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT +ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccC +WvkEN/U0NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+ +6xnOQ6OjQjBAMB0GA1UdDgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8B +Af8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNnADBkAjAn7qRa +qCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RHlAFWovgzJQxC36oCMB3q +4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21USAGKcw== +-----END CERTIFICATE----- + +# Issuer: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Subject: CN=Sectigo Public Server Authentication Root R46 O=Sectigo Limited +# Label: "Sectigo Public Server Authentication Root R46" +# Serial: 156256931880233212765902055439220583700 +# MD5 Fingerprint: 32:10:09:52:00:d5:7e:6c:43:df:15:c0:b1:16:93:e5 +# SHA1 Fingerprint: ad:98:f9:f3:e4:7d:75:3b:65:d4:82:b3:a4:52:17:bb:6e:f5:e4:38 +# SHA256 Fingerprint: 7b:b6:47:a6:2a:ee:ac:88:bf:25:7a:a5:22:d0:1f:fe:a3:95:e0:ab:45:c7:3f:93:f6:56:54:ec:38:f2:5a:06 +-----BEGIN CERTIFICATE----- +MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBf +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQD +Ey1TZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYw +HhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5WjBfMQswCQYDVQQGEwJHQjEY +MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1Ymxp +YyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDa +ef0rty2k1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnz +SDBh+oF8HqcIStw+KxwfGExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xf +iOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMPFF1bFOdLvt30yNoDN9HWOaEhUTCDsG3X +ME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vuZDCQOc2TZYEhMbUjUDM3 +IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5QazYw6A3OAS +VYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgE +SJ/AwSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu ++Zd4KKTIRJLpfSYFplhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt +8uaZFURww3y8nDnAtOFr94MlI1fZEoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+L +HaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW6aWWrL3DkJiy4Pmi1KZHQ3xt +zwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWIIUkwDgYDVR0P +AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c +mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQ +YKlJfp/imTYpE0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52 +gDY9hAaLMyZlbcp+nv4fjFg4exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZA +Fv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M0ejf5lG5Nkc/kLnHvALcWxxPDkjB +JYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI84HxZmduTILA7rpX +DhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9mpFui +TdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5 +dHn5HrwdVw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65 +LvKRRFHQV80MNNVIIb/bE/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp +0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmmJ1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAY +QqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS RSA Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS RSA Root CA 2022" +# Serial: 148535279242832292258835760425842727825 +# MD5 Fingerprint: d8:4e:c6:59:30:d8:fe:a0:d6:7a:5a:2c:2c:69:78:da +# SHA1 Fingerprint: ec:2c:83:40:72:af:26:95:10:ff:0e:f2:03:ee:31:70:f6:78:9d:ca +# SHA256 Fingerprint: 8f:af:7d:2e:2c:b4:70:9b:b8:e0:b3:36:66:bf:75:a5:dd:45:b5:de:48:0f:8e:a8:d4:bf:e6:be:bc:17:f2:ed +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBO +MQswCQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQD +DBxTU0wuY29tIFRMUyBSU0EgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloX +DTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jw +b3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJvb3QgQ0EgMjAyMjCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u9nTP +L3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OY +t6/wNr/y7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0ins +S657Lb85/bRi3pZ7QcacoOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3 +PnxEX4MN8/HdIGkWCVDi1FW24IBydm5MR7d1VVm0U3TZlMZBrViKMWYPHqIbKUBO +L9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDGD6C1vBdOSHtRwvzpXGk3 +R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEWTO6Af77w +dr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS ++YCk8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYS +d66UNHsef8JmAOSqg+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoG +AtUjHBPW6dvbxrB6y3snm/vg1UYk7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2f +gTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsuN+7jhHonLs0Z +NbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt +hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsM +QtfhWsSWTVTNj8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvf +R4iyrT7gJ4eLSYwfqUdYe5byiB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJ +DPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjUo3KUQyxi4U5cMj29TH0ZR6LDSeeW +P4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqoENjwuSfr98t67wVy +lrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7EgkaibMOlq +bLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2w +AgDHbICivRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3q +r5nsLFR+jM4uElZI7xc7P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sji +Mho6/4UIyYOf8kpIEFR3N+2ivEC+5BB09+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU +98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Subject: CN=SSL.com TLS ECC Root CA 2022 O=SSL Corporation +# Label: "SSL.com TLS ECC Root CA 2022" +# Serial: 26605119622390491762507526719404364228 +# MD5 Fingerprint: 99:d7:5c:f1:51:36:cc:e9:ce:d9:19:2e:77:71:56:c5 +# SHA1 Fingerprint: 9f:5f:d9:1a:54:6d:f5:0c:71:f0:ee:7a:bd:17:49:98:84:73:e2:39 +# SHA256 Fingerprint: c3:2f:fd:9f:46:f9:36:d1:6c:36:73:99:09:59:43:4b:9a:d6:0a:af:bb:9e:7c:f3:36:54:f1:44:cc:1b:a1:43 +-----BEGIN CERTIFICATE----- +MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQsw +CQYDVQQGEwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxT +U0wuY29tIFRMUyBFQ0MgUm9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2 +MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3Jh +dGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3QgQ0EgMjAyMjB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWyJGYm +acCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFN +SeR7T5v15wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +GDAWgBSJjy+j6CugFFR781a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NW +uCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp +15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w7deedWo1dlJF4AIxAMeN +b0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5Zn6g6g== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA ECC TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA ECC TLS 2021" +# Serial: 81873346711060652204712539181482831616 +# MD5 Fingerprint: 16:9f:ad:f1:70:ad:79:d6:ed:29:b4:d1:c5:79:70:a8 +# SHA1 Fingerprint: 9e:bc:75:10:42:b3:02:f3:81:f4:f7:30:62:d4:8f:c3:a7:51:b2:dd +# SHA256 Fingerprint: b2:fa:e5:3e:14:cc:d7:ab:92:12:06:47:01:ae:27:9c:1d:89:88:fa:cb:77:5f:a8:a0:08:91:4e:66:39:88:a8 +-----BEGIN CERTIFICATE----- +MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4w +LAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0w +CwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0 +MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBF +Q0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6KDP/X +tXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4 +AjJn8ZQSb+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2 +KCXWfeBmmnoJsmo7jjPXNtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMD +aAAwZQIwW5kp85wxtolrbNa9d+F851F+uDrNozZffPc8dz7kUK2o59JZDCaOMDtu +CCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGYa3cpetskz2VAv9LcjBHo +9H1/IISpQuQo +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Subject: CN=Atos TrustedRoot Root CA RSA TLS 2021 O=Atos +# Label: "Atos TrustedRoot Root CA RSA TLS 2021" +# Serial: 111436099570196163832749341232207667876 +# MD5 Fingerprint: d4:d3:46:b8:9a:c0:9c:76:5d:9e:3a:c3:b9:99:31:d2 +# SHA1 Fingerprint: 18:52:3b:0d:06:37:e4:d6:3a:df:23:e4:98:fb:5b:16:fb:86:74:48 +# SHA256 Fingerprint: 81:a9:08:8e:a5:9f:b3:64:c5:48:a6:f8:55:59:09:9b:6f:04:05:ef:bf:18:e5:32:4e:c9:f4:57:ba:00:11:2f +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBM +MS4wLAYDVQQDDCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIx +MQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00 +MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0b3MgVHJ1c3RlZFJvb3QgUm9vdCBD +QSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYTAkRFMIICIjAN +BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BBl01Z +4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYv +Ye+W/CBGvevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZ +kmGbzSoXfduP9LVq6hdKZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDs +GY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt0xU6kGpn8bRrZtkh68rZYnxGEFzedUln +nkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVKPNe0OwANwI8f4UDErmwh +3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMYsluMWuPD +0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzy +geBYBr3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8 +ANSbhqRAvNncTFd+rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezB +c6eUWsuSZIKmAMFwoW4sKeFYV+xafJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lI +pw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU +dEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +DAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS +4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPs +o0UvFJ/1TCplQ3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJ +qM7F78PRreBrAwA0JrRUITWXAdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuyw +xfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9GslA9hGCZcbUztVdF5kJHdWoOsAgM +rr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2VktafcxBPTy+av5EzH4 +AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9qTFsR +0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuY +o7Ey7Nmj1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5 +dDTedk+SKlOxJTnbPP/lPqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcE +oji2jbDwN/zIIX8/syQbPYtuzE2wFg2WHYMfRsCbvUOZ58SWLs5fyQ== +-----END CERTIFICATE----- diff --git a/.venv/Lib/site-packages/certifi/core.py b/.venv/Lib/site-packages/certifi/core.py new file mode 100644 index 0000000..de02898 --- /dev/null +++ b/.venv/Lib/site-packages/certifi/core.py @@ -0,0 +1,108 @@ +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem or its contents. +""" +import sys + + +if sys.version_info >= (3, 11): + + from importlib.resources import as_file, files + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem")) + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii") + +elif sys.version_info >= (3, 7): + + from importlib.resources import path as get_path, read_text + + _CACERT_CTX = None + _CACERT_PATH = None + + def where() -> str: + # This is slightly terrible, but we want to delay extracting the + # file in cases where we're inside of a zipimport situation until + # someone actually calls where(), but we don't want to re-extract + # the file on every call of where(), so we'll do it once then store + # it in a global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you + # to manage the cleanup of this file, so it doesn't actually + # return a path, it returns a context manager that will give + # you the path when you enter it and will do any cleanup when + # you leave it. In the common case of not needing a temporary + # file, it will just return the file system location and the + # __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") + +else: + import os + import types + from typing import Union + + Package = Union[types.ModuleType, str] + Resource = Union[str, "os.PathLike"] + + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text( + package: Package, + resource: Resource, + encoding: str = 'utf-8', + errors: str = 'strict' + ) -> str: + with open(where(), encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where() -> str: + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + def contents() -> str: + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/.venv/Lib/site-packages/certifi/py.typed b/.venv/Lib/site-packages/certifi/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE new file mode 100644 index 0000000..ad82355 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 TAHRI Ahmed R. + +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. \ No newline at end of file diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/METADATA b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/METADATA new file mode 100644 index 0000000..ad5158c --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/METADATA @@ -0,0 +1,668 @@ +Metadata-Version: 2.1 +Name: charset-normalizer +Version: 3.3.0 +Summary: The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet. +Home-page: https://github.com/Ousret/charset_normalizer +Author: Ahmed TAHRI +Author-email: ahmed.tahri@cloudnursery.dev +License: MIT +Project-URL: Bug Reports, https://github.com/Ousret/charset_normalizer/issues +Project-URL: Documentation, https://charset-normalizer.readthedocs.io/en/latest +Keywords: encoding,charset,charset-detector,detector,normalization,unicode,chardet,detect +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Intended Audience :: Developers +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Text Processing :: Linguistic +Classifier: Topic :: Utilities +Classifier: Typing :: Typed +Requires-Python: >=3.7.0 +Description-Content-Type: text/markdown +License-File: LICENSE +Provides-Extra: unicode_backport + +

Charset Detection, for Everyone 👋

+ +

+ The Real First Universal Charset Detector
+ + + + + Download Count Total + + + + +

+

+ Featured Packages
+ + Static Badge + + + Static Badge + +

+

+ In other language (unofficial port - by the community)
+ + Static Badge + +

+ +> A library that helps you read text from an unknown charset encoding.
Motivated by `chardet`, +> I'm trying to resolve the issue by taking a new approach. +> All IANA character set names for which the Python core library provides codecs are supported. + +

+ >>>>> 👉 Try Me Online Now, Then Adopt Me 👈 <<<<< +

+ +This project offers you an alternative to **Universal Charset Encoding Detector**, also known as **Chardet**. + +| Feature | [Chardet](https://github.com/chardet/chardet) | Charset Normalizer | [cChardet](https://github.com/PyYoshi/cChardet) | +|--------------------------------------------------|:---------------------------------------------:|:--------------------------------------------------------------------------------------------------:|:-----------------------------------------------:| +| `Fast` | ❌ | ✅ | ✅ | +| `Universal**` | ❌ | ✅ | ❌ | +| `Reliable` **without** distinguishable standards | ❌ | ✅ | ✅ | +| `Reliable` **with** distinguishable standards | ✅ | ✅ | ✅ | +| `License` | LGPL-2.1
_restrictive_ | MIT | MPL-1.1
_restrictive_ | +| `Native Python` | ✅ | ✅ | ❌ | +| `Detect spoken language` | ❌ | ✅ | N/A | +| `UnicodeDecodeError Safety` | ❌ | ✅ | ❌ | +| `Whl Size (min)` | 193.6 kB | 42 kB | ~200 kB | +| `Supported Encoding` | 33 | 🎉 [99](https://charset-normalizer.readthedocs.io/en/latest/user/support.html#supported-encodings) | 40 | + +

+Reading Normalized TextCat Reading Text +

+ +*\*\* : They are clearly using specific code for a specific encoding even if covering most of used one*
+Did you got there because of the logs? See [https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html](https://charset-normalizer.readthedocs.io/en/latest/user/miscellaneous.html) + +## ⚡ Performance + +This package offer better performance than its counterpart Chardet. Here are some numbers. + +| Package | Accuracy | Mean per file (ms) | File per sec (est) | +|-----------------------------------------------|:--------:|:------------------:|:------------------:| +| [chardet](https://github.com/chardet/chardet) | 86 % | 200 ms | 5 file/sec | +| charset-normalizer | **98 %** | **10 ms** | 100 file/sec | + +| Package | 99th percentile | 95th percentile | 50th percentile | +|-----------------------------------------------|:---------------:|:---------------:|:---------------:| +| [chardet](https://github.com/chardet/chardet) | 1200 ms | 287 ms | 23 ms | +| charset-normalizer | 100 ms | 50 ms | 5 ms | + +Chardet's performance on larger file (1MB+) are very poor. Expect huge difference on large payload. + +> Stats are generated using 400+ files using default parameters. More details on used files, see GHA workflows. +> And yes, these results might change at any time. The dataset can be updated to include more files. +> The actual delays heavily depends on your CPU capabilities. The factors should remain the same. +> Keep in mind that the stats are generous and that Chardet accuracy vs our is measured using Chardet initial capability +> (eg. Supported Encoding) Challenge-them if you want. + +## ✨ Installation + +Using pip: + +```sh +pip install charset-normalizer -U +``` + +## 🚀 Basic Usage + +### CLI +This package comes with a CLI. + +``` +usage: normalizer [-h] [-v] [-a] [-n] [-m] [-r] [-f] [-t THRESHOLD] + file [file ...] + +The Real First Universal Charset Detector. Discover originating encoding used +on text file. Normalize text to unicode. + +positional arguments: + files File(s) to be analysed + +optional arguments: + -h, --help show this help message and exit + -v, --verbose Display complementary information about file if any. + Stdout will contain logs about the detection process. + -a, --with-alternative + Output complementary possibilities if any. Top-level + JSON WILL be a list. + -n, --normalize Permit to normalize input file. If not set, program + does not write anything. + -m, --minimal Only output the charset detected to STDOUT. Disabling + JSON output. + -r, --replace Replace file when trying to normalize it instead of + creating a new one. + -f, --force Replace file without asking if you are sure, use this + flag with caution. + -t THRESHOLD, --threshold THRESHOLD + Define a custom maximum amount of chaos allowed in + decoded content. 0. <= chaos <= 1. + --version Show version information and exit. +``` + +```bash +normalizer ./data/sample.1.fr.srt +``` + +or + +```bash +python -m charset_normalizer ./data/sample.1.fr.srt +``` + +🎉 Since version 1.4.0 the CLI produce easily usable stdout result in JSON format. + +```json +{ + "path": "/home/default/projects/charset_normalizer/data/sample.1.fr.srt", + "encoding": "cp1252", + "encoding_aliases": [ + "1252", + "windows_1252" + ], + "alternative_encodings": [ + "cp1254", + "cp1256", + "cp1258", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + "mbcs" + ], + "language": "French", + "alphabets": [ + "Basic Latin", + "Latin-1 Supplement" + ], + "has_sig_or_bom": false, + "chaos": 0.149, + "coherence": 97.152, + "unicode_path": null, + "is_preferred": true +} +``` + +### Python +*Just print out normalized text* +```python +from charset_normalizer import from_path + +results = from_path('./my_subtitle.srt') + +print(str(results.best())) +``` + +*Upgrade your code without effort* +```python +from charset_normalizer import detect +``` + +The above code will behave the same as **chardet**. We ensure that we offer the best (reasonable) BC result possible. + +See the docs for advanced usage : [readthedocs.io](https://charset-normalizer.readthedocs.io/en/latest/) + +## 😇 Why + +When I started using Chardet, I noticed that it was not suited to my expectations, and I wanted to propose a +reliable alternative using a completely different method. Also! I never back down on a good challenge! + +I **don't care** about the **originating charset** encoding, because **two different tables** can +produce **two identical rendered string.** +What I want is to get readable text, the best I can. + +In a way, **I'm brute forcing text decoding.** How cool is that ? 😎 + +Don't confuse package **ftfy** with charset-normalizer or chardet. ftfy goal is to repair unicode string whereas charset-normalizer to convert raw file in unknown encoding to unicode. + +## 🍰 How + + - Discard all charset encoding table that could not fit the binary content. + - Measure noise, or the mess once opened (by chunks) with a corresponding charset encoding. + - Extract matches with the lowest mess detected. + - Additionally, we measure coherence / probe for a language. + +**Wait a minute**, what is noise/mess and coherence according to **YOU ?** + +*Noise :* I opened hundred of text files, **written by humans**, with the wrong encoding table. **I observed**, then +**I established** some ground rules about **what is obvious** when **it seems like** a mess. + I know that my interpretation of what is noise is probably incomplete, feel free to contribute in order to + improve or rewrite it. + +*Coherence :* For each language there is on earth, we have computed ranked letter appearance occurrences (the best we can). So I thought +that intel is worth something here. So I use those records against decoded text to check if I can detect intelligent design. + +## ⚡ Known limitations + + - Language detection is unreliable when text contains two or more languages sharing identical letters. (eg. HTML (english tags) + Turkish content (Sharing Latin characters)) + - Every charset detector heavily depends on sufficient content. In common cases, do not bother run detection on very tiny content. + +## ⚠️ About Python EOLs + +**If you are running:** + +- Python >=2.7,<3.5: Unsupported +- Python 3.5: charset-normalizer < 2.1 +- Python 3.6: charset-normalizer < 3.1 +- Python 3.7: charset-normalizer < 4.0 + +Upgrade your Python interpreter as soon as possible. + +## 👤 Contributing + +Contributions, issues and feature requests are very much welcome.
+Feel free to check [issues page](https://github.com/ousret/charset_normalizer/issues) if you want to contribute. + +## 📝 License + +Copyright © [Ahmed TAHRI @Ousret](https://github.com/Ousret).
+This project is [MIT](https://github.com/Ousret/charset_normalizer/blob/master/LICENSE) licensed. + +Characters frequencies used in this project © 2012 [Denny Vrandečić](http://simia.net/letters/) + +## 💼 For Enterprise + +Professional support for charset-normalizer is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-charset-normalizer?utm_source=pypi-charset-normalizer&utm_medium=readme + +# Changelog +All notable changes to charset-normalizer will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [3.3.0](https://github.com/Ousret/charset_normalizer/compare/3.2.0...3.3.0) (2023-09-30) + +### Added +- Allow to execute the CLI (e.g. normalizer) through `python -m charset_normalizer.cli` or `python -m charset_normalizer` +- Support for 9 forgotten encoding that are supported by Python but unlisted in `encoding.aliases` as they have no alias (#323) + +### Removed +- (internal) Redundant utils.is_ascii function and unused function is_private_use_only +- (internal) charset_normalizer.assets is moved inside charset_normalizer.constant + +### Changed +- (internal) Unicode code blocks in constants are updated using the latest v15.0.0 definition to improve detection +- Optional mypyc compilation upgraded to version 1.5.1 for Python >= 3.7 + +### Fixed +- Unable to properly sort CharsetMatch when both chaos/noise and coherence were close due to an unreachable condition in \_\_lt\_\_ (#350) + +## [3.2.0](https://github.com/Ousret/charset_normalizer/compare/3.1.0...3.2.0) (2023-06-07) + +### Changed +- Typehint for function `from_path` no longer enforce `PathLike` as its first argument +- Minor improvement over the global detection reliability + +### Added +- Introduce function `is_binary` that relies on main capabilities, and optimized to detect binaries +- Propagate `enable_fallback` argument throughout `from_bytes`, `from_path`, and `from_fp` that allow a deeper control over the detection (default True) +- Explicit support for Python 3.12 + +### Fixed +- Edge case detection failure where a file would contain 'very-long' camel cased word (Issue #289) + +## [3.1.0](https://github.com/Ousret/charset_normalizer/compare/3.0.1...3.1.0) (2023-03-06) + +### Added +- Argument `should_rename_legacy` for legacy function `detect` and disregard any new arguments without errors (PR #262) + +### Removed +- Support for Python 3.6 (PR #260) + +### Changed +- Optional speedup provided by mypy/c 1.0.1 + +## [3.0.1](https://github.com/Ousret/charset_normalizer/compare/3.0.0...3.0.1) (2022-11-18) + +### Fixed +- Multi-bytes cutter/chunk generator did not always cut correctly (PR #233) + +### Changed +- Speedup provided by mypy/c 0.990 on Python >= 3.7 + +## [3.0.0](https://github.com/Ousret/charset_normalizer/compare/2.1.1...3.0.0) (2022-10-20) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it +- Sphinx warnings when generating the documentation + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [3.0.0rc1](https://github.com/Ousret/charset_normalizer/compare/3.0.0b2...3.0.0rc1) (2022-10-18) + +### Added +- Extend the capability of explain=True when cp_isolation contains at most two entries (min one), will log in details of the Mess-detector results +- Support for alternative language frequency set in charset_normalizer.assets.FREQUENCIES +- Add parameter `language_threshold` in `from_bytes`, `from_path` and `from_fp` to adjust the minimum expected coherence ratio + +### Changed +- Build with static metadata using 'build' frontend +- Make the language detection stricter + +### Fixed +- CLI with opt --normalize fail when using full path for files +- TooManyAccentuatedPlugin induce false positive on the mess detection when too few alpha character have been fed to it + +### Removed +- Coherence detector no longer return 'Simple English' instead return 'English' +- Coherence detector no longer return 'Classical Chinese' instead return 'Chinese' + +## [3.0.0b2](https://github.com/Ousret/charset_normalizer/compare/3.0.0b1...3.0.0b2) (2022-08-21) + +### Added +- `normalizer --version` now specify if current version provide extra speedup (meaning mypyc compilation whl) + +### Removed +- Breaking: Method `first()` and `best()` from CharsetMatch +- UTF-7 will no longer appear as "detected" without a recognized SIG/mark (is unreliable/conflict with ASCII) + +### Fixed +- Sphinx warnings when generating the documentation + +## [3.0.0b1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...3.0.0b1) (2022-08-15) + +### Changed +- Optional: Module `md.py` can be compiled using Mypyc to provide an extra speedup up to 4x faster than v2.1 + +### Removed +- Breaking: Class aliases CharsetDetector, CharsetDoctor, CharsetNormalizerMatch and CharsetNormalizerMatches +- Breaking: Top-level function `normalize` +- Breaking: Properties `chaos_secondary_pass`, `coherence_non_latin` and `w_counter` from CharsetMatch +- Support for the backport `unicodedata2` + +## [2.1.1](https://github.com/Ousret/charset_normalizer/compare/2.1.0...2.1.1) (2022-08-19) + +### Deprecated +- Function `normalize` scheduled for removal in 3.0 + +### Changed +- Removed useless call to decode in fn is_unprintable (#206) + +### Fixed +- Third-party library (i18n xgettext) crashing not recognizing utf_8 (PEP 263) with underscore from [@aleksandernovikov](https://github.com/aleksandernovikov) (#204) + +## [2.1.0](https://github.com/Ousret/charset_normalizer/compare/2.0.12...2.1.0) (2022-06-19) + +### Added +- Output the Unicode table version when running the CLI with `--version` (PR #194) + +### Changed +- Re-use decoded buffer for single byte character sets from [@nijel](https://github.com/nijel) (PR #175) +- Fixing some performance bottlenecks from [@deedy5](https://github.com/deedy5) (PR #183) + +### Fixed +- Workaround potential bug in cpython with Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space (PR #175) +- CLI default threshold aligned with the API threshold from [@oleksandr-kuzmenko](https://github.com/oleksandr-kuzmenko) (PR #181) + +### Removed +- Support for Python 3.5 (PR #192) + +### Deprecated +- Use of backport unicodedata from `unicodedata2` as Python is quickly catching up, scheduled for removal in 3.0 (PR #194) + +## [2.0.12](https://github.com/Ousret/charset_normalizer/compare/2.0.11...2.0.12) (2022-02-12) + +### Fixed +- ASCII miss-detection on rare cases (PR #170) + +## [2.0.11](https://github.com/Ousret/charset_normalizer/compare/2.0.10...2.0.11) (2022-01-30) + +### Added +- Explicit support for Python 3.11 (PR #164) + +### Changed +- The logging behavior have been completely reviewed, now using only TRACE and DEBUG levels (PR #163 #165) + +## [2.0.10](https://github.com/Ousret/charset_normalizer/compare/2.0.9...2.0.10) (2022-01-04) + +### Fixed +- Fallback match entries might lead to UnicodeDecodeError for large bytes sequence (PR #154) + +### Changed +- Skipping the language-detection (CD) on ASCII (PR #155) + +## [2.0.9](https://github.com/Ousret/charset_normalizer/compare/2.0.8...2.0.9) (2021-12-03) + +### Changed +- Moderating the logging impact (since 2.0.8) for specific environments (PR #147) + +### Fixed +- Wrong logging level applied when setting kwarg `explain` to True (PR #146) + +## [2.0.8](https://github.com/Ousret/charset_normalizer/compare/2.0.7...2.0.8) (2021-11-24) +### Changed +- Improvement over Vietnamese detection (PR #126) +- MD improvement on trailing data and long foreign (non-pure latin) data (PR #124) +- Efficiency improvements in cd/alphabet_languages from [@adbar](https://github.com/adbar) (PR #122) +- call sum() without an intermediary list following PEP 289 recommendations from [@adbar](https://github.com/adbar) (PR #129) +- Code style as refactored by Sourcery-AI (PR #131) +- Minor adjustment on the MD around european words (PR #133) +- Remove and replace SRTs from assets / tests (PR #139) +- Initialize the library logger with a `NullHandler` by default from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Setting kwarg `explain` to True will add provisionally (bounded to function lifespan) a specific stream handler (PR #135) + +### Fixed +- Fix large (misleading) sequence giving UnicodeDecodeError (PR #137) +- Avoid using too insignificant chunk (PR #137) + +### Added +- Add and expose function `set_logging_handler` to configure a specific StreamHandler from [@nmaynes](https://github.com/nmaynes) (PR #135) +- Add `CHANGELOG.md` entries, format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) (PR #141) + +## [2.0.7](https://github.com/Ousret/charset_normalizer/compare/2.0.6...2.0.7) (2021-10-11) +### Added +- Add support for Kazakh (Cyrillic) language detection (PR #109) + +### Changed +- Further, improve inferring the language from a given single-byte code page (PR #112) +- Vainly trying to leverage PEP263 when PEP3120 is not supported (PR #116) +- Refactoring for potential performance improvements in loops from [@adbar](https://github.com/adbar) (PR #113) +- Various detection improvement (MD+CD) (PR #117) + +### Removed +- Remove redundant logging entry about detected language(s) (PR #115) + +### Fixed +- Fix a minor inconsistency between Python 3.5 and other versions regarding language detection (PR #117 #102) + +## [2.0.6](https://github.com/Ousret/charset_normalizer/compare/2.0.5...2.0.6) (2021-09-18) +### Fixed +- Unforeseen regression with the loss of the backward-compatibility with some older minor of Python 3.5.x (PR #100) +- Fix CLI crash when using --minimal output in certain cases (PR #103) + +### Changed +- Minor improvement to the detection efficiency (less than 1%) (PR #106 #101) + +## [2.0.5](https://github.com/Ousret/charset_normalizer/compare/2.0.4...2.0.5) (2021-09-14) +### Changed +- The project now comply with: flake8, mypy, isort and black to ensure a better overall quality (PR #81) +- The BC-support with v1.x was improved, the old staticmethods are restored (PR #82) +- The Unicode detection is slightly improved (PR #93) +- Add syntax sugar \_\_bool\_\_ for results CharsetMatches list-container (PR #91) + +### Removed +- The project no longer raise warning on tiny content given for detection, will be simply logged as warning instead (PR #92) + +### Fixed +- In some rare case, the chunks extractor could cut in the middle of a multi-byte character and could mislead the mess detection (PR #95) +- Some rare 'space' characters could trip up the UnprintablePlugin/Mess detection (PR #96) +- The MANIFEST.in was not exhaustive (PR #78) + +## [2.0.4](https://github.com/Ousret/charset_normalizer/compare/2.0.3...2.0.4) (2021-07-30) +### Fixed +- The CLI no longer raise an unexpected exception when no encoding has been found (PR #70) +- Fix accessing the 'alphabets' property when the payload contains surrogate characters (PR #68) +- The logger could mislead (explain=True) on detected languages and the impact of one MBCS match (PR #72) +- Submatch factoring could be wrong in rare edge cases (PR #72) +- Multiple files given to the CLI were ignored when publishing results to STDOUT. (After the first path) (PR #72) +- Fix line endings from CRLF to LF for certain project files (PR #67) + +### Changed +- Adjust the MD to lower the sensitivity, thus improving the global detection reliability (PR #69 #76) +- Allow fallback on specified encoding if any (PR #71) + +## [2.0.3](https://github.com/Ousret/charset_normalizer/compare/2.0.2...2.0.3) (2021-07-16) +### Changed +- Part of the detection mechanism has been improved to be less sensitive, resulting in more accurate detection results. Especially ASCII. (PR #63) +- According to the community wishes, the detection will fall back on ASCII or UTF-8 in a last-resort case. (PR #64) + +## [2.0.2](https://github.com/Ousret/charset_normalizer/compare/2.0.1...2.0.2) (2021-07-15) +### Fixed +- Empty/Too small JSON payload miss-detection fixed. Report from [@tseaver](https://github.com/tseaver) (PR #59) + +### Changed +- Don't inject unicodedata2 into sys.modules from [@akx](https://github.com/akx) (PR #57) + +## [2.0.1](https://github.com/Ousret/charset_normalizer/compare/2.0.0...2.0.1) (2021-07-13) +### Fixed +- Make it work where there isn't a filesystem available, dropping assets frequencies.json. Report from [@sethmlarson](https://github.com/sethmlarson). (PR #55) +- Using explain=False permanently disable the verbose output in the current runtime (PR #47) +- One log entry (language target preemptive) was not show in logs when using explain=True (PR #47) +- Fix undesired exception (ValueError) on getitem of instance CharsetMatches (PR #52) + +### Changed +- Public function normalize default args values were not aligned with from_bytes (PR #53) + +### Added +- You may now use charset aliases in cp_isolation and cp_exclusion arguments (PR #47) + +## [2.0.0](https://github.com/Ousret/charset_normalizer/compare/1.4.1...2.0.0) (2021-07-02) +### Changed +- 4x to 5 times faster than the previous 1.4.0 release. At least 2x faster than Chardet. +- Accent has been made on UTF-8 detection, should perform rather instantaneous. +- The backward compatibility with Chardet has been greatly improved. The legacy detect function returns an identical charset name whenever possible. +- The detection mechanism has been slightly improved, now Turkish content is detected correctly (most of the time) +- The program has been rewritten to ease the readability and maintainability. (+Using static typing)+ +- utf_7 detection has been reinstated. + +### Removed +- This package no longer require anything when used with Python 3.5 (Dropped cached_property) +- Removed support for these languages: Catalan, Esperanto, Kazakh, Baque, Volapük, Azeri, Galician, Nynorsk, Macedonian, and Serbocroatian. +- The exception hook on UnicodeDecodeError has been removed. + +### Deprecated +- Methods coherence_non_latin, w_counter, chaos_secondary_pass of the class CharsetMatch are now deprecated and scheduled for removal in v3.0 + +### Fixed +- The CLI output used the relative path of the file(s). Should be absolute. + +## [1.4.1](https://github.com/Ousret/charset_normalizer/compare/1.4.0...1.4.1) (2021-05-28) +### Fixed +- Logger configuration/usage no longer conflict with others (PR #44) + +## [1.4.0](https://github.com/Ousret/charset_normalizer/compare/1.3.9...1.4.0) (2021-05-21) +### Removed +- Using standard logging instead of using the package loguru. +- Dropping nose test framework in favor of the maintained pytest. +- Choose to not use dragonmapper package to help with gibberish Chinese/CJK text. +- Require cached_property only for Python 3.5 due to constraint. Dropping for every other interpreter version. +- Stop support for UTF-7 that does not contain a SIG. +- Dropping PrettyTable, replaced with pure JSON output in CLI. + +### Fixed +- BOM marker in a CharsetNormalizerMatch instance could be False in rare cases even if obviously present. Due to the sub-match factoring process. +- Not searching properly for the BOM when trying utf32/16 parent codec. + +### Changed +- Improving the package final size by compressing frequencies.json. +- Huge improvement over the larges payload. + +### Added +- CLI now produces JSON consumable output. +- Return ASCII if given sequences fit. Given reasonable confidence. + +## [1.3.9](https://github.com/Ousret/charset_normalizer/compare/1.3.8...1.3.9) (2021-05-13) + +### Fixed +- In some very rare cases, you may end up getting encode/decode errors due to a bad bytes payload (PR #40) + +## [1.3.8](https://github.com/Ousret/charset_normalizer/compare/1.3.7...1.3.8) (2021-05-12) + +### Fixed +- Empty given payload for detection may cause an exception if trying to access the `alphabets` property. (PR #39) + +## [1.3.7](https://github.com/Ousret/charset_normalizer/compare/1.3.6...1.3.7) (2021-05-12) + +### Fixed +- The legacy detect function should return UTF-8-SIG if sig is present in the payload. (PR #38) + +## [1.3.6](https://github.com/Ousret/charset_normalizer/compare/1.3.5...1.3.6) (2021-02-09) + +### Changed +- Amend the previous release to allow prettytable 2.0 (PR #35) + +## [1.3.5](https://github.com/Ousret/charset_normalizer/compare/1.3.4...1.3.5) (2021-02-08) + +### Fixed +- Fix error while using the package with a python pre-release interpreter (PR #33) + +### Changed +- Dependencies refactoring, constraints revised. + +### Added +- Add python 3.9 and 3.10 to the supported interpreters + +MIT License + +Copyright (c) 2019 TAHRI Ahmed R. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/RECORD b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/RECORD new file mode 100644 index 0000000..46aacee --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/RECORD @@ -0,0 +1,35 @@ +../../Scripts/normalizer.exe,sha256=y0Lvk1k5pwRgI3k2K-P8bDceYynjYyjPPiJesWtAm_k,107916 +charset_normalizer-3.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +charset_normalizer-3.3.0.dist-info/LICENSE,sha256=znnj1Var_lZ-hzOvD5W50wcQDp9qls3SD2xIau88ufc,1090 +charset_normalizer-3.3.0.dist-info/METADATA,sha256=RsHYDXsr-lzAh8nciMrJMJUZJ8xKWaW6ot7XxZnwF3U,33536 +charset_normalizer-3.3.0.dist-info/RECORD,, +charset_normalizer-3.3.0.dist-info/WHEEL,sha256=yrvteVAZzxQvtDnzdCRh4dP01sPIxYhLXIXplC7o50E,102 +charset_normalizer-3.3.0.dist-info/entry_points.txt,sha256=ADSTKrkXZ3hhdOVFi6DcUEHQRS0xfxDIE_pEz4wLIXA,65 +charset_normalizer-3.3.0.dist-info/top_level.txt,sha256=7ASyzePr8_xuZWJsnqJjIBtyV8vhEo0wBCv1MPRRi3Q,19 +charset_normalizer/__init__.py,sha256=m1cUEsb9K5v831m9P_lv2JlUEKD7MhxL7fxw3hn75o4,1623 +charset_normalizer/__main__.py,sha256=nVnMo31hTPN2Yy045GJIvHj3dKDJz4dAQR3cUSdvYyc,77 +charset_normalizer/__pycache__/__init__.cpython-310.pyc,, +charset_normalizer/__pycache__/__main__.cpython-310.pyc,, +charset_normalizer/__pycache__/api.cpython-310.pyc,, +charset_normalizer/__pycache__/cd.cpython-310.pyc,, +charset_normalizer/__pycache__/constant.cpython-310.pyc,, +charset_normalizer/__pycache__/legacy.cpython-310.pyc,, +charset_normalizer/__pycache__/md.cpython-310.pyc,, +charset_normalizer/__pycache__/models.cpython-310.pyc,, +charset_normalizer/__pycache__/utils.cpython-310.pyc,, +charset_normalizer/__pycache__/version.cpython-310.pyc,, +charset_normalizer/api.py,sha256=qFL0frUrcfcYEJmGpqoJ4Af68ToVue3f5SK1gp8UC5Q,21723 +charset_normalizer/cd.py,sha256=Yfk3sbee0Xqo1-vmQYbOqM51-SajXPLzFVG89nTsZzc,12955 +charset_normalizer/cli/__init__.py,sha256=COwP8fK2qbuldMem2lL81JieY-PIA2G2GZ5IdAPMPFA,106 +charset_normalizer/cli/__main__.py,sha256=rs-cBipBzr7d0TAaUa0nG4qrjXhdddeCVB-f6Xt_wS0,10040 +charset_normalizer/cli/__pycache__/__init__.cpython-310.pyc,, +charset_normalizer/cli/__pycache__/__main__.cpython-310.pyc,, +charset_normalizer/constant.py,sha256=2tVrXQ9cvC8jt0b8gZzRXvXte1pVbRra0A5dOWDQSao,42476 +charset_normalizer/legacy.py,sha256=KbJxEpu7g6zE2uXSB3T-3178cgiSQdVJlJmY-gv3EAM,2125 +charset_normalizer/md.cp310-win_amd64.pyd,sha256=pl39INILDt4awihp6VZ9Mf4ThFrclQAWkTBelSxID00,10752 +charset_normalizer/md.py,sha256=XHD9ZFD3Lhx-ZmeTptUQJZg06F538gF1Q9m8J-eE9iI,19249 +charset_normalizer/md__mypyc.cp310-win_amd64.pyd,sha256=RL5yOvNyiwvTxIJ4a5NW5UC61bZIOD3m1XeoqfwnIMs,113664 +charset_normalizer/models.py,sha256=GUMoL9BqGd2o844SVZSkrdWnf0nSyyJGdhMJMkMNZ68,11824 +charset_normalizer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +charset_normalizer/utils.py,sha256=e3880z-YakWwBjdzbXh9seKuRa4Tm3kqRO5BIUJjVSk,11630 +charset_normalizer/version.py,sha256=KPoL8s8b5S9fj_JNzC_5AXvb8kmxrZU8-eXSMC_2Amw,85 diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL new file mode 100644 index 0000000..49053d7 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.2) +Root-Is-Purelib: false +Tag: cp310-cp310-win_amd64 + diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt new file mode 100644 index 0000000..65619e7 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +normalizer = charset_normalizer.cli:cli_detect diff --git a/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt new file mode 100644 index 0000000..66958f0 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer-3.3.0.dist-info/top_level.txt @@ -0,0 +1 @@ +charset_normalizer diff --git a/.venv/Lib/site-packages/charset_normalizer/__init__.py b/.venv/Lib/site-packages/charset_normalizer/__init__.py new file mode 100644 index 0000000..55991fc --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/__init__.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- +""" +Charset-Normalizer +~~~~~~~~~~~~~~ +The Real First Universal Charset Detector. +A library that helps you read text from an unknown charset encoding. +Motivated by chardet, This package is trying to resolve the issue by taking a new approach. +All IANA character set names for which the Python core library provides codecs are supported. + +Basic usage: + >>> from charset_normalizer import from_bytes + >>> results = from_bytes('Bсеки човек има право на образование. Oбразованието!'.encode('utf_8')) + >>> best_guess = results.best() + >>> str(best_guess) + 'Bсеки човек има право на образование. Oбразованието!' + +Others methods and usages are available - see the full documentation +at . +:copyright: (c) 2021 by Ahmed TAHRI +:license: MIT, see LICENSE for more details. +""" +import logging + +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 +from .version import VERSION, __version__ + +__all__ = ( + "from_fp", + "from_path", + "from_bytes", + "is_binary", + "detect", + "CharsetMatch", + "CharsetMatches", + "__version__", + "VERSION", + "set_logging_handler", +) + +# Attach a NullHandler to the top level logger by default +# https://docs.python.org/3.3/howto/logging.html#configuring-logging-for-a-library + +logging.getLogger("charset_normalizer").addHandler(logging.NullHandler()) diff --git a/.venv/Lib/site-packages/charset_normalizer/__main__.py b/.venv/Lib/site-packages/charset_normalizer/__main__.py new file mode 100644 index 0000000..beae2ef --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/__main__.py @@ -0,0 +1,4 @@ +from .cli import cli_detect + +if __name__ == "__main__": + cli_detect() diff --git a/.venv/Lib/site-packages/charset_normalizer/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/charset_normalizer/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6650c49ac31d94d89fa17097fbea16a5990efef GIT binary patch literal 1578 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 K^FGpsp8J0<_D^>J literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/__pycache__/legacy.cpython-310.pyc b/.venv/Lib/site-packages/charset_normalizer/__pycache__/legacy.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a4ee1773510fca4e5e6fbaa8b6da33f1c3bf494 GIT binary patch literal 1844 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/__pycache__/models.cpython-310.pyc b/.venv/Lib/site-packages/charset_normalizer/__pycache__/models.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16154517a8ddfdb6acf4e01bccef79316cb812a2 GIT binary patch literal 11494 zcmb7KTZ|l6TJE}Z^<{cy+U>DDV>?O3x!9e=6DJ|Yn|K{NV<#~ikF&A8iyDWbrq7v~ zp6Q!URoj_%&$8>WSaDep3p^kpVG9Xl9`XPZLgE35H^eLAp@fhSNUQLK6c#qS?3(ZY zPgUQhC%eq3PMzp~#*y_*tQk-MJ~xgE1Ihqt_#!rK(y4#0}MjRG1*HY!#PjTK<*@!ZJz2*lpK-CG>{a0TS4`W*$Sm6o7I-6HP@o)PP2xp^pxLRlT|w8@ZStx z&f^IpY$H<@L!>HZ&JbS~rnH15ZDGr_NJ~dJA|tXgBkhIMYC+^g{(icW6;m=N3es7% z#k82YZ&v`ge#@*VqGd`JFe1HbihZJV-`+7Q(|EV>zF*9telX2gm{u$=K3v9371=dMC_8xd|Dji)`Q$iJ3J$v z<(5O-LT7zWJkKrj{g&h61h*{oTgu`EZaLg1f@naJ(agFZ zctLH=YbkG~)rfL+&{D@=lR;EmYOPBJYLmP!T4seLdJ|r}K{Yc(Z&Ww&ED_1QgQ92j zQeLWOqBMFIO0$#|MQ zn@b%r-640(r&M_S${-+wAyxBc4OgM|ltSH?If%(W$GVG{km9U!pQQg7ASU!hJ z2t0?zjv4F^O<_E+Lc3>dq<0Mbrs(&fxntY|em5MnJDXO7X18Bpm)_oAU7iIe>npy>Zq-q0A;UiN$iv`pPDhL(2c%Bw@^m(X1AQ_rBOv5&c zhWXfjJfH6FAA=d4eFQ`{=8&pm5GhppAj*X1JtG7wY!Hy_`P7cFZSs4XfX44u4`AHH zd3u&GH*Nd^jMTenUjs97-)r1wsMq>nrM`I8O=23W`_;S~|6OiC<1}P51VqD@+weD~ z8?+R?`nUaB-CwCox6=l&hi@hW7X;S`7W?b0-JSd7-GA-ge=Dy1{#)gYdI9&-xX6Fa zuXkc(SpG^7r9q>uAj!B*8rIBKiX2@Vr@q z!0676oHZV__YsSj2{AxN;p07wnf!^f!|S-m?`|J=$(jjH+}$ppD_iO%I@8NkoT6gV z5h2!;Y~zf-fDxY&EQ`i25vE6sFeHuaWA_YR5{6Vc(ovhH+NWg~G37&G{2olDp5Z}T zZ8#4gs~)nAs-@MNH=4{a;3QuNh$=0Q+_QJL&$)i!`fku!fgq}`yRB8c4PU#Q9q@~K z4F}P;hOL~^cydvT9KYR`O`%?)<}oZ4u&0-7a0LSb0(glfl+6;#aR8Ks;awMp=j_59 zkv@_AXM}TH7$pA4SS}lTQVJvK7ik8;)frbJiMSovh@jucz(u^QrMAIW4~&PYi>Z$m zZkpTXHi<>EX961sde9?1i=ciBb^ux}v_8eHX531KkI}u?7fzRAqu3>j+4YrlH=$9R zpfL!%<`y@<Xyb+)iW)tkHxACF~&k#{hQhgGGS+D?W)JZ7n7DtE( zT|dL>>hfM|&$92*QbH=P;j7I?f1jhH`;dz>7`AIq0yf=)!6OV|-e;=42vN;??;ral z@gZ9;z_tXkNe70K(MWvRZUsS&^j_ag1ll_=G-^#ZHgZ7`w>ki@9N_v!(DCba5EIN4 zCAr!OEr&M0xZo(2ag$uTghP`bXsgMQrj-if{v$5gq7){t$ zy0&eFnVz*{2#Ap2MUn1VSmmT}U@yT3UH}kj2de3}a;E#;J_TKA0hhql3QPP15MMwk z?&VbwM^n0YV8MWpLRlrL0fAC$!l+SFyu|d_$N!yLy&e-mf7fF%{*MjtAEo`ETB}tu zmzryU{W{|oXf5>xKytVsI?!0@dqx8P}m=b~~Tt_*n@i&ddM#1uu;r)H^OrTrz;5^HYI&koO+3d<%(-NKZBydlTQTd>)z ztX+7VHO(K-Iku5CXT~*4GH--nCJQ-G|4};HB(i)R9e+TbEaXZfM2Y*hf?ezP36c&= z?kH2ds!{evdne`s(nDkq$8Y0#~oCM2tgp$| zWz*CU#vB4@!uk$)C&V6-`4VRpBNO`dh&t zV;BpBlG!~x0;G{)d!A2yo%SI+p=>JBXNqn;apQgc6%)VvPiW{bqv$?4dFy20uI)z@ z9xQ|x`)qYp0T2kmxt(U%>QvXkmu!FzxC~UoHu5Bty@A9086Fm9PI^o^!u0>*ld$T= z`Yx832!m{5)O|uDm^4S7^Q3>*J_&VxM!u>h2#7m_+{H)cax5tn@#o&V7dS!^+pT|r zp?pnn;HV)vJZj_|iArL{d>-?eH&Pu#WvK>{&5BxkRHUk5{lW1iK@Rn8Pz(JJ`7r6_ zi5u+Fd1T7(7+U9PWoIZdi9vMl<0rB~%xX;Usb%#14Ia&ZsjT5V9#eXLy}j{pJ4(!*%2%jubhM=WV!xqYAt~d;}cC ze*_MughXDhfgWQ+jd6Vl&_amfpZmOdeUgoq=r(9fKXi2jjli{a<9V^@)T8H=Ar}GTAm_gDoLm(x!bPX^bI>DfjO&g88$Q>Yg4UkcnD+ zlG%n0j$oBN1%kSP-oH!sna^~O{q%jJbSGT(&agSKxBLAn7G>dJbW%Z{YCU7qQU`Ug zSPO^;;2U8+q`)ybg%%UbCw+)mRCK4<>N#UNtn18~C?u{fP{C#~;ZD6r1;wn?SEx8h z#n-4{Q|vU=KBB^-f(#AyD^yges8K=O$UxJvu>q}cjifh+VDqR11lw%N%-Wxuruh@o zGJkB^=Kq>$^GBv*{?N(fKQAqma_0V`F=NfZ@HVFq*|z2kvp~ObJ%isP@jD_Ax*fj` z#wBB>=8UDU72;EoB)UIg7U$F-y5c%%Y5@iP1%|4=wx9 zZ;KMItn-qkp%$H++)sXGc|MvMrZO3H|B^XnsnrbqS`*BErxvc0L$9_*0(&}C4m|^b zpe2Ne1q}I9Zezrcgv=opsUrzDV2=yXX!RN*^FFJf6Nn}$@;b}zN+(uG6m=j;#Ibw? z8rgHK`^2IYJ!pwIR?nh`RAR7843nL4e3t@K?DjdBCVoq&iOwZg%BffB~XPP+qwbZRcp>xkDo87zsbqPec|P=Ofpotjw>U4R6FW$# zVID=dg#37PQ4m!d=!M@$v9B1>gVo-Nb3BoSteIl?lOj{(Y_MF4vdLDE?qq1HZ4{I{ zBoZ8>l4#2Fpor&q2eAD6Vw?IDCrZ=`w>R)M)3J}lcyfD zi!e!;@)diiB!n5vj%HkS<|3p#YX(`X?53ek0T?+D=RpvsxsgXt9+C8yQJ+G6O4lD0 zbcO@01|fKBf#y7z)@|Voy|HJOV-aa}ztJb<%T1)NVR$Em%vp~`_v;kX;w&z8gFyXi z6_SyNeTxh(CN~9}gS?ahr7ii0)>G~`nKhhC84T;5#6S{-I!i+1IU%f5N?3kW?ktyQ zC+1w3h!+W4>>0Dxou*f&6f!=vc4k$6o?b~5j*xho?>k1}ipKr~4~y7*no`G1(~qHS zjd@VHgFrrICPy<@AhS5_Lnh3gq{i`Hpkyor#TN1)<9kgTtZ{Iel+9{Q!LNxCbd7U^ zF2dV2hy~(&fQ|cP@JpvY8o*jd57b?pXd+SDE3n>51};me?YEZQfpj{PKfVb0}#I zGw|2;I)0j=a+uCfoS(Hvlbtv_574@BPPJ(r3TP{Zf)b{pRYgjYO++^I*!mZHI~u75Aw)PX(Xy+f-wtZcsc=Z6Blf7d(vrY|1v~(|ktoW$`)K3`{hOj4?K^__Hv4239~jeImu5g~43g4+5QwN=xpYqT;Q2}4dLA>ZtdzFH) z$sg4T$t*?RK}9>9Jt%j4okXrCvW)C-^4CfHrBa%|LUMW;v}byVWO>ppxs=4 z6ocpgf5G3TTkfGv1wL=^yz_Kl3NzWrAng8kzQ4zf_3T|@sjp{?SW=r36uClZoq`bd z^7T*2v_veuAe%u)Nn~`9mWdp)tC|#Pqi*#(R7^T{CTw{dkWU}r)aosaLS%gxODx8N zmdi6^B1cP*fw*A_64GWYb0~$U94hD<`V_xMwSg?*8WYQ}qvJUO9=V_J7Y*_j9e9fl zyhW$)Et;R3S@Q>G&io%UZ~nJ4Wq#i*=63-xB zyk4)Zu+tyebaMt!Kg34So8Jnns2Z-#k_N3R^A;<=D1@Eijd=5?829t{Th3_JL4VpL-d?y zx7m--chNnLeU2^Y>^=5A_IRC@#K`_s4=%BBjDCYnpm$PW-o)4`b{V~I?dm;_-Ycw( z-V5vlSHAN$ySktk49u+iLsrG8Ih^GNo}1{u zh4+UEEjS-e$Yjh{LDMk%h}l@XP3HK1QIB(%-KNW(u*G9-+6%(im}!SztLgZ$T6M!XGuLVR zZk)N%L?@;myVmhTZ+B(AmPPsBs9xu(6XDadG8XTF0B>B*F?EAIXhV`SJws-YoO*J*mB2h0hbSZg{B zH#ToNe#f2Uyu}|V{18Zr`d-JygFLckgo%*t~=mximp@AFLnl0Xd>aDr_l}_mS!B~4W zE_gxBsn?;Q9Vc|z2yxW{P?Un4mvvcrVyFalMR}~N%D1|ve4}TSNBkrP^#}$rNYd~K z!Hl7?BbG=GauL`X$(st3At)tOLoHGm`~g!plnt^Pt@22=IEnh8&S!C_x#(K0g$1wfIle`zU@h=g!*Z;^YcBe()is1Mu}Y<= z#%hZ*egH>`GZ1kjC~67${oS!OjEGIKc#YPybLgmv@25DD>SBUDhgE|-fRPzg4B3Ft zHI=`Fjvk)uw!g1l1a{5b5%jIp(yGt|SmAK56&BUXl%1J|6RGgSn8}Y3Am!dACIbrT zJE7Nn5B=giijtQNHUF5@kRuQ3JrBvJE2G!&v2z+GlQr``rc`knAvpy~Cv_x#h^bYH zK?Q}iXDYFLeQql5yWVNm$q=Av57b2ej5_RMvBg&fE6^(pbZCd)+xU23r*B_&lc}|L zHn>9c6#z`dfDRfdhvPjIzOxU7L4V@k_yAG0hteZV1EraiQXQ05W4SU1K}^9N z1pHMj$cb-z1(CyXgVn}-%fAI|deXt&C%u6Fo|BSp&@)aGjst{JVlNTWQE=TPt4PiY zgC}jsO*UE~?4gNZC>UH!JRpA^v-h5;4<~{Ri}4Gz1;v3b-`>W@Q>W=_205fi+LX31 zD?(I&UYJ5JV981BNMpkY&Z?zaagiLrBl)FA^2H9V^k4t-`$zJ-bFpk+q)%J9-ojJI z!(f|PF9_gsU7W9(8x4lJzrKr#${MJ3hPBc30w#y&LLSy%CKZxz?NJ45W4)>gS-(904knphi1YSLx z?>2h=GO#4PSRMc1sxag$IM$tuZB(bZ%7tJG;+ij*StJKF-vQ;EIQ;+1MiBtLKe}$j8h}khTx6P5%kUer*bgybt z2_4ONf^=qGi?mH+OWMpaon^O_buBbE`$Y0IisUJ?u1A?j!<8&3RZ{mC96~&FPG1@n*ORqxgbg{3qrSowp;fWJeOHuLyOT! zuPG9-1&;@z)jUg8Q;?=uamESio)_!hBC=)ofgI~DCFX%hOdrW-W4Tt$$EJrZgU}(y zX2kqBH@DhOlK5El-6qd~lbrl?tTw!6tS4uRGpTpxZri6=K^DV{0L3h)ILki-u(J?b z4Xeai?gpsr0(+=SM{S#qxUk)-iGnij?|yr5O?!1`1l*`Sy~@8~zksq~Q==pVKl!Mv zJkk1h}RZ0*qTS|VrW@jXi*(2@@KKu z#T<5y^-j1@JNIUsqxbpOYV&T=b^f)a>)e~*Z?_3-h6Y|pUT<}$`N*FIq850IkMi3L z4#qxRM@0=a2s-n1-wA>^=b=d9q3_Md{YkUdXt549(HE%h3ON}ar?`hyhj{mtfMDE$ z${JDG74v^!XquNR=Af*|%46kgzKY%+=96zEofFKbU=&h)Vxd++*>yxh$t6ch2t(zA zk+O&qEK-0UK^jK=>62p$3S@U6#(Q$i_} zR#08JC`9Jdye0uERUkZCWAAYe2TQGv&uRfGz4opn;dV8NABM~+@tKRW^|mO?Vx7j; z!yac$Qlv*nk-~ElQ8q>Nh4Vyqzo`o6Sx75S3GNtDLq2;nQd7C*Bbh%RYE0dP%icn? z{sQ+SBI@vuu_pg1z#0lsiZfQ&vT)6k)ThFdpsv=LPuI^Bas5K0Db?QbQ~W4>egXiY zeMari2`mxt2<)lnazdn(4(5p!ludV8fKWjfu!x@L+e?@?(8B~ zT{jSuvyrhSN15b}_*;q)pWl+!^}8>lWgH`g$yF9{B=O@RUfd?|69OPzdiaD|{nUC4 zP&9;F;w#j9j{vEO@OyD4DT#kZ9SoqDg$^xzw zX-vJc}yfEJ}(|HzELv)JJSY zS4#_YyMVh3tB2~;56gT2hefK{<@;02LIB#Cd5M@s;oQ)XTt4Q1hNdm_G2(=D0iD}vn(!3qAY4s~`2Aa)mH!SP)@chWx>32&GJ83DkXV); zgQ`0kbB*|GVz!wvMXFVh`R{45+_nP@ghP$9xFf{;AU5kuo#rz18Moxa2zM0qDEK)m z4ip@|JRaN|evtNKK-*dMTMmm4^=25U)x`tbo;Mv=C#SUiBc&lNsN)Gv{ zew_7wWHKr0r*lQdiVUnudoW{EVz~_}Ql48cVBbR2C(cfLewyz2Y44tJtjS)xSCsg# zWvMCO^-@YLqO@pMrXEr{k+{sysnzwH{8@ZHq>%RT34RDY^MohA$cfMVK0tARiyHus zI{uQtUlG_Outngn3H%L#za{V+09<{OirDxc3TcYlWOlyZ3A-WH9!U_mb_#LnEL5ph zUs{gkJ5Q52mn>@>#ymKxU=kKLm!XePihKrO1Quo%lu^G-ds9J`2a8 zDo+aVvBO%PVxwHZ<(3A&YpB}4^S{SZ$fs_K*IW{vf0Tp|aj` zG~G7nUJ^xKm}IVG38JDC7x2k#!a?*Qoe1%7x_Rs_{wpH>k08Wqyi2?+~EWKS^dOp%lqel5u1fVCA8RSi)P! zTDdYcBbhUF8(Lqnt5$lyp}WK_vR7i8^Q6g46eLtDO8H1iu} iMEgT;pYn~8QT|ual}Ace`5z=%|E=egKjh8A*Z&9fX359^ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/__pycache__/version.cpython-310.pyc b/.venv/Lib/site-packages/charset_normalizer/__pycache__/version.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20d4cce56223d6583f28cb80985ee81d99b32ad7 GIT binary patch literal 264 zcmd1j<>g`k0>*a3)KDP(7{oya%s`F<5EqL9i4=w?h7`sq##F`yOestY8Kam}n1dNK zS*irMTq_Fli&GWKQj3Z+^Ygf>SdI0J^$cz?>iKE1++vT9PsvY?kH5to9}iUlkW*FmKT2z#pmt5&s zP!OY6mYP=<bQ=D0ns#}nloSm4SS{##{kyuomS`wd^UzD4elUbEoqz|=Hub}c4 YhfQvNN@-529V5t3Ap2MtSXlTN0qV|4Q~&?~ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/api.py b/.venv/Lib/site-packages/charset_normalizer/api.py new file mode 100644 index 0000000..0ba08e3 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/api.py @@ -0,0 +1,626 @@ +import logging +from os import PathLike +from typing import BinaryIO, List, Optional, Set, Union + +from .cd import ( + coherence_ratio, + encoding_languages, + mb_encoding_languages, + merge_coherence_ratios, +) +from .constant import IANA_SUPPORTED, TOO_BIG_SEQUENCE, TOO_SMALL_SEQUENCE, TRACE +from .md import mess_ratio +from .models import CharsetMatch, CharsetMatches +from .utils import ( + any_specified_encoding, + cut_sequence_chunks, + iana_name, + identify_sig_or_bom, + is_cp_similar, + is_multi_byte_encoding, + should_strip_sig_or_bom, +) + +# Will most likely be controversial +# logging.addLevelName(TRACE, "TRACE") +logger = logging.getLogger("charset_normalizer") +explain_handler = logging.StreamHandler() +explain_handler.setFormatter( + logging.Formatter("%(asctime)s | %(levelname)s | %(message)s") +) + + +def from_bytes( + sequences: Union[bytes, bytearray], + steps: int = 5, + chunk_size: int = 512, + threshold: float = 0.2, + 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 = True, +) -> CharsetMatches: + """ + Given a raw bytes sequence, return the best possibles charset usable to render str objects. + If there is no results, it is a strong indicator that the source is binary/not text. + By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. + And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. + + The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page + but never take it for granted. Can improve the performance. + + You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that + purpose. + + This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. + By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' + toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. + Custom logging format and handler can be set manually. + """ + + if not isinstance(sequences, (bytearray, bytes)): + raise TypeError( + "Expected object of type bytes or bytearray, got: {0}".format( + type(sequences) + ) + ) + + if explain: + previous_logger_level: int = logger.level + logger.addHandler(explain_handler) + logger.setLevel(TRACE) + + length: int = len(sequences) + + if length == 0: + logger.debug("Encoding detection on empty bytes, assuming utf_8 intention.") + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level or logging.WARNING) + return CharsetMatches([CharsetMatch(sequences, "utf_8", 0.0, False, [], "")]) + + if cp_isolation is not None: + logger.log( + TRACE, + "cp_isolation is set. use this flag for debugging purpose. " + "limited list of encoding allowed : %s.", + ", ".join(cp_isolation), + ) + cp_isolation = [iana_name(cp, False) for cp in cp_isolation] + else: + cp_isolation = [] + + if cp_exclusion is not None: + logger.log( + TRACE, + "cp_exclusion is set. use this flag for debugging purpose. " + "limited list of encoding excluded : %s.", + ", ".join(cp_exclusion), + ) + cp_exclusion = [iana_name(cp, False) for cp in cp_exclusion] + else: + cp_exclusion = [] + + if length <= (chunk_size * steps): + logger.log( + TRACE, + "override steps (%i) and chunk_size (%i) as content does not fit (%i byte(s) given) parameters.", + steps, + chunk_size, + length, + ) + steps = 1 + chunk_size = length + + if steps > 1 and length / steps < chunk_size: + chunk_size = int(length / steps) + + is_too_small_sequence: bool = len(sequences) < TOO_SMALL_SEQUENCE + is_too_large_sequence: bool = len(sequences) >= TOO_BIG_SEQUENCE + + if is_too_small_sequence: + logger.log( + TRACE, + "Trying to detect encoding from a tiny portion of ({}) byte(s).".format( + length + ), + ) + elif is_too_large_sequence: + logger.log( + TRACE, + "Using lazy str decoding because the payload is quite large, ({}) byte(s).".format( + length + ), + ) + + prioritized_encodings: List[str] = [] + + specified_encoding: Optional[str] = ( + any_specified_encoding(sequences) if preemptive_behaviour else None + ) + + if specified_encoding is not None: + prioritized_encodings.append(specified_encoding) + logger.log( + TRACE, + "Detected declarative mark in sequence. Priority +1 given for %s.", + specified_encoding, + ) + + tested: Set[str] = set() + tested_but_hard_failure: List[str] = [] + tested_but_soft_failure: List[str] = [] + + fallback_ascii: Optional[CharsetMatch] = None + fallback_u8: Optional[CharsetMatch] = None + fallback_specified: Optional[CharsetMatch] = None + + results: CharsetMatches = CharsetMatches() + + sig_encoding, sig_payload = identify_sig_or_bom(sequences) + + if sig_encoding is not None: + prioritized_encodings.append(sig_encoding) + logger.log( + TRACE, + "Detected a SIG or BOM mark on first %i byte(s). Priority +1 given for %s.", + len(sig_payload), + sig_encoding, + ) + + prioritized_encodings.append("ascii") + + if "utf_8" not in prioritized_encodings: + prioritized_encodings.append("utf_8") + + for encoding_iana in prioritized_encodings + IANA_SUPPORTED: + if cp_isolation and encoding_iana not in cp_isolation: + continue + + if cp_exclusion and encoding_iana in cp_exclusion: + continue + + if encoding_iana in tested: + continue + + tested.add(encoding_iana) + + decoded_payload: Optional[str] = None + bom_or_sig_available: bool = sig_encoding == encoding_iana + strip_sig_or_bom: bool = bom_or_sig_available and should_strip_sig_or_bom( + encoding_iana + ) + + if encoding_iana in {"utf_16", "utf_32"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because it require a BOM. Will try some sub-encoder LE/BE.", + encoding_iana, + ) + continue + if encoding_iana in {"utf_7"} and not bom_or_sig_available: + logger.log( + TRACE, + "Encoding %s won't be tested as-is because detection is unreliable without BOM/SIG.", + encoding_iana, + ) + continue + + try: + is_multi_byte_decoder: bool = is_multi_byte_encoding(encoding_iana) + except (ModuleNotFoundError, ImportError): + logger.log( + TRACE, + "Encoding %s does not provide an IncrementalDecoder", + encoding_iana, + ) + continue + + 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)], + encoding=encoding_iana, + ) + else: + decoded_payload = str( + sequences + if strip_sig_or_bom is False + else sequences[len(sig_payload) :], + encoding=encoding_iana, + ) + except (UnicodeDecodeError, LookupError) as e: + if not isinstance(e, LookupError): + logger.log( + TRACE, + "Code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + similar_soft_failure_test: bool = False + + for encoding_soft_failed in tested_but_soft_failure: + if is_cp_similar(encoding_iana, encoding_soft_failed): + similar_soft_failure_test = True + break + + if similar_soft_failure_test: + logger.log( + TRACE, + "%s is deemed too similar to code page %s and was consider unsuited already. Continuing!", + encoding_iana, + encoding_soft_failed, + ) + continue + + r_ = range( + 0 if not bom_or_sig_available else len(sig_payload), + length, + int(length / steps), + ) + + multi_byte_bonus: bool = ( + is_multi_byte_decoder + and decoded_payload is not None + and len(decoded_payload) < length + ) + + if multi_byte_bonus: + logger.log( + TRACE, + "Code page %s is a multi byte encoding table and it appear that at least one character " + "was encoded using n-bytes.", + encoding_iana, + ) + + max_chunk_gave_up: int = int(len(r_) / 4) + + max_chunk_gave_up = max(max_chunk_gave_up, 2) + early_stop_count: int = 0 + lazy_str_hard_failure = False + + md_chunks: List[str] = [] + md_ratios = [] + + try: + for chunk in cut_sequence_chunks( + sequences, + encoding_iana, + r_, + chunk_size, + bom_or_sig_available, + strip_sig_or_bom, + sig_payload, + is_multi_byte_decoder, + decoded_payload, + ): + md_chunks.append(chunk) + + md_ratios.append( + mess_ratio( + chunk, + threshold, + explain is True and 1 <= len(cp_isolation) <= 2, + ) + ) + + if md_ratios[-1] >= threshold: + early_stop_count += 1 + + if (early_stop_count >= max_chunk_gave_up) or ( + bom_or_sig_available and strip_sig_or_bom is False + ): + break + except ( + UnicodeDecodeError + ) as e: # Lazy str loading may have missed something there + logger.log( + TRACE, + "LazyStr Loading: After MD chunk decode, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + early_stop_count = max_chunk_gave_up + lazy_str_hard_failure = True + + # We might want to check the sequence again with the whole content + # Only if initial MD tests passes + if ( + not lazy_str_hard_failure + and is_too_large_sequence + and not is_multi_byte_decoder + ): + try: + sequences[int(50e3) :].decode(encoding_iana, errors="strict") + except UnicodeDecodeError as e: + logger.log( + TRACE, + "LazyStr Loading: After final lookup, code page %s does not fit given bytes sequence at ALL. %s", + encoding_iana, + str(e), + ) + tested_but_hard_failure.append(encoding_iana) + continue + + mean_mess_ratio: float = sum(md_ratios) / len(md_ratios) if md_ratios else 0.0 + if mean_mess_ratio >= threshold or early_stop_count >= max_chunk_gave_up: + tested_but_soft_failure.append(encoding_iana) + logger.log( + TRACE, + "%s was excluded because of initial chaos probing. Gave up %i time(s). " + "Computed mean chaos is %f %%.", + encoding_iana, + early_stop_count, + round(mean_mess_ratio * 100, ndigits=3), + ) + # Preparing those fallbacks in case we got nothing. + if ( + 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 + ) + if encoding_iana == specified_encoding: + fallback_specified = fallback_entry + elif encoding_iana == "ascii": + fallback_ascii = fallback_entry + else: + fallback_u8 = fallback_entry + continue + + logger.log( + TRACE, + "%s passed initial chaos probing. Mean measured chaos is %f %%", + encoding_iana, + round(mean_mess_ratio * 100, ndigits=3), + ) + + if not is_multi_byte_decoder: + target_languages: List[str] = encoding_languages(encoding_iana) + else: + target_languages = mb_encoding_languages(encoding_iana) + + if target_languages: + logger.log( + TRACE, + "{} should target any language(s) of {}".format( + encoding_iana, str(target_languages) + ), + ) + + cd_ratios = [] + + # We shall skip the CD when its about ASCII + # Most of the time its not relevant to run "language-detection" on it. + if encoding_iana != "ascii": + for chunk in md_chunks: + chunk_languages = coherence_ratio( + chunk, + language_threshold, + ",".join(target_languages) if target_languages else None, + ) + + cd_ratios.append(chunk_languages) + + cd_ratios_merged = merge_coherence_ratios(cd_ratios) + + if cd_ratios_merged: + logger.log( + TRACE, + "We detected language {} using {}".format( + cd_ratios_merged, encoding_iana + ), + ) + + results.append( + CharsetMatch( + sequences, + encoding_iana, + mean_mess_ratio, + bom_or_sig_available, + cd_ratios_merged, + decoded_payload, + ) + ) + + if ( + encoding_iana in [specified_encoding, "ascii", "utf_8"] + and mean_mess_ratio < 0.1 + ): + logger.debug( + "Encoding detection: %s is most likely the one.", encoding_iana + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if encoding_iana == sig_encoding: + logger.debug( + "Encoding detection: %s is most likely the one as we detected a BOM or SIG within " + "the beginning of the sequence.", + encoding_iana, + ) + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + return CharsetMatches([results[encoding_iana]]) + + if len(results) == 0: + if fallback_u8 or fallback_ascii or fallback_specified: + logger.log( + TRACE, + "Nothing got out of the detection process. Using ASCII/UTF-8/Specified fallback.", + ) + + if fallback_specified: + logger.debug( + "Encoding detection: %s will be used as a fallback match", + fallback_specified.encoding, + ) + results.append(fallback_specified) + elif ( + (fallback_u8 and fallback_ascii is None) + or ( + fallback_u8 + and fallback_ascii + and fallback_u8.fingerprint != fallback_ascii.fingerprint + ) + or (fallback_u8 is not None) + ): + logger.debug("Encoding detection: utf_8 will be used as a fallback match") + results.append(fallback_u8) + elif fallback_ascii: + logger.debug("Encoding detection: ascii will be used as a fallback match") + results.append(fallback_ascii) + + if results: + logger.debug( + "Encoding detection: Found %s as plausible (best-candidate) for content. With %i alternatives.", + results.best().encoding, # type: ignore + len(results) - 1, + ) + else: + logger.debug("Encoding detection: Unable to determine any suitable charset.") + + if explain: + logger.removeHandler(explain_handler) + logger.setLevel(previous_logger_level) + + return results + + +def from_fp( + fp: BinaryIO, + 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 = True, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but using a file pointer that is already ready. + Will not close the file pointer. + """ + return from_bytes( + fp.read(), + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + preemptive_behaviour, + explain, + language_threshold, + enable_fallback, + ) + + +def from_path( + path: Union[str, bytes, PathLike], # 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 = True, +) -> CharsetMatches: + """ + Same thing than the function from_bytes but with one extra step. Opening and reading given file path in binary mode. + Can raise IOError. + """ + with open(path, "rb") as fp: + return from_fp( + fp, + steps, + chunk_size, + threshold, + cp_isolation, + cp_exclusion, + 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/.venv/Lib/site-packages/charset_normalizer/cd.py b/.venv/Lib/site-packages/charset_normalizer/cd.py new file mode 100644 index 0000000..4ea6760 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/cd.py @@ -0,0 +1,395 @@ +import importlib +from codecs import IncrementalDecoder +from collections import Counter +from functools import lru_cache +from typing import Counter as TypeCounter, Dict, List, Optional, Tuple + +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 ( + is_accentuated, + is_latin, + is_multi_byte_encoding, + is_unicode_range_secondary, + unicode_range, +) + + +def encoding_unicode_range(iana_name: str) -> List[str]: + """ + Return associated unicode ranges in a single byte code page. + """ + if is_multi_byte_encoding(iana_name): + raise IOError("Function not supported on multi-byte code page") + + decoder = importlib.import_module( + "encodings.{}".format(iana_name) + ).IncrementalDecoder + + p: IncrementalDecoder = decoder(errors="ignore") + seen_ranges: Dict[str, int] = {} + character_count: int = 0 + + for i in range(0x40, 0xFF): + chunk: str = p.decode(bytes([i])) + + if chunk: + character_range: Optional[str] = unicode_range(chunk) + + if character_range is None: + continue + + if is_unicode_range_secondary(character_range) is False: + if character_range not in seen_ranges: + seen_ranges[character_range] = 0 + seen_ranges[character_range] += 1 + character_count += 1 + + return sorted( + [ + character_range + for character_range in seen_ranges + if seen_ranges[character_range] / character_count >= 0.15 + ] + ) + + +def unicode_range_languages(primary_range: str) -> List[str]: + """ + Return inferred languages used with a unicode range. + """ + languages: List[str] = [] + + for language, characters in FREQUENCIES.items(): + for character in characters: + if unicode_range(character) == primary_range: + languages.append(language) + break + + return languages + + +@lru_cache() +def encoding_languages(iana_name: str) -> List[str]: + """ + Single-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + unicode_ranges: List[str] = encoding_unicode_range(iana_name) + primary_range: Optional[str] = None + + for specified_range in unicode_ranges: + if "Latin" not in specified_range: + primary_range = specified_range + break + + if primary_range is None: + return ["Latin Based"] + + return unicode_range_languages(primary_range) + + +@lru_cache() +def mb_encoding_languages(iana_name: str) -> List[str]: + """ + Multi-byte encoding language association. Some code page are heavily linked to particular language(s). + This function does the correspondence. + """ + if ( + iana_name.startswith("shift_") + or iana_name.startswith("iso2022_jp") + or iana_name.startswith("euc_j") + or iana_name == "cp932" + ): + return ["Japanese"] + if iana_name.startswith("gb") or iana_name in ZH_NAMES: + return ["Chinese"] + if iana_name.startswith("iso2022_kr") or iana_name in KO_NAMES: + return ["Korean"] + + return [] + + +@lru_cache(maxsize=LANGUAGE_SUPPORTED_COUNT) +def get_target_features(language: str) -> Tuple[bool, bool]: + """ + Determine main aspects from a supported language if it contains accents and if is pure Latin. + """ + target_have_accents: bool = False + target_pure_latin: bool = True + + for character in FREQUENCIES[language]: + if not target_have_accents and is_accentuated(character): + target_have_accents = True + if target_pure_latin and is_latin(character) is False: + target_pure_latin = False + + return target_have_accents, target_pure_latin + + +def alphabet_languages( + characters: List[str], ignore_non_latin: bool = False +) -> List[str]: + """ + Return associated languages associated to given characters. + """ + languages: List[Tuple[str, float]] = [] + + source_have_accents = any(is_accentuated(character) for character in characters) + + for language, language_characters in FREQUENCIES.items(): + target_have_accents, target_pure_latin = get_target_features(language) + + if ignore_non_latin and target_pure_latin is False: + continue + + if target_have_accents is False and source_have_accents: + continue + + character_count: int = len(language_characters) + + character_match_count: int = len( + [c for c in language_characters if c in characters] + ) + + ratio: float = character_match_count / character_count + + if ratio >= 0.2: + languages.append((language, ratio)) + + languages = sorted(languages, key=lambda x: x[1], reverse=True) + + return [compatible_language[0] for compatible_language in languages] + + +def characters_popularity_compare( + language: str, ordered_characters: List[str] +) -> float: + """ + Determine if a ordered characters list (by occurrence from most appearance to rarest) match a particular language. + The result is a ratio between 0. (absolutely no correspondence) and 1. (near perfect fit). + Beware that is function is not strict on the match in order to ease the detection. (Meaning close match is 1.) + """ + if language not in FREQUENCIES: + raise ValueError("{} not available".format(language)) + + character_approved_count: int = 0 + FREQUENCIES_language_set = set(FREQUENCIES[language]) + + ordered_characters_count: int = len(ordered_characters) + target_language_characters_count: int = len(FREQUENCIES[language]) + + large_alphabet: bool = target_language_characters_count > 26 + + for character, character_rank in zip( + ordered_characters, range(0, ordered_characters_count) + ): + if character not in FREQUENCIES_language_set: + continue + + character_rank_in_language: int = FREQUENCIES[language].index(character) + expected_projection_ratio: float = ( + target_language_characters_count / ordered_characters_count + ) + character_rank_projection: int = int(character_rank * expected_projection_ratio) + + if ( + large_alphabet is False + and abs(character_rank_projection - character_rank_in_language) > 4 + ): + continue + + if ( + large_alphabet is True + and abs(character_rank_projection - character_rank_in_language) + < target_language_characters_count / 3 + ): + character_approved_count += 1 + continue + + characters_before_source: List[str] = FREQUENCIES[language][ + 0:character_rank_in_language + ] + characters_after_source: List[str] = FREQUENCIES[language][ + character_rank_in_language: + ] + characters_before: List[str] = ordered_characters[0:character_rank] + characters_after: List[str] = ordered_characters[character_rank:] + + before_match_count: int = len( + set(characters_before) & set(characters_before_source) + ) + + after_match_count: int = len( + set(characters_after) & set(characters_after_source) + ) + + if len(characters_before_source) == 0 and before_match_count <= 4: + character_approved_count += 1 + continue + + if len(characters_after_source) == 0 and after_match_count <= 4: + character_approved_count += 1 + continue + + if ( + before_match_count / len(characters_before_source) >= 0.4 + or after_match_count / len(characters_after_source) >= 0.4 + ): + character_approved_count += 1 + continue + + return character_approved_count / len(ordered_characters) + + +def alpha_unicode_split(decoded_sequence: str) -> List[str]: + """ + Given a decoded text sequence, return a list of str. Unicode range / alphabet separation. + Ex. a text containing English/Latin with a bit a Hebrew will return two items in the resulting list; + One containing the latin letters and the other hebrew. + """ + layers: Dict[str, str] = {} + + for character in decoded_sequence: + if character.isalpha() is False: + continue + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + layer_target_range: Optional[str] = None + + for discovered_range in layers: + if ( + is_suspiciously_successive_range(discovered_range, character_range) + is False + ): + layer_target_range = discovered_range + break + + if layer_target_range is None: + layer_target_range = character_range + + if layer_target_range not in layers: + layers[layer_target_range] = character.lower() + continue + + layers[layer_target_range] += character.lower() + + return list(layers.values()) + + +def merge_coherence_ratios(results: List[CoherenceMatches]) -> CoherenceMatches: + """ + This function merge results previously given by the function coherence_ratio. + The return type is the same as coherence_ratio. + """ + per_language_ratios: Dict[str, List[float]] = {} + for result in results: + for sub_result in result: + language, ratio = sub_result + if language not in per_language_ratios: + per_language_ratios[language] = [ratio] + continue + per_language_ratios[language].append(ratio) + + merge = [ + ( + language, + round( + sum(per_language_ratios[language]) / len(per_language_ratios[language]), + 4, + ), + ) + for language in per_language_ratios + ] + + return sorted(merge, key=lambda x: x[1], reverse=True) + + +def filter_alt_coherence_matches(results: CoherenceMatches) -> CoherenceMatches: + """ + We shall NOT return "English—" in CoherenceMatches because it is an alternative + of "English". This function only keeps the best match and remove the em-dash in it. + """ + index_results: Dict[str, List[float]] = dict() + + for result in results: + language, ratio = result + no_em_name: str = language.replace("—", "") + + if no_em_name not in index_results: + index_results[no_em_name] = [] + + index_results[no_em_name].append(ratio) + + if any(len(index_results[e]) > 1 for e in index_results): + filtered_results: CoherenceMatches = [] + + for language in index_results: + filtered_results.append((language, max(index_results[language]))) + + return filtered_results + + return results + + +@lru_cache(maxsize=2048) +def coherence_ratio( + decoded_sequence: str, threshold: float = 0.1, lg_inclusion: Optional[str] = None +) -> CoherenceMatches: + """ + Detect ANY language that can be identified in given sequence. The sequence will be analysed by layers. + A layer = Character extraction by alphabets/ranges. + """ + + results: List[Tuple[str, float]] = [] + ignore_non_latin: bool = False + + sufficient_match_count: int = 0 + + lg_inclusion_list = lg_inclusion.split(",") if lg_inclusion is not None else [] + if "Latin Based" in lg_inclusion_list: + ignore_non_latin = True + lg_inclusion_list.remove("Latin Based") + + for layer in alpha_unicode_split(decoded_sequence): + sequence_frequencies: TypeCounter[str] = Counter(layer) + most_common = sequence_frequencies.most_common() + + character_count: int = sum(o for c, o in most_common) + + if character_count <= TOO_SMALL_SEQUENCE: + continue + + popular_character_ordered: List[str] = [c for c, o in most_common] + + for language in lg_inclusion_list or alphabet_languages( + popular_character_ordered, ignore_non_latin + ): + ratio: float = characters_popularity_compare( + language, popular_character_ordered + ) + + if ratio < threshold: + continue + elif ratio >= 0.8: + sufficient_match_count += 1 + + results.append((language, round(ratio, 4))) + + if sufficient_match_count >= 3: + break + + return sorted( + filter_alt_coherence_matches(results), key=lambda x: x[1], reverse=True + ) diff --git a/.venv/Lib/site-packages/charset_normalizer/cli/__init__.py b/.venv/Lib/site-packages/charset_normalizer/cli/__init__.py new file mode 100644 index 0000000..d95fedf --- /dev/null +++ b/.venv/Lib/site-packages/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/.venv/Lib/site-packages/charset_normalizer/cli/__main__.py b/.venv/Lib/site-packages/charset_normalizer/cli/__main__.py new file mode 100644 index 0000000..f4bcbaa --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/cli/__main__.py @@ -0,0 +1,296 @@ +import argparse +import sys +from json import dumps +from os.path import abspath, basename, dirname, join, realpath +from platform import python_version +from typing import List, Optional +from unicodedata import unidata_version + +import charset_normalizer.md as md_module +from charset_normalizer import from_fp +from charset_normalizer.models import CliDetectionResult +from charset_normalizer.version import __version__ + + +def query_yes_no(question: str, default: str = "yes") -> bool: + """Ask a yes/no question via input() and return their answer. + + "question" is a string that is presented to the user. + "default" is the presumed answer if the user just hits . + It must be "yes" (the default), "no" or None (meaning + an answer is required of the user). + + The "answer" return value is True for "yes" or False for "no". + + Credit goes to (c) https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input + """ + valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False} + if default is None: + prompt = " [y/n] " + elif default == "yes": + prompt = " [Y/n] " + elif default == "no": + prompt = " [y/N] " + else: + raise ValueError("invalid default answer: '%s'" % default) + + while True: + sys.stdout.write(question + prompt) + choice = input().lower() + if default is not None and choice == "": + return valid[default] + elif choice in valid: + return valid[choice] + else: + sys.stdout.write("Please respond with 'yes' or 'no' " "(or 'y' or 'n').\n") + + +def cli_detect(argv: Optional[List[str]] = None) -> int: + """ + CLI assistant using ARGV and ArgumentParser + :param argv: + :return: 0 if everything is fine, anything else equal trouble + """ + parser = argparse.ArgumentParser( + description="The Real First Universal Charset Detector. " + "Discover originating encoding used on text file. " + "Normalize text to unicode." + ) + + parser.add_argument( + "files", type=argparse.FileType("rb"), nargs="+", help="File(s) to be analysed" + ) + parser.add_argument( + "-v", + "--verbose", + action="store_true", + default=False, + dest="verbose", + help="Display complementary information about file if any. " + "Stdout will contain logs about the detection process.", + ) + parser.add_argument( + "-a", + "--with-alternative", + action="store_true", + default=False, + dest="alternatives", + help="Output complementary possibilities if any. Top-level JSON WILL be a list.", + ) + parser.add_argument( + "-n", + "--normalize", + action="store_true", + default=False, + dest="normalize", + help="Permit to normalize input file. If not set, program does not write anything.", + ) + parser.add_argument( + "-m", + "--minimal", + action="store_true", + default=False, + dest="minimal", + help="Only output the charset detected to STDOUT. Disabling JSON output.", + ) + parser.add_argument( + "-r", + "--replace", + action="store_true", + default=False, + dest="replace", + help="Replace file when trying to normalize it instead of creating a new one.", + ) + parser.add_argument( + "-f", + "--force", + action="store_true", + default=False, + dest="force", + help="Replace file without asking if you are sure, use this flag with caution.", + ) + parser.add_argument( + "-t", + "--threshold", + action="store", + default=0.2, + type=float, + dest="threshold", + help="Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1.", + ) + parser.add_argument( + "--version", + action="version", + version="Charset-Normalizer {} - Python {} - Unicode {} - SpeedUp {}".format( + __version__, + python_version(), + unidata_version, + "OFF" if md_module.__file__.lower().endswith(".py") else "ON", + ), + help="Show version information and exit.", + ) + + args = parser.parse_args(argv) + + if args.replace is True and args.normalize is False: + print("Use --replace in addition of --normalize only.", file=sys.stderr) + return 1 + + if args.force is True and args.replace is False: + print("Use --force in addition of --replace only.", file=sys.stderr) + return 1 + + if args.threshold < 0.0 or args.threshold > 1.0: + 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) + + best_guess = matches.best() + + if best_guess is None: + print( + 'Unable to identify originating encoding for "{}". {}'.format( + my_file.name, + "Maybe try increasing maximum amount of chaos." + if args.threshold < 1.0 + else "", + ), + file=sys.stderr, + ) + x_.append( + CliDetectionResult( + abspath(my_file.name), + None, + [], + [], + "Unknown", + [], + False, + 1.0, + 0.0, + None, + True, + ) + ) + else: + x_.append( + CliDetectionResult( + abspath(my_file.name), + best_guess.encoding, + best_guess.encoding_aliases, + [ + cp + for cp in best_guess.could_be_from_charset + if cp != best_guess.encoding + ], + best_guess.language, + best_guess.alphabets, + best_guess.bom, + best_guess.percent_chaos, + best_guess.percent_coherence, + None, + True, + ) + ) + + if len(matches) > 1 and args.alternatives: + for el in matches: + if el != best_guess: + x_.append( + CliDetectionResult( + abspath(my_file.name), + el.encoding, + el.encoding_aliases, + [ + cp + for cp in el.could_be_from_charset + if cp != el.encoding + ], + el.language, + el.alphabets, + el.bom, + el.percent_chaos, + el.percent_coherence, + None, + False, + ) + ) + + if args.normalize is True: + if best_guess.encoding.startswith("utf") is True: + print( + '"{}" file does not need to be normalized, as it already came from unicode.'.format( + my_file.name + ), + file=sys.stderr, + ) + if my_file.closed is False: + my_file.close() + continue + + dir_path = dirname(realpath(my_file.name)) + file_name = basename(realpath(my_file.name)) + + o_: List[str] = file_name.split(".") + + if args.replace is False: + o_.insert(-1, best_guess.encoding) + if my_file.closed is False: + my_file.close() + elif ( + args.force is False + and query_yes_no( + 'Are you sure to normalize "{}" by replacing it ?'.format( + my_file.name + ), + "no", + ) + is False + ): + if my_file.closed is False: + my_file.close() + continue + + 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)) + except IOError as e: + print(str(e), file=sys.stderr) + if my_file.closed is False: + my_file.close() + return 2 + + if my_file.closed is False: + my_file.close() + + if args.minimal is False: + print( + dumps( + [el.__dict__ for el in x_] if len(x_) > 1 else x_[0].__dict__, + ensure_ascii=True, + indent=4, + ) + ) + else: + for my_file in args.files: + print( + ", ".join( + [ + el.encoding or "undefined" + for el in x_ + if el.path == abspath(my_file.name) + ] + ) + ) + + return 0 + + +if __name__ == "__main__": + cli_detect() diff --git a/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..979a8b5c7e4861fa9e431d91ff26196de16d7e5d GIT binary patch literal 265 zcmYk0u}TCn5QdZNq08ZcrLVAscN~I+h$!2N&0(_!hL{W*O|ol}Jy~DCXYrM`wel6L zoOJ#$-|)}C%-^q8OGe_KTYRDZUCe(8GS^h;gkYHAj(Og3FFL`=b(Il2)>J>7){U5# z+F3A|QRn&SZNxaigb6}_*DU55z$+U7V!0YC!h8szoCEk`@t_O~ejnNkd7m&QnL__= zWV<^%-^zB35rdv?hC#0P820kkKFVY>o(@XCswYfRKdYE9)5GYMvmY2YlxPEBgUtZz UVVdhp-<#3lRf(Jygkx5VKbIp%aR2}S literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__main__.cpython-310.pyc b/.venv/Lib/site-packages/charset_normalizer/cli/__pycache__/__main__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bd5513bb62331dbe3d0cfaabc851125bafdeef3 GIT binary patch literal 6464 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 eT1La$nSLB)03~mr;CCc({FL_Rna8k+o&N literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/constant.py b/.venv/Lib/site-packages/charset_normalizer/constant.py new file mode 100644 index 0000000..8634904 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/constant.py @@ -0,0 +1,1995 @@ +# -*- 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 + +# Contain for each eligible encoding a list of/item bytes SIG/BOM +ENCODING_MARKS: Dict[str, Union[bytes, List[bytes]]] = { + "utf_8": BOM_UTF8, + "utf_7": [ + b"\x2b\x2f\x76\x38", + b"\x2b\x2f\x76\x39", + b"\x2b\x2f\x76\x2b", + b"\x2b\x2f\x76\x2f", + b"\x2b\x2f\x76\x38\x2d", + ], + "gb18030": b"\x84\x31\x95\x33", + "utf_32": [BOM_UTF32_BE, BOM_UTF32_LE], + "utf_16": [BOM_UTF16_BE, BOM_UTF16_LE], +} + +TOO_SMALL_SEQUENCE: int = 32 +TOO_BIG_SEQUENCE: int = int(10e6) + +UTF8_MAXIMAL_ALLOCATION: int = 1_112_064 + +# Up-to-date Unicode ucd/15.0.0 +UNICODE_RANGES_COMBINED: Dict[str, range] = { + "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), +} + + +UNICODE_SECONDARY_RANGE_KEYWORD: List[str] = [ + "Supplement", + "Extended", + "Extensions", + "Modifier", + "Marks", + "Punctuation", + "Symbols", + "Forms", + "Operators", + "Miscellaneous", + "Drawing", + "Block", + "Shapes", + "Supplemental", + "Tags", +] + +RE_POSSIBLE_ENCODING_INDICATION = re_compile( + r"(?:(?:encoding)|(?:charset)|(?:coding))(?:[\:= ]{1,10})(?:[\"\']?)([a-zA-Z0-9\-_]+)(?:[\"\']?)", + 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())) + IANA_NO_ALIASES, + ) +) + +IANA_SUPPORTED_COUNT: int = len(IANA_SUPPORTED) + +# pre-computed code page that are similar using the function cp_similarity. +IANA_SUPPORTED_SIMILAR: Dict[str, List[str]] = { + "cp037": ["cp1026", "cp1140", "cp273", "cp500"], + "cp1026": ["cp037", "cp1140", "cp273", "cp500"], + "cp1125": ["cp866"], + "cp1140": ["cp037", "cp1026", "cp273", "cp500"], + "cp1250": ["iso8859_2"], + "cp1251": ["kz1048", "ptcp154"], + "cp1252": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1253": ["iso8859_7"], + "cp1254": ["iso8859_15", "iso8859_9", "latin_1"], + "cp1257": ["iso8859_13"], + "cp273": ["cp037", "cp1026", "cp1140", "cp500"], + "cp437": ["cp850", "cp858", "cp860", "cp861", "cp862", "cp863", "cp865"], + "cp500": ["cp037", "cp1026", "cp1140", "cp273"], + "cp850": ["cp437", "cp857", "cp858", "cp865"], + "cp857": ["cp850", "cp858", "cp865"], + "cp858": ["cp437", "cp850", "cp857", "cp865"], + "cp860": ["cp437", "cp861", "cp862", "cp863", "cp865"], + "cp861": ["cp437", "cp860", "cp862", "cp863", "cp865"], + "cp862": ["cp437", "cp860", "cp861", "cp863", "cp865"], + "cp863": ["cp437", "cp860", "cp861", "cp862", "cp865"], + "cp865": ["cp437", "cp850", "cp857", "cp858", "cp860", "cp861", "cp862", "cp863"], + "cp866": ["cp1125"], + "iso8859_10": ["iso8859_14", "iso8859_15", "iso8859_4", "iso8859_9", "latin_1"], + "iso8859_11": ["tis_620"], + "iso8859_13": ["cp1257"], + "iso8859_14": [ + "iso8859_10", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_15": [ + "cp1252", + "cp1254", + "iso8859_10", + "iso8859_14", + "iso8859_16", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_16": [ + "iso8859_14", + "iso8859_15", + "iso8859_2", + "iso8859_3", + "iso8859_9", + "latin_1", + ], + "iso8859_2": ["cp1250", "iso8859_16", "iso8859_4"], + "iso8859_3": ["iso8859_14", "iso8859_15", "iso8859_16", "iso8859_9", "latin_1"], + "iso8859_4": ["iso8859_10", "iso8859_2", "iso8859_9", "latin_1"], + "iso8859_7": ["cp1253"], + "iso8859_9": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "latin_1", + ], + "kz1048": ["cp1251", "ptcp154"], + "latin_1": [ + "cp1252", + "cp1254", + "cp1258", + "iso8859_10", + "iso8859_14", + "iso8859_15", + "iso8859_16", + "iso8859_3", + "iso8859_4", + "iso8859_9", + ], + "mac_iceland": ["mac_roman", "mac_turkish"], + "mac_roman": ["mac_iceland", "mac_turkish"], + "mac_turkish": ["mac_iceland", "mac_roman"], + "ptcp154": ["cp1251", "kz1048"], + "tis_620": ["iso8859_11"], +} + + +CHARDET_CORRESPONDENCE: Dict[str, str] = { + "iso2022_kr": "ISO-2022-KR", + "iso2022_jp": "ISO-2022-JP", + "euc_kr": "EUC-KR", + "tis_620": "TIS-620", + "utf_32": "UTF-32", + "euc_jp": "EUC-JP", + "koi8_r": "KOI8-R", + "iso8859_1": "ISO-8859-1", + "iso8859_2": "ISO-8859-2", + "iso8859_5": "ISO-8859-5", + "iso8859_6": "ISO-8859-6", + "iso8859_7": "ISO-8859-7", + "iso8859_8": "ISO-8859-8", + "utf_16": "UTF-16", + "cp855": "IBM855", + "mac_cyrillic": "MacCyrillic", + "gb2312": "GB2312", + "gb18030": "GB18030", + "cp932": "CP932", + "cp866": "IBM866", + "utf_8": "utf-8", + "utf_8_sig": "UTF-8-SIG", + "shift_jis": "SHIFT_JIS", + "big5": "Big5", + "cp1250": "windows-1250", + "cp1251": "windows-1251", + "cp1252": "Windows-1252", + "cp1253": "windows-1253", + "cp1255": "windows-1255", + "cp1256": "windows-1256", + "cp1254": "Windows-1254", + "cp949": "CP949", +} + + +COMMON_SAFE_ASCII_CHARACTERS: Set[str] = { + "<", + ">", + "=", + ":", + "/", + "&", + ";", + "{", + "}", + "[", + "]", + ",", + "|", + '"', + "-", +} + + +KO_NAMES: Set[str] = {"johab", "cp949", "euc_kr"} +ZH_NAMES: Set[str] = {"big5", "cp950", "big5hkscs", "hz"} + +# 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/.venv/Lib/site-packages/charset_normalizer/legacy.py b/.venv/Lib/site-packages/charset_normalizer/legacy.py new file mode 100644 index 0000000..43aad21 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/legacy.py @@ -0,0 +1,54 @@ +from typing import Any, Dict, Optional, Union +from warnings import warn + +from .api import from_bytes +from .constant import CHARDET_CORRESPONDENCE + + +def detect( + byte_str: bytes, should_rename_legacy: bool = False, **kwargs: Any +) -> Dict[str, Optional[Union[str, float]]]: + """ + chardet legacy method + Detect the encoding of the given byte string. It should be mostly backward-compatible. + Encoding name will match Chardet own writing whenever possible. (Not on encoding name unsupported by it) + This function is deprecated and should be used to migrate your project easily, consult the documentation for + further information. Not planned for removal. + + :param byte_str: The byte sequence to examine. + :param should_rename_legacy: Should we rename legacy encodings + to their more modern equivalents? + """ + if len(kwargs): + warn( + f"charset-normalizer disregard arguments '{','.join(list(kwargs.keys()))}' in legacy function detect()" + ) + + if not isinstance(byte_str, (bytearray, bytes)): + raise TypeError( # pragma: nocover + "Expected object of type bytes or bytearray, got: " + "{0}".format(type(byte_str)) + ) + + if isinstance(byte_str, bytearray): + byte_str = bytes(byte_str) + + r = from_bytes(byte_str).best() + + encoding = r.encoding if r is not None else None + language = r.language if r is not None and r.language != "Unknown" else "" + confidence = 1.0 - r.chaos if r is not None else None + + # Note: CharsetNormalizer does not return 'UTF-8-SIG' as the sig get stripped in the detection/normalization process + # but chardet does return 'utf-8-sig' and it is a valid codec name. + if r is not None and encoding == "utf_8" and r.bom: + encoding += "_sig" + + if should_rename_legacy is False and encoding in CHARDET_CORRESPONDENCE: + encoding = CHARDET_CORRESPONDENCE[encoding] + + return { + "encoding": encoding, + "language": language, + "confidence": confidence, + } diff --git a/.venv/Lib/site-packages/charset_normalizer/md.cp310-win_amd64.pyd b/.venv/Lib/site-packages/charset_normalizer/md.cp310-win_amd64.pyd new file mode 100644 index 0000000000000000000000000000000000000000..1c0f0e6e57755bb5f3c6a1fb2f38c1cbd850baeb GIT binary patch literal 10752 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 bool: + """ + Determine if given character should be fed in. + """ + raise NotImplementedError # pragma: nocover + + def feed(self, character: str) -> None: + """ + The main routine to be executed upon character. + Insert the logic in witch the text would be considered chaotic. + """ + raise NotImplementedError # pragma: nocover + + def reset(self) -> None: # pragma: no cover + """ + Permit to reset the plugin to the initial state. + """ + raise NotImplementedError + + @property + def ratio(self) -> float: + """ + Compute the chaos ratio based on what your feed() has seen. + Must NOT be lower than 0.; No restriction gt 0. + """ + raise NotImplementedError # pragma: nocover + + +class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._punctuation_count: int = 0 + self._symbol_count: int = 0 + self._character_count: int = 0 + + self._last_printable_char: Optional[str] = None + self._frenzy_symbol_in_word: bool = False + + def eligible(self, character: str) -> bool: + return character.isprintable() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if ( + character != self._last_printable_char + and character not in COMMON_SAFE_ASCII_CHARACTERS + ): + if is_punctuation(character): + self._punctuation_count += 1 + elif ( + character.isdigit() is False + and is_symbol(character) + and is_emoticon(character) is False + ): + self._symbol_count += 2 + + self._last_printable_char = character + + def reset(self) -> None: # pragma: no cover + self._punctuation_count = 0 + self._character_count = 0 + self._symbol_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + ratio_of_punctuation: float = ( + self._punctuation_count + self._symbol_count + ) / self._character_count + + return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0 + + +class TooManyAccentuatedPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._character_count: int = 0 + self._accentuated_count: int = 0 + + def eligible(self, character: str) -> bool: + return character.isalpha() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if is_accentuated(character): + self._accentuated_count += 1 + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._accentuated_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0 or 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 + + +class UnprintablePlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._unprintable_count: int = 0 + self._character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if is_unprintable(character): + self._unprintable_count += 1 + self._character_count += 1 + + def reset(self) -> None: # pragma: no cover + self._unprintable_count = 0 + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._unprintable_count * 8) / self._character_count + + +class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._successive_count: int = 0 + self._character_count: int = 0 + + self._last_latin_character: Optional[str] = None + + def eligible(self, character: str) -> bool: + return character.isalpha() and is_latin(character) + + def feed(self, character: str) -> None: + self._character_count += 1 + if ( + self._last_latin_character is not None + and is_accentuated(character) + and is_accentuated(self._last_latin_character) + ): + if character.isupper() and self._last_latin_character.isupper(): + self._successive_count += 1 + # Worse if its the same char duplicated with different accent. + if remove_accent(character) == remove_accent(self._last_latin_character): + self._successive_count += 1 + self._last_latin_character = character + + def reset(self) -> None: # pragma: no cover + self._successive_count = 0 + self._character_count = 0 + self._last_latin_character = None + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return (self._successive_count * 2) / self._character_count + + +class SuspiciousRange(MessDetectorPlugin): + def __init__(self) -> None: + self._suspicious_successive_range_count: int = 0 + self._character_count: int = 0 + self._last_printable_seen: Optional[str] = None + + def eligible(self, character: str) -> bool: + return character.isprintable() + + def feed(self, character: str) -> None: + self._character_count += 1 + + if ( + character.isspace() + or is_punctuation(character) + or character in COMMON_SAFE_ASCII_CHARACTERS + ): + self._last_printable_seen = None + return + + if self._last_printable_seen is None: + self._last_printable_seen = character + return + + unicode_range_a: Optional[str] = unicode_range(self._last_printable_seen) + unicode_range_b: Optional[str] = unicode_range(character) + + if is_suspiciously_successive_range(unicode_range_a, unicode_range_b): + self._suspicious_successive_range_count += 1 + + self._last_printable_seen = character + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._suspicious_successive_range_count = 0 + self._last_printable_seen = None + + @property + def ratio(self) -> float: + if self._character_count == 0: + 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 + + +class SuperWeirdWordPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._word_count: int = 0 + self._bad_word_count: int = 0 + self._foreign_long_count: int = 0 + + self._is_current_word_bad: bool = False + self._foreign_long_watch: bool = False + + self._character_count: int = 0 + self._bad_character_count: int = 0 + + self._buffer: str = "" + self._buffer_accent_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character.isalpha(): + self._buffer += character + if is_accentuated(character): + self._buffer_accent_count += 1 + if ( + self._foreign_long_watch is False + and (is_latin(character) is False or is_accentuated(character)) + and is_cjk(character) is False + and is_hangul(character) is False + and is_katakana(character) is False + and is_hiragana(character) is False + and is_thai(character) is False + ): + self._foreign_long_watch = True + return + if not self._buffer: + return + if ( + character.isspace() or is_punctuation(character) or is_separator(character) + ) and self._buffer: + self._word_count += 1 + buffer_length: int = len(self._buffer) + + self._character_count += buffer_length + + if buffer_length >= 4: + if self._buffer_accent_count / buffer_length > 0.34: + self._is_current_word_bad = True + # 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(): + self._foreign_long_count += 1 + self._is_current_word_bad = True + if buffer_length >= 24 and self._foreign_long_watch: + 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 + self._bad_character_count += len(self._buffer) + self._is_current_word_bad = False + + self._foreign_long_watch = False + self._buffer = "" + self._buffer_accent_count = 0 + elif ( + character not in {"<", ">", "-", "=", "~", "|", "_"} + and character.isdigit() is False + and is_symbol(character) + ): + self._is_current_word_bad = True + self._buffer += character + + def reset(self) -> None: # pragma: no cover + self._buffer = "" + self._is_current_word_bad = False + self._foreign_long_watch = False + self._bad_word_count = 0 + self._word_count = 0 + self._character_count = 0 + self._bad_character_count = 0 + self._foreign_long_count = 0 + + @property + def ratio(self) -> float: + if self._word_count <= 10 and self._foreign_long_count == 0: + return 0.0 + + return self._bad_character_count / self._character_count + + +class CjkInvalidStopPlugin(MessDetectorPlugin): + """ + GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and + can be easily detected. Searching for the overuse of '丅' and '丄'. + """ + + def __init__(self) -> None: + self._wrong_stop_count: int = 0 + self._cjk_character_count: int = 0 + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + if character in {"丅", "丄"}: + self._wrong_stop_count += 1 + return + if is_cjk(character): + self._cjk_character_count += 1 + + def reset(self) -> None: # pragma: no cover + self._wrong_stop_count = 0 + self._cjk_character_count = 0 + + @property + def ratio(self) -> float: + if self._cjk_character_count < 16: + return 0.0 + return self._wrong_stop_count / self._cjk_character_count + + +class ArchaicUpperLowerPlugin(MessDetectorPlugin): + def __init__(self) -> None: + self._buf: bool = False + + self._character_count_since_last_sep: int = 0 + + self._successive_upper_lower_count: int = 0 + self._successive_upper_lower_count_final: int = 0 + + self._character_count: int = 0 + + self._last_alpha_seen: Optional[str] = None + self._current_ascii_only: bool = True + + def eligible(self, character: str) -> bool: + return True + + def feed(self, character: str) -> None: + is_concerned = character.isalpha() and is_case_variable(character) + chunk_sep = is_concerned is False + + if chunk_sep and self._character_count_since_last_sep > 0: + if ( + self._character_count_since_last_sep <= 64 + and character.isdigit() is False + and self._current_ascii_only is False + ): + self._successive_upper_lower_count_final += ( + self._successive_upper_lower_count + ) + + self._successive_upper_lower_count = 0 + self._character_count_since_last_sep = 0 + self._last_alpha_seen = None + self._buf = False + self._character_count += 1 + self._current_ascii_only = True + + return + + 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: + if (character.isupper() and self._last_alpha_seen.islower()) or ( + character.islower() and self._last_alpha_seen.isupper() + ): + if self._buf is True: + self._successive_upper_lower_count += 2 + self._buf = False + else: + self._buf = True + else: + self._buf = False + + self._character_count += 1 + self._character_count_since_last_sep += 1 + self._last_alpha_seen = character + + def reset(self) -> None: # pragma: no cover + self._character_count = 0 + self._character_count_since_last_sep = 0 + self._successive_upper_lower_count = 0 + self._successive_upper_lower_count_final = 0 + self._last_alpha_seen = None + self._buf = False + self._current_ascii_only = True + + @property + def ratio(self) -> float: + if self._character_count == 0: + return 0.0 + + return self._successive_upper_lower_count_final / self._character_count + + +@lru_cache(maxsize=1024) +def is_suspiciously_successive_range( + unicode_range_a: Optional[str], unicode_range_b: Optional[str] +) -> bool: + """ + Determine if two Unicode range seen next to each other can be considered as suspicious. + """ + if unicode_range_a is None or unicode_range_b is None: + return True + + if unicode_range_a == unicode_range_b: + return False + + if "Latin" in unicode_range_a and "Latin" in unicode_range_b: + return False + + if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b: + return False + + # Latin characters can be accompanied with a combining diacritical mark + # eg. Vietnamese. + if ("Latin" in unicode_range_a or "Latin" in unicode_range_b) and ( + "Combining" in unicode_range_a or "Combining" in unicode_range_b + ): + return False + + keywords_range_a, keywords_range_b = unicode_range_a.split( + " " + ), unicode_range_b.split(" ") + + for el in keywords_range_a: + if el in UNICODE_SECONDARY_RANGE_KEYWORD: + continue + if el in keywords_range_b: + return False + + # Japanese Exception + range_a_jp_chars, range_b_jp_chars = ( + unicode_range_a + in ( + "Hiragana", + "Katakana", + ), + unicode_range_b in ("Hiragana", "Katakana"), + ) + if (range_a_jp_chars or range_b_jp_chars) and ( + "CJK" in unicode_range_a or "CJK" in unicode_range_b + ): + return False + if range_a_jp_chars and range_b_jp_chars: + return False + + if "Hangul" in unicode_range_a or "Hangul" in unicode_range_b: + if "CJK" in unicode_range_a or "CJK" in unicode_range_b: + return False + if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin": + return False + + # Chinese/Japanese use dedicated range for punctuation and/or separators. + if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or ( + unicode_range_a in ["Katakana", "Hiragana"] + and unicode_range_b in ["Katakana", "Hiragana"] + ): + if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b: + return False + if "Forms" in unicode_range_a or "Forms" in unicode_range_b: + return False + + return True + + +@lru_cache(maxsize=2048) +def mess_ratio( + decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False +) -> float: + """ + Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier. + """ + + detectors: List[MessDetectorPlugin] = [ + md_class() for md_class in MessDetectorPlugin.__subclasses__() + ] + + length: int = len(decoded_sequence) + 1 + + mean_mess_ratio: float = 0.0 + + if length < 512: + intermediary_mean_mess_ratio_calc: int = 32 + elif length <= 1024: + intermediary_mean_mess_ratio_calc = 64 + else: + intermediary_mean_mess_ratio_calc = 128 + + for character, index in zip(decoded_sequence + "\n", range(length)): + for detector in detectors: + if detector.eligible(character): + detector.feed(character) + + if ( + index > 0 and index % intermediary_mean_mess_ratio_calc == 0 + ) or index == length - 1: + mean_mess_ratio = sum(dt.ratio for dt in detectors) + + if mean_mess_ratio >= maximum_threshold: + break + + if debug: + logger = getLogger("charset_normalizer") + + logger.log( + TRACE, + "Mess-detector extended-analysis start. " + f"intermediary_mean_mess_ratio_calc={intermediary_mean_mess_ratio_calc} mean_mess_ratio={mean_mess_ratio} " + f"maximum_threshold={maximum_threshold}", + ) + + if len(decoded_sequence) > 16: + logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}") + logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}") + + for dt in detectors: # pragma: nocover + logger.log(TRACE, f"{dt.__class__}: {dt.ratio}") + + return round(mean_mess_ratio, 3) diff --git a/.venv/Lib/site-packages/charset_normalizer/md__mypyc.cp310-win_amd64.pyd b/.venv/Lib/site-packages/charset_normalizer/md__mypyc.cp310-win_amd64.pyd new file mode 100644 index 0000000000000000000000000000000000000000..d80815732542b2560307a63c0d3dfc11bc303341 GIT binary patch literal 113664 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 E3(iN~IsgCw literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/charset_normalizer/models.py b/.venv/Lib/site-packages/charset_normalizer/models.py new file mode 100644 index 0000000..f3f7bcc --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/models.py @@ -0,0 +1,337 @@ +from encodings.aliases import aliases +from hashlib import sha256 +from json import dumps +from typing import Any, Dict, Iterator, List, Optional, Tuple, Union + +from .constant import TOO_BIG_SEQUENCE +from .utils import iana_name, is_multi_byte_encoding, unicode_range + + +class CharsetMatch: + def __init__( + self, + payload: bytes, + guessed_encoding: str, + mean_mess_ratio: float, + has_sig_or_bom: bool, + languages: "CoherenceMatches", + decoded_payload: Optional[str] = None, + ): + self._payload: bytes = payload + + self._encoding: str = guessed_encoding + self._mean_mess_ratio: float = mean_mess_ratio + self._languages: CoherenceMatches = languages + self._has_sig_or_bom: bool = has_sig_or_bom + self._unicode_ranges: Optional[List[str]] = None + + self._leaves: List[CharsetMatch] = [] + self._mean_coherence_ratio: float = 0.0 + + self._output_payload: Optional[bytes] = None + self._output_encoding: Optional[str] = None + + self._string: Optional[str] = decoded_payload + + 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__) + ) + ) + return self.encoding == other.encoding and self.fingerprint == other.fingerprint + + def __lt__(self, other: object) -> bool: + """ + Implemented to make sorted available upon CharsetMatches items. + """ + if not isinstance(other, CharsetMatch): + raise ValueError + + chaos_difference: float = abs(self.chaos - other.chaos) + coherence_difference: float = abs(self.coherence - other.coherence) + + # Below 1% difference --> Use Coherence + if chaos_difference < 0.01 and coherence_difference > 0.02: + 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. + 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)) + + def __str__(self) -> str: + # Lazy Str Loading + if self._string is None: + self._string = str(self._payload, self._encoding, "strict") + return self._string + + def __repr__(self) -> str: + return "".format(self.encoding, self.fingerprint) + + def add_submatch(self, other: "CharsetMatch") -> None: + if not isinstance(other, CharsetMatch) or other == self: + raise ValueError( + "Unable to add instance <{}> as a submatch of a CharsetMatch".format( + other.__class__ + ) + ) + + other._string = None # Unload RAM usage; dirty trick. + self._leaves.append(other) + + @property + def encoding(self) -> str: + return self._encoding + + @property + def encoding_aliases(self) -> List[str]: + """ + Encoding name are known by many name, using this could help when searching for IBM855 when it's listed as CP855. + """ + also_known_as: List[str] = [] + for u, p in aliases.items(): + if self.encoding == u: + also_known_as.append(p) + elif self.encoding == p: + also_known_as.append(u) + return also_known_as + + @property + def bom(self) -> bool: + return self._has_sig_or_bom + + @property + def byte_order_mark(self) -> bool: + return self._has_sig_or_bom + + @property + def languages(self) -> List[str]: + """ + Return the complete list of possible languages found in decoded sequence. + Usually not really useful. Returned list may be empty even if 'language' property return something != 'Unknown'. + """ + return [e[0] for e in self._languages] + + @property + def language(self) -> str: + """ + Most probable language found in decoded sequence. If none were detected or inferred, the property will return + "Unknown". + """ + if not self._languages: + # Trying to infer the language based on the given encoding + # Its either English or we should not pronounce ourselves in certain cases. + if "ascii" in self.could_be_from_charset: + return "English" + + # doing it there to avoid circular import + from charset_normalizer.cd import encoding_languages, mb_encoding_languages + + languages = ( + mb_encoding_languages(self.encoding) + if is_multi_byte_encoding(self.encoding) + else encoding_languages(self.encoding) + ) + + if len(languages) == 0 or "Latin Based" in languages: + return "Unknown" + + return languages[0] + + return self._languages[0][0] + + @property + def chaos(self) -> float: + return self._mean_mess_ratio + + @property + def coherence(self) -> float: + if not self._languages: + return 0.0 + return self._languages[0][1] + + @property + def percent_chaos(self) -> float: + return round(self.chaos * 100, ndigits=3) + + @property + def percent_coherence(self) -> float: + return round(self.coherence * 100, ndigits=3) + + @property + def raw(self) -> bytes: + """ + Original untouched bytes. + """ + return self._payload + + @property + def submatch(self) -> List["CharsetMatch"]: + return self._leaves + + @property + def has_submatch(self) -> bool: + return len(self._leaves) > 0 + + @property + def alphabets(self) -> List[str]: + if self._unicode_ranges is not None: + return self._unicode_ranges + # list detected ranges + detected_ranges: List[Optional[str]] = [ + unicode_range(char) for char in str(self) + ] + # filter and sort + self._unicode_ranges = sorted(list({r for r in detected_ranges if r})) + return self._unicode_ranges + + @property + def could_be_from_charset(self) -> List[str]: + """ + The complete list of encoding that output the exact SAME str result and therefore could be the originating + encoding. + This list does include the encoding available in property 'encoding'. + """ + return [self._encoding] + [m.encoding for m in self._leaves] + + def output(self, encoding: str = "utf_8") -> bytes: + """ + Method to get re-encoded bytes payload using given target encoding. Default to UTF-8. + Any errors will be simply ignored by the encoder NOT replaced. + """ + if self._output_encoding is None or self._output_encoding != encoding: + self._output_encoding = encoding + self._output_payload = str(self).encode(encoding, "replace") + + return self._output_payload # type: ignore + + @property + def fingerprint(self) -> str: + """ + Retrieve the unique SHA256 computed using the transformed (re-encoded) payload. Not the original one. + """ + return sha256(self.output()).hexdigest() + + +class CharsetMatches: + """ + Container with every CharsetMatch items ordered by default from most probable to the less one. + Act like a list(iterable) but does not implements all related methods. + """ + + def __init__(self, results: Optional[List[CharsetMatch]] = None): + self._results: List[CharsetMatch] = sorted(results) if results else [] + + def __iter__(self) -> Iterator[CharsetMatch]: + yield from self._results + + def __getitem__(self, item: Union[int, str]) -> CharsetMatch: + """ + Retrieve a single item either by its position or encoding name (alias may be used here). + Raise KeyError upon invalid index or encoding not present in results. + """ + if isinstance(item, int): + return self._results[item] + if isinstance(item, str): + item = iana_name(item, False) + for result in self._results: + if item in result.could_be_from_charset: + return result + raise KeyError + + def __len__(self) -> int: + return len(self._results) + + def __bool__(self) -> bool: + return len(self._results) > 0 + + def append(self, item: CharsetMatch) -> None: + """ + Insert a single match. Will be inserted accordingly to preserve sort. + Can be inserted as a submatch. + """ + if not isinstance(item, CharsetMatch): + raise ValueError( + "Cannot append instance '{}' to CharsetMatches".format( + str(item.__class__) + ) + ) + # We should disable the submatch factoring when the input file is too heavy (conserve RAM usage) + 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) + return + self._results.append(item) + self._results = sorted(self._results) + + def best(self) -> Optional["CharsetMatch"]: + """ + Simply return the first match. Strict equivalent to matches[0]. + """ + if not self._results: + return None + return self._results[0] + + def first(self) -> Optional["CharsetMatch"]: + """ + Redundant method, call the method best(). Kept for BC reasons. + """ + return self.best() + + +CoherenceMatch = Tuple[str, float] +CoherenceMatches = List[CoherenceMatch] + + +class CliDetectionResult: + def __init__( + self, + path: str, + encoding: Optional[str], + encoding_aliases: List[str], + alternative_encodings: List[str], + language: str, + alphabets: List[str], + has_sig_or_bom: bool, + chaos: float, + coherence: float, + unicode_path: Optional[str], + is_preferred: bool, + ): + self.path: str = path + self.unicode_path: Optional[str] = unicode_path + self.encoding: Optional[str] = encoding + self.encoding_aliases: List[str] = encoding_aliases + self.alternative_encodings: List[str] = alternative_encodings + self.language: str = language + self.alphabets: List[str] = alphabets + self.has_sig_or_bom: bool = has_sig_or_bom + self.chaos: float = chaos + self.coherence: float = coherence + self.is_preferred: bool = is_preferred + + @property + def __dict__(self) -> Dict[str, Any]: # type: ignore + return { + "path": self.path, + "encoding": self.encoding, + "encoding_aliases": self.encoding_aliases, + "alternative_encodings": self.alternative_encodings, + "language": self.language, + "alphabets": self.alphabets, + "has_sig_or_bom": self.has_sig_or_bom, + "chaos": self.chaos, + "coherence": self.coherence, + "unicode_path": self.unicode_path, + "is_preferred": self.is_preferred, + } + + def to_json(self) -> str: + return dumps(self.__dict__, ensure_ascii=True, indent=4) diff --git a/.venv/Lib/site-packages/charset_normalizer/py.typed b/.venv/Lib/site-packages/charset_normalizer/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/charset_normalizer/utils.py b/.venv/Lib/site-packages/charset_normalizer/utils.py new file mode 100644 index 0000000..45a402e --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/utils.py @@ -0,0 +1,399 @@ +import importlib +import logging +import unicodedata +from codecs import IncrementalDecoder +from encodings.aliases import aliases +from functools import lru_cache +from re import findall +from typing import Generator, List, Optional, Set, Tuple, Union + +from _multibytecodec import MultibyteIncrementalDecoder + +from .constant import ( + ENCODING_MARKS, + IANA_SUPPORTED_SIMILAR, + RE_POSSIBLE_ENCODING_INDICATION, + UNICODE_RANGES_COMBINED, + UNICODE_SECONDARY_RANGE_KEYWORD, + UTF8_MAXIMAL_ALLOCATION, +) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_accentuated(character: str) -> bool: + try: + description: str = unicodedata.name(character) + except ValueError: + return False + return ( + "WITH GRAVE" in description + or "WITH ACUTE" in description + or "WITH CEDILLA" in description + or "WITH DIAERESIS" in description + or "WITH CIRCUMFLEX" in description + or "WITH TILDE" in description + ) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def remove_accent(character: str) -> str: + decomposed: str = unicodedata.decomposition(character) + if not decomposed: + return character + + codes: List[str] = decomposed.split(" ") + + return chr(int(codes[0], 16)) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def unicode_range(character: str) -> Optional[str]: + """ + Retrieve the Unicode range official name from a single character. + """ + character_ord: int = ord(character) + + for range_name, ord_range in UNICODE_RANGES_COMBINED.items(): + if character_ord in ord_range: + return range_name + + return None + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_latin(character: str) -> bool: + try: + description: str = unicodedata.name(character) + except ValueError: + return False + return "LATIN" in description + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_punctuation(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "P" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Punctuation" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_symbol(character: str) -> bool: + character_category: str = unicodedata.category(character) + + if "S" in character_category or "N" in character_category: + return True + + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Forms" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_emoticon(character: str) -> bool: + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + return False + + return "Emoticons" in character_range + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_separator(character: str) -> bool: + if character.isspace() or character in {"|", "+", "<", ">"}: + return True + + character_category: str = unicodedata.category(character) + + return "Z" in character_category or character_category in {"Po", "Pd", "Pc"} + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_case_variable(character: str) -> bool: + return character.islower() != character.isupper() + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_cjk(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "CJK" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_hiragana(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "HIRAGANA" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_katakana(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "KATAKANA" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_hangul(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "HANGUL" in character_name + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_thai(character: str) -> bool: + try: + character_name = unicodedata.name(character) + except ValueError: + return False + + return "THAI" 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) + + +@lru_cache(maxsize=UTF8_MAXIMAL_ALLOCATION) +def is_unprintable(character: str) -> bool: + return ( + character.isspace() is False # includes \n \t \r \v + and character.isprintable() is False + and character != "\x1A" # Why? Its the ASCII substitute character. + and character != "\ufeff" # bug discovered in Python, + # Zero Width No-Break Space located in Arabic Presentation Forms-B, Unicode 1.1 not acknowledged as space. + ) + + +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. + """ + if not isinstance(sequence, bytes): + raise TypeError + + seq_len: int = len(sequence) + + results: List[str] = findall( + RE_POSSIBLE_ENCODING_INDICATION, + sequence[: min(seq_len, search_zone)].decode("ascii", errors="ignore"), + ) + + if len(results) == 0: + return None + + for specified_encoding in results: + specified_encoding = specified_encoding.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + for encoding_alias, encoding_iana in aliases.items(): + if encoding_alias == specified_encoding: + return encoding_iana + if encoding_iana == specified_encoding: + return encoding_iana + + return None + + +@lru_cache(maxsize=128) +def is_multi_byte_encoding(name: str) -> bool: + """ + Verify is a specific encoding is a multi byte one based on it IANA name + """ + return name in { + "utf_8", + "utf_8_sig", + "utf_16", + "utf_16_be", + "utf_16_le", + "utf_32", + "utf_32_le", + "utf_32_be", + "utf_7", + } or issubclass( + importlib.import_module("encodings.{}".format(name)).IncrementalDecoder, + MultibyteIncrementalDecoder, + ) + + +def identify_sig_or_bom(sequence: bytes) -> Tuple[Optional[str], bytes]: + """ + Identify and extract SIG/BOM in given sequence. + """ + + for iana_encoding in ENCODING_MARKS: + marks: Union[bytes, List[bytes]] = ENCODING_MARKS[iana_encoding] + + if isinstance(marks, bytes): + marks = [marks] + + for mark in marks: + if sequence.startswith(mark): + return iana_encoding, mark + + return None, b"" + + +def should_strip_sig_or_bom(iana_encoding: str) -> bool: + return iana_encoding not in {"utf_16", "utf_32"} + + +def iana_name(cp_name: str, strict: bool = True) -> str: + cp_name = cp_name.lower().replace("-", "_") + + encoding_alias: str + encoding_iana: str + + for encoding_alias, encoding_iana in aliases.items(): + if cp_name in [encoding_alias, encoding_iana]: + return encoding_iana + + if strict: + raise ValueError("Unable to retrieve IANA for '{}'".format(cp_name)) + + return cp_name + + +def range_scan(decoded_sequence: str) -> List[str]: + ranges: Set[str] = set() + + for character in decoded_sequence: + character_range: Optional[str] = unicode_range(character) + + if character_range is None: + continue + + ranges.add(character_range) + + return list(ranges) + + +def cp_similarity(iana_name_a: str, iana_name_b: str) -> float: + if is_multi_byte_encoding(iana_name_a) or is_multi_byte_encoding(iana_name_b): + return 0.0 + + decoder_a = importlib.import_module( + "encodings.{}".format(iana_name_a) + ).IncrementalDecoder + decoder_b = importlib.import_module( + "encodings.{}".format(iana_name_b) + ).IncrementalDecoder + + id_a: IncrementalDecoder = decoder_a(errors="ignore") + id_b: IncrementalDecoder = decoder_b(errors="ignore") + + character_match_count: int = 0 + + for i in range(255): + to_be_decoded: bytes = bytes([i]) + if id_a.decode(to_be_decoded) == id_b.decode(to_be_decoded): + character_match_count += 1 + + return character_match_count / 254 + + +def is_cp_similar(iana_name_a: str, iana_name_b: str) -> bool: + """ + Determine if two code page are at least 80% similar. IANA_SUPPORTED_SIMILAR dict was generated using + the function cp_similarity. + """ + return ( + iana_name_a in IANA_SUPPORTED_SIMILAR + and iana_name_b in IANA_SUPPORTED_SIMILAR[iana_name_a] + ) + + +def set_logging_handler( + name: str = "charset_normalizer", + level: int = logging.INFO, + format_string: str = "%(asctime)s | %(levelname)s | %(message)s", +) -> None: + logger = logging.getLogger(name) + logger.setLevel(level) + + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(format_string)) + logger.addHandler(handler) + + +def cut_sequence_chunks( + sequences: bytes, + encoding_iana: str, + offsets: range, + chunk_size: int, + bom_or_sig_available: bool, + strip_sig_or_bom: bool, + sig_payload: bytes, + is_multi_byte_decoder: bool, + decoded_payload: Optional[str] = None, +) -> Generator[str, None, None]: + if decoded_payload and is_multi_byte_decoder is False: + for i in offsets: + chunk = decoded_payload[i : i + chunk_size] + if not chunk: + break + yield chunk + else: + for i in offsets: + chunk_end = i + chunk_size + if chunk_end > len(sequences) + 8: + continue + + cut_sequence = sequences[i : i + chunk_size] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode( + encoding_iana, + errors="ignore" if is_multi_byte_decoder else "strict", + ) + + # multi-byte bad cutting detector and adjustment + # not the cleanest way to perform that fix but clever enough for now. + if is_multi_byte_decoder and i > 0: + chunk_partial_size_chk: int = min(chunk_size, 16) + + if ( + decoded_payload + and chunk[:chunk_partial_size_chk] not in decoded_payload + ): + for j in range(i, i - 4, -1): + cut_sequence = sequences[j:chunk_end] + + if bom_or_sig_available and strip_sig_or_bom is False: + cut_sequence = sig_payload + cut_sequence + + chunk = cut_sequence.decode(encoding_iana, errors="ignore") + + if chunk[:chunk_partial_size_chk] in decoded_payload: + break + + yield chunk diff --git a/.venv/Lib/site-packages/charset_normalizer/version.py b/.venv/Lib/site-packages/charset_normalizer/version.py new file mode 100644 index 0000000..db1ff57 --- /dev/null +++ b/.venv/Lib/site-packages/charset_normalizer/version.py @@ -0,0 +1,6 @@ +""" +Expose version +""" + +__version__ = "3.3.0" +VERSION = __version__.split(".") diff --git a/.venv/Lib/site-packages/click-8.1.7.dist-info/INSTALLER b/.venv/Lib/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/click-8.1.7.dist-info/LICENSE.rst b/.venv/Lib/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/.venv/Lib/site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/click-8.1.7.dist-info/METADATA b/.venv/Lib/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/.venv/Lib/site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Chat: https://discord.gg/pallets diff --git a/.venv/Lib/site-packages/click-8.1.7.dist-info/RECORD b/.venv/Lib/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..7bc97df --- /dev/null +++ b/.venv/Lib/site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +click/__pycache__/__init__.cpython-310.pyc,, +click/__pycache__/_compat.cpython-310.pyc,, +click/__pycache__/_termui_impl.cpython-310.pyc,, +click/__pycache__/_textwrap.cpython-310.pyc,, +click/__pycache__/_winconsole.cpython-310.pyc,, +click/__pycache__/core.cpython-310.pyc,, +click/__pycache__/decorators.cpython-310.pyc,, +click/__pycache__/exceptions.cpython-310.pyc,, +click/__pycache__/formatting.cpython-310.pyc,, +click/__pycache__/globals.cpython-310.pyc,, +click/__pycache__/parser.cpython-310.pyc,, +click/__pycache__/shell_completion.cpython-310.pyc,, +click/__pycache__/termui.cpython-310.pyc,, +click/__pycache__/testing.cpython-310.pyc,, +click/__pycache__/types.cpython-310.pyc,, +click/__pycache__/utils.cpython-310.pyc,, +click/_compat.py,sha256=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/.venv/Lib/site-packages/click-8.1.7.dist-info/WHEEL b/.venv/Lib/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/.venv/Lib/site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/Lib/site-packages/click-8.1.7.dist-info/top_level.txt b/.venv/Lib/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/.venv/Lib/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/.venv/Lib/site-packages/click/__init__.py b/.venv/Lib/site-packages/click/__init__.py new file mode 100644 index 0000000..9a1dab0 --- /dev/null +++ b/.venv/Lib/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.7" diff --git a/.venv/Lib/site-packages/click/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14ac235a8637b2015f5a79660c76fb0640c0e9c0 GIT binary patch literal 2611 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/__pycache__/core.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/core.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..426c512bb5605fa7e4562ffd2c82e0e5ddaee9fa GIT binary patch literal 91187 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 BC-49O literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/__pycache__/decorators.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/decorators.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d5278f9f3b7a69c3de16221df0803fad5f902141 GIT binary patch literal 17209 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%0D(0#Gh7v~cPmvoa_f0B2wjud!kRMPNQz!`+ zHF+PaPWH>Z>^(P*eAWfk@GJ<}MU#==G zr0}OnTq>2+uT+|C)ooC|SgC9yOqA8+D;3qQqSyx5ry@zcPZ-w2hW;~(IisuCVb~G0Rq*jY>Se+l+aEbNl4=KFObym z#6;S&U`+7BsWWIYj6-F+=mfh8N4@|I%9zqHr;xJ=Kh0l zklDbA;#)1m{oqEn5GgeJIGdUAy`buM%uNpsW>D+~tG=h=joV|pgGEBH!NL^+q=c}h z4|HCn8wF_sTP#x0i)1t&6R*^}f-v5?3a>5=&X{NQUZe%3e@KuybL1jFYf3lWcca~& zTnfe*AtneCVtPjZRlq+b5WibAH|EkrnD};M#V{uI1Tl63cls16E`c#UjZE*QpI~e7 zcLe-ffczH@K^bN5(7y@H)k041P~BxD<=GSVGqo{ac7l&DQSs=oxNf%M84z(?`dSlpDD;jeVySz(~{{sNXmKG5Y0}Q z{UgGK_kzoOGbak*XiZ56NqVYM30tjp!YCdCtqi8%e;2w-jc5yu(Q}V-WaOmIdK>?l zAXU#tT_=pz{kY5nH4xBnMD3qa16` zlUz<$gxbFH9oon83HU7g$^+^%ZxvFR@n+$!IxMZ%_RNld^YhGj)!JIsgZAgab@6P; z^Zvle@dj(&SMZqMq2nGW(rXiV`_dl=?SOcK?1%cIla$(J9`H~ujVtX6NP`viRkn_@_6onm&+?7OVSAll=9~N+ zjLz^Y{5)C_tJ_{~4@Y3{0)Gv@Im^keS9|?Ap!Zrel9i;2n0!uP3bUoAN~}1rx3aQ{ zrAX|H4J+!mV=FY1Ki*=}h@Y~u7IvZ&9l|#eepoad#2;THHAx@=m|9agRPgm7a0{eb)1-c$bvAR+W@XiEcs{x0zz5aJ!KA9?1oh46Sp zj>tpMx##il0r{EmaCb49k(pO3v4^n5T}QZ~b|mP+QR--*3wP_3?u}wYBbLyX%l|o}tB+M%|a11 zFdI(=Y~YYJ29qRe^ipO_aST1mMWi&dN*DG}$;K+7v2lh{9gmrg;!N>U=xWXEhqpT*i5t72+B?~(hvu5f_Ep0jmP4q)=Ky4PR}L#^Ow*L-`d0Q zKxhDn!C68CoD9ZRZ7Cx*3nON1R_?kAla-8x49?bXSgYgy#OCI+>Q2JNf!iuuJ-%_x zcO@eu;?0aUBOfZ9@gGE8`t5g9SdWI?BRHRb( zQ6Y6yxnM`SilZ(HtP`~MG+qx7ns_7VH}f&RPCecWP?D6K3Sbfl>n@!69Mlc6Tq!}= z`W3%S;F6-SP$Rb>n%qTMhN;GX4VQQ|QU`&HAdF)tXaNdTXt}$qwvm z?MMs8agJw`t?k{rbF(4QJel`qDMPo($~bI@Q|SG-kH_A3PYFjyyHc!gXFt6SC5 H+ogX1MFnwP literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/__pycache__/parser.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..614417819d7aa4c37e813039da7ea293085a824b GIT binary patch literal 13675 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

pG(8Yhx6@}lbLp200 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 S88z=7KX4CTXLaCU@&5p70j^~L literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/__pycache__/testing.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..608fddaef81314ee32974fdebc9b16b6326e6588 GIT binary patch literal 15204 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/__pycache__/types.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/types.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c9e310bf6e12812cc2f3ef82082347337666954 GIT binary patch literal 33688 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/__pycache__/utils.cpython-310.pyc b/.venv/Lib/site-packages/click/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4877710dc377d0a305167c5694089bb83ded1d7f GIT binary patch literal 18848 zcmc(HTWlOxnqF6R^_5MEx>z^McKIr`O|>lBV|y5n*AjKHW@L(M$(Bt^X_opF$)=iJ zoKw}L*l9Z6k@tqg+1+Ha33f686)b`no5^L7yks-Gzyt^qAddk8RD!(ZAs8UYKFmuZ zkF9*)f2#UI$}{tpmh14;sdGR7{r``H@$qs7zyEpXwEyiZnauy-%kXa!FK^)qe`04c zDx<7cX5Rd@<}G=*=WY3$op)`3HhALx5}$y^J9`P zAYYlUNWO^t`24u!OUO^mPe{Iu{GRzek{?5Ua(+_s73BBM@0I*G^84oZNqz$P{qy@J zzX$mP^9Lk9*?MI4;QT==<2x&d^qS22@ca?~$o5gS_ntNXsPAkaQ~Qv6Ozrm{R|ovZ z7ajG8I{2wG|Acy99aWDa=c;39|77y@G4(jgo>JG9ixyA%PfK}TJ*A%hG&ldu#f*AJ zJ^N`!J$u)le->}gspEJ%j<@GZ7XFkF(z+8TCSvKVjZcGUZp*Njx?A zQboxDWi3|JDfJ>od0y>Tr!lUx@&e}jl6o04nnK^Ns1N1KH>B0$X!UA8$J!?si|RG? zI(n#;zRCKSOI6LQX{_Y0;CWcPH!zED;bHq^ev1?8P4#Q&WtKQd@--i zsu_HFQQc7I(BpZOUr4?c)kXC-zMaOdTvFf0u6!H2@)CCArut5Qo|h$8Te+V@sN zl#B&yejB6k9j|-C<)G72ENHH!t;!>Bm1JIN583ONxY|dw9|o;;zupL17%*8xY|X{i zyRp;uR{c1y{ivhc4X!l(G4J4+!4vL7qO9#qFSBjk%iOcJ?Ryz)sXcq&I$6!e&Pvd1 z$GLE=)r{g?E7;&l^?o$^Jfn}`&;5%t(>LA=eI4Ei+rfsqF?03hS5M!V>1ge@8=Gg= z)^60+{r38e%gtLiLhRJZHSE5(W#)quPwuYI(O>{zr3D?z=bd9~&)+YFE~xX3+LpAH93?=E$1aTLDiN zPxw3%Whq-_m7{V|X2ptZ09F3CGmDnWtHP(1Ei20Qtl!DpwXqk)?u*v}Poe9%oCim6 z!@!M}y~u4wZn%L-1skF3-)Z}ah_&Q1}moBJ&B@_0Ow}Q1$`WuIJfS#I{wHB5h}R>GkC(YNFpph zvhLdYv2GF2X-C;@hY*@q% zwxhtjG?hy%YcJLA=Q`2i$=Bn8_Sae<5Y<9lZidZv7ox z<42bKXtCMyk&paUfO??NQ(Sqk-DIWnS_c|6BcjU*tj6rl;3$f#-ff>aU*mcwkd$q6 z8k3g&plIutQ1sK2NMdK%Z>`1URqsx{<+qoj->|pxTZJCK7VcWTyvp5n4rN};Y&kurXWe%6jFo9W-76@Jr;6zJeO20a z(03Mf3x_i7|DI(7h%q`_*m|Lt@8vMl1+>h6_mruB4=2b`RQawYy~{}YcV%Ssbp&Ue zj{bT&x}|@kUF0|@$(yg?+F*P$wkjXO*wwM_3-1bbByco>w({GduUvpjNE8niU2c2| zBVD^({^EDU1X6&%ePFOl5 zu$1yJuoE5CIrY~uNXVp|E!q{Un00K&s$?scgSSchfK}wXeH3{RfKSSHC0ooMMyZXb zc>iEg6Q~+^Mt);>dkatazmWJDii{8!t@&)pE@ewjDW{%Rc`)#tk8@ZQC_t`+l7f#@ zQ{{ec%rAnKSJXJze@RWC)*gH-L*SWIdm-?Q;XS`-t9@!e-YW8SoHanLZHP;cpmYMl z*g@Y-Chyw3TU&>-+v^7(I1o1kynpP?f`OoR2E{>6Us%~M`V

H@B7u6u2{8M^qd6Z)8iiy>T+=wv#eUj42@`AETr z)KQ9KOV7r6(#uA4Augr^b|-_dHs?jlm$CMb@cCx!tdd9;`y??BVJgrdpI#KKHXDsR zpeFq>PaGngh3iNnh#@@?uU@7O@`V&+2PsKQrk?BNkb<~dAY*)10CpfBC!#{nLhWqN zx$E3uD=>_Di5ya)m-UQ(IV!WpU3+`%9$G52trtO%l3G<~RzHH#^?4-Ms+HIdFyF;+ z4GR-tN59RlmzaE;$#<9#4`RE%7*`SruF(oYKX!PyaZX;U`Pd2l)}p@11`q2*IKmKH zr~}uVQN8|MGziH@E5*EJ{yAXNWngR3o^bM3+3N01fw7jhGLseIVwguTpT#5FOkP9Y zN_npb{(3c|$)T%uTmVn=qDbpGynk-%ck##cxMP-M^?FjZUjLh@B*NN+)jcpYp?-y3 zT)uzcWPLb997o5}@b`NF`z`xpd&Anm38Fnx>`lJ=qbt~#a6nW* zA)3)~LwGj*NXSk~2q@^etIefl&?K+fayOdMvS2#NlIKoCnw?&_fZY>OW&zD+LB5u~ zwrYVWU<^LaMG`u*= z5Y(y_Ia0y2!2#~XLzp-q+FrS8WUlf+4A(dLr3k7d6RkRO@UgAeW6PJ1J2k&32@DQcJUMY%e>=Q-SIx46B0+@fuaHNP2hpTG0qP17~rA89I*}r z2ek5O&_ z*q*SQ2i=MOWQ8Vu{cI_qaE`iUsKdxSe^=N?UjYi*;2YB4PIz-Syigzw2zm?53LLHl zM%f1luFOpo3qaKcu%T4aHc%z-)b=5VnE@byLAD-(8|(tl{A+h1-Y*jaC5`-6tGVR2 zqt@o1q`Q)LAOJn+9vj`2(aO8_h^NXE{Tb1{2doyFX?Fi1=Ky6EA|1}HUjI|JB0vCa z_Vvf?e+Hwx)2K(VMnF_VPL!0`j&3zLQu<@Q4^&j#DC8SXmXdEvE0lk3U|cUFubWI( zn2bV63|i;kA(#2r_$b7?k{{tF=IgFq=ucrE+ND!4)Q$R<;UihWqS&ET#6auAHV9K- zg?jzRoC4QZ+{M!5JFu2qc~)OQdI4OC+>MC9zxo`K>Jcu8;!nLEm+N)NAF%i!UjZBK zc&+41p;$6vvF)$yto>!tv4397*a>33{phhvNVdu(U94$(J4fHqi zqoVj0p74*548(RnyW-%X5(t9`L~ocxAn@iP!b64Q7nBuL5oJY)+$B{;uB68BrHp6H zuZUP(k$2?Pxa7u@{)%cs?LmtP^aW)g5$yL!&y%RRSA=XM;O`S5`;oZv9p7IgDMJzrkkE+YcF(@c*Ci2x)QhyLR=L zkQX^kv!MgBV(Sk$l5FS07D`n8&#dtYl3gP{L~!GxQuxt#*^)a6U|D7UYsVoH{}DQ=r$H3F(jCV6x7HAZX|iAwo!tP$W%ZQg1Tp6BQvyy34Y^ z#^h@$3P=74p73!b#mrIbK(?ISO)DmfN3)uBuU&`>t9}^5Fsq3tvE6RPSrBk2GBhqX zawtrHG&k{`z#qc(0?dPe1684yg&3c?o7uA3S(xtdH~m6k2WBXWLC;XQkFt>y>dnHFaf^W%c(4kK)JSqoWoo%7oP1|+xb+S zlDg~@S{}$QG(z-A6A;H-NNe`;+r?h)o&}*gKWN*2A}T?5v|#e0p6H;5AR6oCWLA5l zivA=Tmwvj@xb$na^F1g0B&~zq(_V*WRLyyN^O?*XOpKB1xyklILRN0u-+&bDizXi_ zcokeoK`<|a($$QfZd6M5meKE_vMZ62d{5CZHBC8edSQ)SFQ8JxLk$|EA%?Fv6~xI~ zzKD%sXKfAUAQ8T(@T=zHq7Tb_l0t4NxI^h~?g>00YoLeav)Fcy4G({^jx zO_44|G;a}mC18`FVGZy}Pm<^;iRpA?0&-H*R8OGQQgfwNhCNzt($H@X(wu!Dn`9uM z=AIpBI!U*#(SAj((E+-#S5{ zKK>+l2v{Xn?nI+xwkZ(ydx2C9*Bp;)GpwaYHbqC+a1lI4II3Hm2kn9eSN(}%6;m7z7AQHr34`7bQUNnyag?Q>Tj9&2M)UjCXM3}k(M`@z1x zG}J@7uL&6#;6CwL3cXd2R8G{}7GTW)*sOjHj5D^%Kcfgzu1;uhiHs&!)h{p+rDO`Z zxI~QfwDvaRoZz&k6c0}UcUd!zLsR(F<4pE2DIuvA^ry^=!26rb{T7qoMiOUn`texe zlNQN(R4k1hzp)(rS5yrzASs@7tfG~-i?Dhe&X(ahaBM1SW%>?~bF7Jck=_E9;0;Pj zscfSj-jWo)22Gn<_ju&jE_2@S&mI?@{`i#345pOia1h6LJ8midh^%n}8L<$wbNJyvx2jL zyO4lX#@S86x~%^$UPQqj*wz|Zl%+qOK>rj7nf+6MeO_e0-KPKtIxX%z3GcsS#9wq6 z!f1yMBXL%ALa6VsGnpU;!Y*8=1yL)#kxf*TsJDFMs-f{Ph8m7EeT_WucvQXZOk zrKep8AX`3FiMc zlfT0P#~5!1{*&+X(+)V@!-E+LbeZi#=^jF9+0uW=R_B>qWb!tW*r9Dv%*Z2-C4p{y z7qW2!nI7gqphdKYjVF5~6TuQs5QTL;r>xI%_W-I9Ec3%cs7s7{GF9T6ds23-2f-g*--1i~Tqb26>tCrJfR0x7oHfO}X#)Z2;o zQ^v_i%%*TDbl-^U#+znJYVOtMYLh<4D3E@5%Kc#z>NVYfD>4$#h6#sh~i37iYU* z{HoWc!f8AR)CI(Di)sd@#NtdBCRiv`n*f9w5*w#OZHH^@o1^Ky0A+Q(Mgw5ph6BBo z;3}-^9D3KzCYlNa4a(prZz1I6HbjKAO?1>YS`4W+I~H;;rlb=*Tq1SVg^_!4dW6U$ z0Kl{xl7I~XxQ3}RN7YTHok+wy)+w`>1|C3Z`d#+-_taqDM-Y_AXC!RqxU(C}&Bk*7 zxYChE8l|Xi8m4b-W1?F)8!4qHo2yMt`OS8JX6EersGm}sgkEs5LOTY|q5+vm>Jn)o z-g`LK6u8pax}7#;Lje^q)dtx!1SfG5kOKE7!9ES-$t(e^h{J)d>*;3V(WZbHxY}z1 zSWHJ|UIP_R-09Lu+kl=L8J**~-jbI(ACk!%%p1~9y#CNhH~>XoSezJ2BgP=yCgs;F&jQthc1;%LC zFP^QvckRN-*ZWI)$HTsb4G>k`3_|yL*chIduoO;I*xg_gX-f(^OUqNP>IfT{J3r@s zYRV+!{goG|u*;2BhkE*uJ?c6(fRjPLGIy+)yvxu`Fq9C*=`JurI0U;~PEO^i z)H*?f6bW3SPb>q978Wj_nZ5X}nRH=OD4Ai;!XxLdT)p%GTDxF*`r%4+x%*0JPoHG+cq}NoK|qi###u z07&JOTwyF`P8eqH!)tF}nZ=jazjYcT$@)%y;39TX&Xeqtzu}dlOEGVfA{t%iS6QJP z<}NM@<_H`n+NNAs5cj=Huxci_Yiy?iwMLjXRx0VwOl~MmIgTJW>?;r}Oz@^mkG&C9MCUGhvt!T7f>bz;O_uwMHOKr6B!0 z2&1kdiTCUPhiX}0X1T*2;vz!DL^#p!u!WcssHL3!{4Dc3b*(Hzm9SQ z{UOS}PhLPLtMljt;*QGpq~+u*KX<(@K zNgZy27fnf0CkK;1+z3C&{LsFK05Zt(#g&r8wZ1h{ufX6kk@eYk9^WvkDki;@(AG9R zu}-z@{T8@Ks=D%IjmiheYXM&c09lHSK!}US*l-E3p^{}3rBn=;lc$sdkwl_SL3zL! z80CP{)gT0ST7wD9X}5ZT<_3_745E@WOB^U($`=muIW z?M=Yhr!EA6d)CvS95mJ;Hn2~TWkv$5sr5ct6>aLckpPC5Oclm6!+_rL8t#>=?gy#h zyRh)_DFpUI=-NDWX0QdR&Hhv}cw*j2Te~NODprSksVxS<$y**svP=tN#+{MRX4_Bg zuJtQ)mYO(EBtSYeaR2hc8{h!?%^O(6IXFgcylcSu#^?h29Z^^L)jPY)X!@b9WQDsW zKH3)LQz~aB$Yl&sIMo!wM3)dSBh8lEBRnet55tFW_-jpQK+Uc{5SNGO9>TjojVaM! zQzJ;X@OW@WFOreH!jtq{Mx4||M+T_C* z)j(~)px%I#K0;@Q=*YBjkYKS~FXGsMLkrh*2l^|TiegMDLVzme%=jRCxpQc~C({=; zfqe@RqXAq=B(r4(-S%sMFndCkfq`G!pTd%9f6=@1(OYaV=z>C{2olM zK67RE!ljG#x39c&zFR_LgI{1MVnr6NQb;_4#*p(vkn9-2b!z|~;);Z`%k>;#EpZXj zbA&@%MI7cf>gsz;{t;VcZ~L1Frxl91gVV%gwEAG>b=A~=PLAWEh4VxO*HVgj5Wr?V z4%<&2dFMesdjL7-EB#MVsexzYM@`}_JRuE3g8-NLEP_oKjqa>4`W$hU2x!5DMFgc3 z5PP16wv_ym%CZi=mem-(mU%y-Iv($v^BQn{T%b?wy17{9{RyTj=7}VbjgX055sedU z09v?6JaApY1sb|%b#U8n&ovW^Z3wy=;=Wl5R5Ve7R@cPDFV2%&K1qH;#eq(@qyu*i zJwW&srG=C`T<$==+GwA`tpl%h^5TrZXaa+&Tt|l?rh&A^7*2S-=*Afu40HF4->^TR z^aC+@$k!t)>K6e3DAittHX%F>CN3YY+;(%-gYpiyF%cWQsBO$J#z)qGeA9+>LyL>C zVsR1BX%P?z8eo*=9YK)XS<)2P(PR%~X50sK02dNxjOo(=jL79CEV+<%DFcHV-f5;T zm-Ob7`XzBh`eT5Oi373pKSLfu67^Ea?*Ls1-1t9$0}~1I=x!+K#}84h?*FpL(TqQX zC!9sX>rH83=ye1`%S|tP^Ere9TL=Z-hs#ZwRu5eja|WB1PWhD?)cg_$_abMHRM$fy9<} z(r{RFVPZ~Ai?lUHdK0!?=wA{z?BDU>bMe)X zY0v0qhHs``9q9$$WusJ|T!lKyu;X+#NiP@&8Z3fADVTsH@!qL%%ndaaX$tK@XZpPx zIZOyV9pUZckU20-$Q_UuB1qJrrwvFfW|m6N z0Ykpc?lAhnbVKqgQy8^hv!O8)C!9nKt%ftD$J947AhL(k$1V&Rip_Ai`nvwni#G?x z7F3dhg8l4akr#qYX5fVdg!2Nm>UGT2EN?VEN_K#EhF`nB|Pq1BV07WcBZY~!OF;1XtO~Sj(tE~1{2tE9A5&_JW!bA@D3$qir zaj5?cJ@JM)Kmj*pA#27HOReA*Zs9aKxPb}9_zBME-!l0zlRrn&03DVe2$Gl+81FEH zCnR$Kr?gv{Ra^$OGE0mR%;3W6D{#_T`hZdNdwG}=@-QA8lXu6wg99VSE2^K_TfB@@ zabRj*$#1@B;j)JGRroN|=5?Dw_|0B!yTEo<=DTI&i#?bWOdhn-@qUDTfIALX0HMZH zj|Fbw8Umbw5S`^_sn}0boJww#r;g*RxY(CEs<9h2ZV5E^qzJZlp#uXk9N$2Oh0r{- z&bp_=)O;-TOfVFNV8+joXplw^^flT;Q$fs3I}HTFg~Glx*Ix?AFar3zO_9+2I}rLH zTf#^O`IpuWP{N@N*bt+F3Q|Ndp=iXeX~g`&{sFl)#W{(N#3z_85spa0YnD8sA`)_@ z-SeW7a2+7ARNkOT05$`?IZ_z_)~`Dh>WEw6Ft~sejz+JILgF;&?(;OR%F;l&(;=G3 z_u;jL0p%bD^kon@^m^^Ie52Brn(;XZ$usyWZf#L$Wq1l5^I!#VW<{F=puspG$Ns=Q z2zy~$oLf{BkQIyZt_h^xBoa6SB)iFz5f^dgiu2(;tp19sCH)sbD={(}>hMqSnreXr zEnKF;{dgH07d+`5P_QrFA$-9b^$-L$9e&1cvN&Hv9TQsoaEH)`yBp@f>x7SABWZEb zrg98HN4&HQ0)zi=0ZfvVO6>;@u4h#ckfi?uDuI$6!yo+^6B;lzgP?H_|7HHk&CXuC zfcqonLJ6eg^C(Sjmt3e?7pnF(JhQXa*UYki!VYRk;yfK8?Iq)hD~anFS4KklA0fm! z`p`p7vLxZ!^9B50IiLnbL&04%e@cLsgz*@^U4>=iOeUC6`^G&?90csw65xgZXUT_i z=j$_XpP%{8rP+(~d(AAcJ=kQD6P!VW%R_U#`FnNEZ|J?!$2H97eT0rtd^Ztgk1}_h z$vTslki=QANV(;$&#|n>qa zH)1h~dvXH?xD`9ZZ#kTybM8ynaq$hq(cUC=5C0pIBCZ4RAMF4<+T?HgE`Je~CU)t4 z*|KwB{BU{VrHK#hqvqlauFiZ>24GAk*Jl75gX=R(_5{9viJHQlczMQg%0IUc_1oU( zH+$q_4X@tV_sfOy|FvIszDmE_+47gio}V~vA9WrGx080|uk2~|mH&ceyuQQnZCu|e I<|pp|Ki2%u9{>OV literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/click/_compat.py b/.venv/Lib/site-packages/click/_compat.py new file mode 100644 index 0000000..23f8866 --- /dev/null +++ b/.venv/Lib/site-packages/click/_compat.py @@ -0,0 +1,623 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +WIN = sys.platform.startswith("win") +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO[t.Any]) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, "os.PathLike[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( # noqa: F811 + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/.venv/Lib/site-packages/click/_termui_impl.py b/.venv/Lib/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..f744657 --- /dev/null +++ b/.venv/Lib/site-packages/click/_termui_impl.py @@ -0,0 +1,739 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ +from io import StringIO +from types import TracebackType + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/.venv/Lib/site-packages/click/_textwrap.py b/.venv/Lib/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/.venv/Lib/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/.venv/Lib/site-packages/click/_winconsole.py b/.venv/Lib/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/.venv/Lib/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/.venv/Lib/site-packages/click/core.py b/.venv/Lib/site-packages/click/core.py new file mode 100644 index 0000000..cc65e89 --- /dev/null +++ b/.venv/Lib/site-packages/click/core.py @@ -0,0 +1,3042 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.MutableMapping[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invocable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": + ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: + ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt) as e: + echo(file=sys.stderr) + raise Abort() from e + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.MutableMapping[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The latter is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator[t.Any]: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return t.cast(Option, param).flag_value + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the constructor of :class:`Parameter`. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/.venv/Lib/site-packages/click/decorators.py b/.venv/Lib/site-packages/click/decorators.py new file mode 100644 index 0000000..d9bba95 --- /dev/null +++ b/.venv/Lib/site-packages/click/decorators.py @@ -0,0 +1,561 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + return decorator # type: ignore[return-value] + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator # type: ignore[return-value] + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: + ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: + ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + message % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/.venv/Lib/site-packages/click/exceptions.py b/.venv/Lib/site-packages/click/exceptions.py new file mode 100644 index 0000000..fe68a36 --- /dev/null +++ b/.venv/Lib/site-packages/click/exceptions.py @@ -0,0 +1,288 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd: t.Optional["Command"] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename: str = format_filename(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code: int = code diff --git a/.venv/Lib/site-packages/click/formatting.py b/.venv/Lib/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/.venv/Lib/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/.venv/Lib/site-packages/click/globals.py b/.venv/Lib/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/.venv/Lib/site-packages/click/globals.py @@ -0,0 +1,68 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: + ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/.venv/Lib/site-packages/click/parser.py b/.venv/Lib/site-packages/click/parser.py new file mode 100644 index 0000000..5fa7adf --- /dev/null +++ b/.venv/Lib/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes: t.Set[str] = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: t.Any, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List["CoreParameter"] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args: bool = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options: bool = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we recombine the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/.venv/Lib/site-packages/click/py.typed b/.venv/Lib/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/click/shell_completion.py b/.venv/Lib/site-packages/click/shell_completion.py new file mode 100644 index 0000000..dc9e00b --- /dev/null +++ b/.venv/Lib/site-packages/click/shell_completion.py @@ -0,0 +1,596 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + @staticmethod + def _check_version() -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + return cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + # Will be None if expose_value is False. + value = ctx.params.get(param.name) + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + sub_ctx = ctx + + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/.venv/Lib/site-packages/click/termui.py b/.venv/Lib/site-packages/click/termui.py new file mode 100644 index 0000000..db7a4b2 --- /dev/null +++ b/.venv/Lib/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/.venv/Lib/site-packages/click/testing.py b/.venv/Lib/site-packages/click/testing.py new file mode 100644 index 0000000..e0df0d2 --- /dev/null +++ b/.venv/Lib/site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(input) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env: t.Mapping[str, t.Optional[str]] = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/.venv/Lib/site-packages/click/types.py b/.venv/Lib/site-packages/click/types.py new file mode 100644 index 0000000..2b1d179 --- /dev/null +++ b/.venv/Lib/site-packages/click/types.py @@ -0,0 +1,1089 @@ +import os +import stat +import sys +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import format_filename +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name: str = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = sys.getfilesystemencoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type[t.Any]] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name: str = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/.venv/Lib/site-packages/click/utils.py b/.venv/Lib/site-packages/click/utils.py new file mode 100644 index 0000000..d536434 --- /dev/null +++ b/.venv/Lib/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO[t.Any]: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO[t.Any]: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict". This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return filename + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no effect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO[t.Any]) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/.venv/Lib/site-packages/colorama-0.4.6.dist-info/INSTALLER b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/colorama-0.4.6.dist-info/METADATA b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/METADATA new file mode 100644 index 0000000..a1b5c57 --- /dev/null +++ b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/METADATA @@ -0,0 +1,441 @@ +Metadata-Version: 2.1 +Name: colorama +Version: 0.4.6 +Summary: Cross-platform colored terminal text. +Project-URL: Homepage, https://github.com/tartley/colorama +Author-email: Jonathan Hartley +License-File: LICENSE.txt +Keywords: ansi,color,colour,crossplatform,terminal,text,windows,xplatform +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Terminals +Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7 +Description-Content-Type: text/x-rst + +.. image:: https://img.shields.io/pypi/v/colorama.svg + :target: https://pypi.org/project/colorama/ + :alt: Latest Version + +.. image:: https://img.shields.io/pypi/pyversions/colorama.svg + :target: https://pypi.org/project/colorama/ + :alt: Supported Python versions + +.. image:: https://github.com/tartley/colorama/actions/workflows/test.yml/badge.svg + :target: https://github.com/tartley/colorama/actions/workflows/test.yml + :alt: Build Status + +Colorama +======== + +Makes ANSI escape character sequences (for producing colored terminal text and +cursor positioning) work under MS Windows. + +.. |donate| image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif + :target: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2MZ9D2GMLYCUJ&item_name=Colorama¤cy_code=USD + :alt: Donate with Paypal + +`PyPI for releases `_ | +`Github for source `_ | +`Colorama for enterprise on Tidelift `_ + +If you find Colorama useful, please |donate| to the authors. Thank you! + +Installation +------------ + +Tested on CPython 2.7, 3.7, 3.8, 3.9 and 3.10 and Pypy 2.7 and 3.8. + +No requirements other than the standard library. + +.. code-block:: bash + + pip install colorama + # or + conda install -c anaconda colorama + +Description +----------- + +ANSI escape character sequences have long been used to produce colored terminal +text and cursor positioning on Unix and Macs. Colorama makes this work on +Windows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which +would appear as gobbledygook in the output), and converting them into the +appropriate win32 calls to modify the state of the terminal. On other platforms, +Colorama does nothing. + +This has the upshot of providing a simple cross-platform API for printing +colored terminal text from Python, and has the happy side-effect that existing +applications or libraries which use ANSI sequences to produce colored output on +Linux or Macs can now also work on Windows, simply by calling +``colorama.just_fix_windows_console()`` (since v0.4.6) or ``colorama.init()`` +(all versions, but may have other side-effects – see below). + +An alternative approach is to install ``ansi.sys`` on Windows machines, which +provides the same behaviour for all applications running in terminals. Colorama +is intended for situations where that isn't easy (e.g., maybe your app doesn't +have an installer.) + +Demo scripts in the source code repository print some colored text using +ANSI sequences. Compare their output under Gnome-terminal's built in ANSI +handling, versus on Windows Command-Prompt using Colorama: + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png + :width: 661 + :height: 357 + :alt: ANSI sequences on Ubuntu under gnome-terminal. + +.. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png + :width: 668 + :height: 325 + :alt: Same ANSI sequences on Windows, using Colorama. + +These screenshots show that, on Windows, Colorama does not support ANSI 'dim +text'; it looks the same as 'normal text'. + +Usage +----- + +Initialisation +.............. + +If the only thing you want from Colorama is to get ANSI escapes to work on +Windows, then run: + +.. code-block:: python + + from colorama import just_fix_windows_console + just_fix_windows_console() + +If you're on a recent version of Windows 10 or better, and your stdout/stderr +are pointing to a Windows console, then this will flip the magic configuration +switch to enable Windows' built-in ANSI support. + +If you're on an older version of Windows, and your stdout/stderr are pointing to +a Windows console, then this will wrap ``sys.stdout`` and/or ``sys.stderr`` in a +magic file object that intercepts ANSI escape sequences and issues the +appropriate Win32 calls to emulate them. + +In all other circumstances, it does nothing whatsoever. Basically the idea is +that this makes Windows act like Unix with respect to ANSI escape handling. + +It's safe to call this function multiple times. It's safe to call this function +on non-Windows platforms, but it won't do anything. It's safe to call this +function when one or both of your stdout/stderr are redirected to a file – it +won't do anything to those streams. + +Alternatively, you can use the older interface with more features (but also more +potential footguns): + +.. code-block:: python + + from colorama import init + init() + +This does the same thing as ``just_fix_windows_console``, except for the +following differences: + +- It's not safe to call ``init`` multiple times; you can end up with multiple + layers of wrapping and broken ANSI support. + +- Colorama will apply a heuristic to guess whether stdout/stderr support ANSI, + and if it thinks they don't, then it will wrap ``sys.stdout`` and + ``sys.stderr`` in a magic file object that strips out ANSI escape sequences + before printing them. This happens on all platforms, and can be convenient if + you want to write your code to emit ANSI escape sequences unconditionally, and + let Colorama decide whether they should actually be output. But note that + Colorama's heuristic is not particularly clever. + +- ``init`` also accepts explicit keyword args to enable/disable various + functionality – see below. + +To stop using Colorama before your program exits, simply call ``deinit()``. +This will restore ``stdout`` and ``stderr`` to their original values, so that +Colorama is disabled. To resume using Colorama again, call ``reinit()``; it is +cheaper than calling ``init()`` again (but does the same thing). + +Most users should depend on ``colorama >= 0.4.6``, and use +``just_fix_windows_console``. The old ``init`` interface will be supported +indefinitely for backwards compatibility, but we don't plan to fix any issues +with it, also for backwards compatibility. + +Colored Output +.............. + +Cross-platform printing of colored text can then be done using Colorama's +constant shorthand for ANSI escape sequences. These are deliberately +rudimentary, see below. + +.. code-block:: python + + from colorama import Fore, Back, Style + print(Fore.RED + 'some red text') + print(Back.GREEN + 'and with a green background') + print(Style.DIM + 'and in dim text') + print(Style.RESET_ALL) + print('back to normal now') + +...or simply by manually printing ANSI sequences from your own code: + +.. code-block:: python + + print('\033[31m' + 'some red text') + print('\033[39m') # and reset to default color + +...or, Colorama can be used in conjunction with existing ANSI libraries +such as the venerable `Termcolor `_ +the fabulous `Blessings `_, +or the incredible `_Rich `_. + +If you wish Colorama's Fore, Back and Style constants were more capable, +then consider using one of the above highly capable libraries to generate +colors, etc, and use Colorama just for its primary purpose: to convert +those ANSI sequences to also work on Windows: + +SIMILARLY, do not send PRs adding the generation of new ANSI types to Colorama. +We are only interested in converting ANSI codes to win32 API calls, not +shortcuts like the above to generate ANSI characters. + +.. code-block:: python + + from colorama import just_fix_windows_console + from termcolor import colored + + # use Colorama to make Termcolor work on Windows too + just_fix_windows_console() + + # then use Termcolor for all colored text output + print(colored('Hello, World!', 'green', 'on_red')) + +Available formatting constants are:: + + Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. + Style: DIM, NORMAL, BRIGHT, RESET_ALL + +``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will +perform this reset automatically on program exit. + +These are fairly well supported, but not part of the standard:: + + Fore: LIGHTBLACK_EX, LIGHTRED_EX, LIGHTGREEN_EX, LIGHTYELLOW_EX, LIGHTBLUE_EX, LIGHTMAGENTA_EX, LIGHTCYAN_EX, LIGHTWHITE_EX + Back: LIGHTBLACK_EX, LIGHTRED_EX, LIGHTGREEN_EX, LIGHTYELLOW_EX, LIGHTBLUE_EX, LIGHTMAGENTA_EX, LIGHTCYAN_EX, LIGHTWHITE_EX + +Cursor Positioning +.................. + +ANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for +an example of how to generate them. + +Init Keyword Args +................. + +``init()`` accepts some ``**kwargs`` to override default behaviour. + +init(autoreset=False): + If you find yourself repeatedly sending reset sequences to turn off color + changes at the end of every print, then ``init(autoreset=True)`` will + automate that: + + .. code-block:: python + + from colorama import init + init(autoreset=True) + print(Fore.RED + 'some red text') + print('automatically back to default color again') + +init(strip=None): + Pass ``True`` or ``False`` to override whether ANSI codes should be + stripped from the output. The default behaviour is to strip if on Windows + or if output is redirected (not a tty). + +init(convert=None): + Pass ``True`` or ``False`` to override whether to convert ANSI codes in the + output into win32 calls. The default behaviour is to convert if on Windows + and output is to a tty (terminal). + +init(wrap=True): + On Windows, Colorama works by replacing ``sys.stdout`` and ``sys.stderr`` + with proxy objects, which override the ``.write()`` method to do their work. + If this wrapping causes you problems, then this can be disabled by passing + ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or + ``strip`` or ``convert`` are True. + + When wrapping is disabled, colored printing on non-Windows platforms will + continue to work as normal. To do cross-platform colored output, you can + use Colorama's ``AnsiToWin32`` proxy directly: + + .. code-block:: python + + import sys + from colorama import init, AnsiToWin32 + init(wrap=False) + stream = AnsiToWin32(sys.stderr).stream + + # Python 2 + print >>stream, Fore.BLUE + 'blue text on stderr' + + # Python 3 + print(Fore.BLUE + 'blue text on stderr', file=stream) + +Recognised ANSI Sequences +......................... + +ANSI sequences generally take the form:: + + ESC [ ; ... + +Where ```` is an integer, and ```` is a single letter. Zero or +more params are passed to a ````. If no params are passed, it is +generally synonymous with passing a single zero. No spaces exist in the +sequence; they have been inserted here simply to read more easily. + +The only ANSI sequences that Colorama converts into win32 calls are:: + + ESC [ 0 m # reset all (colors and brightness) + ESC [ 1 m # bright + ESC [ 2 m # dim (looks same as normal brightness) + ESC [ 22 m # normal brightness + + # FOREGROUND: + ESC [ 30 m # black + ESC [ 31 m # red + ESC [ 32 m # green + ESC [ 33 m # yellow + ESC [ 34 m # blue + ESC [ 35 m # magenta + ESC [ 36 m # cyan + ESC [ 37 m # white + ESC [ 39 m # reset + + # BACKGROUND + ESC [ 40 m # black + ESC [ 41 m # red + ESC [ 42 m # green + ESC [ 43 m # yellow + ESC [ 44 m # blue + ESC [ 45 m # magenta + ESC [ 46 m # cyan + ESC [ 47 m # white + ESC [ 49 m # reset + + # cursor positioning + ESC [ y;x H # position cursor at x across, y down + ESC [ y;x f # position cursor at x across, y down + ESC [ n A # move cursor n lines up + ESC [ n B # move cursor n lines down + ESC [ n C # move cursor n characters forward + ESC [ n D # move cursor n characters backward + + # clear the screen + ESC [ mode J # clear the screen + + # clear the line + ESC [ mode K # clear the line + +Multiple numeric params to the ``'m'`` command can be combined into a single +sequence:: + + ESC [ 36 ; 45 ; 1 m # bright cyan text on magenta background + +All other ANSI sequences of the form ``ESC [ ; ... `` +are silently stripped from the output on Windows. + +Any other form of ANSI sequence, such as single-character codes or alternative +initial characters, are not recognised or stripped. It would be cool to add +them though. Let me know if it would be useful for you, via the Issues on +GitHub. + +Status & Known Problems +----------------------- + +I've personally only tested it on Windows XP (CMD, Console2), Ubuntu +(gnome-terminal, xterm), and OS X. + +Some valid ANSI sequences aren't recognised. + +If you're hacking on the code, see `README-hacking.md`_. ESPECIALLY, see the +explanation there of why we do not want PRs that allow Colorama to generate new +types of ANSI codes. + +See outstanding issues and wish-list: +https://github.com/tartley/colorama/issues + +If anything doesn't work for you, or doesn't do what you expected or hoped for, +I'd love to hear about it on that issues list, would be delighted by patches, +and would be happy to grant commit access to anyone who submits a working patch +or two. + +.. _README-hacking.md: README-hacking.md + +License +------- + +Copyright Jonathan Hartley & Arnon Yaari, 2013-2020. BSD 3-Clause license; see +LICENSE file. + +Professional support +-------------------- + +.. |tideliftlogo| image:: https://cdn2.hubspot.net/hubfs/4008838/website/logos/logos_for_download/Tidelift_primary-shorthand-logo.png + :alt: Tidelift + :target: https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=readme + +.. list-table:: + :widths: 10 100 + + * - |tideliftlogo| + - Professional support for colorama is available as part of the + `Tidelift Subscription`_. + Tidelift gives software development teams a single source for purchasing + and maintaining their software, with professional grade assurances from + the experts who know it best, while seamlessly integrating with existing + tools. + +.. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=readme + +Thanks +------ + +See the CHANGELOG for more thanks! + +* Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5. +* Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``, + providing a solution to issue #7's setuptools/distutils debate, + and other fixes. +* User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``. +* Matthew McCormick for politely pointing out a longstanding crash on non-Win. +* Ben Hoyt, for a magnificent fix under 64-bit Windows. +* Jesse at Empty Square for submitting a fix for examples in the README. +* User 'jamessp', an observant documentation fix for cursor positioning. +* User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7 + fix. +* Julien Stuyck, for wisely suggesting Python3 compatible updates to README. +* Daniel Griffith for multiple fabulous patches. +* Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty + output. +* Roger Binns, for many suggestions, valuable feedback, & bug reports. +* Tim Golden for thought and much appreciated feedback on the initial idea. +* User 'Zearin' for updates to the README file. +* John Szakmeister for adding support for light colors +* Charles Merriam for adding documentation to demos +* Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes +* Florian Bruhin for a fix when stdout or stderr are None +* Thomas Weininger for fixing ValueError on Windows +* Remi Rampin for better Github integration and fixes to the README file +* Simeon Visser for closing a file handle using 'with' and updating classifiers + to include Python 3.3 and 3.4 +* Andy Neff for fixing RESET of LIGHT_EX colors. +* Jonathan Hartley for the initial idea and implementation. diff --git a/.venv/Lib/site-packages/colorama-0.4.6.dist-info/RECORD b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/RECORD new file mode 100644 index 0000000..8c5f12d --- /dev/null +++ b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/RECORD @@ -0,0 +1,31 @@ +colorama-0.4.6.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +colorama-0.4.6.dist-info/METADATA,sha256=e67SnrUMOym9sz_4TjF3vxvAV4T3aF7NyqRHHH3YEMw,17158 +colorama-0.4.6.dist-info/RECORD,, +colorama-0.4.6.dist-info/WHEEL,sha256=cdcF4Fbd0FPtw2EMIOwH-3rSOTUdTCeOSXRMD1iLUb8,105 +colorama-0.4.6.dist-info/licenses/LICENSE.txt,sha256=ysNcAmhuXQSlpxQL-zs25zrtSWZW6JEQLkKIhteTAxg,1491 +colorama/__init__.py,sha256=wePQA4U20tKgYARySLEC047ucNX-g8pRLpYBuiHlLb8,266 +colorama/__pycache__/__init__.cpython-310.pyc,, +colorama/__pycache__/ansi.cpython-310.pyc,, +colorama/__pycache__/ansitowin32.cpython-310.pyc,, +colorama/__pycache__/initialise.cpython-310.pyc,, +colorama/__pycache__/win32.cpython-310.pyc,, +colorama/__pycache__/winterm.cpython-310.pyc,, +colorama/ansi.py,sha256=Top4EeEuaQdBWdteKMEcGOTeKeF19Q-Wo_6_Cj5kOzQ,2522 +colorama/ansitowin32.py,sha256=vPNYa3OZbxjbuFyaVo0Tmhmy1FZ1lKMWCnT7odXpItk,11128 +colorama/initialise.py,sha256=-hIny86ClXo39ixh5iSCfUIa2f_h_bgKRDW7gqs-KLU,3325 +colorama/tests/__init__.py,sha256=MkgPAEzGQd-Rq0w0PZXSX2LadRWhUECcisJY8lSrm4Q,75 +colorama/tests/__pycache__/__init__.cpython-310.pyc,, +colorama/tests/__pycache__/ansi_test.cpython-310.pyc,, +colorama/tests/__pycache__/ansitowin32_test.cpython-310.pyc,, +colorama/tests/__pycache__/initialise_test.cpython-310.pyc,, +colorama/tests/__pycache__/isatty_test.cpython-310.pyc,, +colorama/tests/__pycache__/utils.cpython-310.pyc,, +colorama/tests/__pycache__/winterm_test.cpython-310.pyc,, +colorama/tests/ansi_test.py,sha256=FeViDrUINIZcr505PAxvU4AjXz1asEiALs9GXMhwRaE,2839 +colorama/tests/ansitowin32_test.py,sha256=RN7AIhMJ5EqDsYaCjVo-o4u8JzDD4ukJbmevWKS70rY,10678 +colorama/tests/initialise_test.py,sha256=BbPy-XfyHwJ6zKozuQOvNvQZzsx9vdb_0bYXn7hsBTc,6741 +colorama/tests/isatty_test.py,sha256=Pg26LRpv0yQDB5Ac-sxgVXG7hsA1NYvapFgApZfYzZg,1866 +colorama/tests/utils.py,sha256=1IIRylG39z5-dzq09R_ngufxyPZxgldNbrxKxUGwGKE,1079 +colorama/tests/winterm_test.py,sha256=qoWFPEjym5gm2RuMwpf3pOis3a5r_PJZFCzK254JL8A,3709 +colorama/win32.py,sha256=YQOKwMTwtGBbsY4dL5HYTvwTeP9wIQra5MvPNddpxZs,6181 +colorama/winterm.py,sha256=XCQFDHjPi6AHYNdZwy0tA02H-Jh48Jp-HvCjeLeLp3U,7134 diff --git a/.venv/Lib/site-packages/colorama-0.4.6.dist-info/WHEEL b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/WHEEL new file mode 100644 index 0000000..d79189f --- /dev/null +++ b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.11.1 +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/colorama-0.4.6.dist-info/licenses/LICENSE.txt b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/licenses/LICENSE.txt new file mode 100644 index 0000000..3105888 --- /dev/null +++ b/.venv/Lib/site-packages/colorama-0.4.6.dist-info/licenses/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2010 Jonathan Hartley +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holders, nor those of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/colorama/__init__.py b/.venv/Lib/site-packages/colorama/__init__.py new file mode 100644 index 0000000..383101c --- /dev/null +++ b/.venv/Lib/site-packages/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text, just_fix_windows_console +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.4.6' + diff --git a/.venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/colorama/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..185a870939a5a8000c01e48349dea0f81977b354 GIT binary patch literal 456 zcmYk2%}N6?5P&zk+3j|>?YReEU=LQ?N)IApErW+s_G-R)+9m#^)RWhe+f!T2wsH!l3K*B*6HBN0eMkPJyEBN9nWu#8EJ zAQp;5wn$5+B$aK_mKpIWy+0DU?2wMXW74hTc~B(ZzE)7g4s*pDm(*;p&0cpGT4+4vLXZ!BGCWwl@hcKAvg=I~{;cysZ**$L*7*~(aL3gq&svix2@ zay1^k$H#+{!Q`&!kqnCQN^r{z%x5A12E>5G!{N&RH7&4HKpOzNA~{4F?Ry!IOzu4{ zr*zGXh#gF20km@WS{a6~C|OX*;_bLpAX^-8dF*q(*94p1L;P#XRMTHkuP literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-310.pyc b/.venv/Lib/site-packages/colorama/__pycache__/ansi.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49bccb51749fe25b9295d593be11852e1424aa2e GIT binary patch literal 2982 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/__pycache__/win32.cpython-310.pyc b/.venv/Lib/site-packages/colorama/__pycache__/win32.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e199b5a1f13ac7ec2be982e3a37bd1357b1a3c11 GIT binary patch literal 4449 zcmaJ^%~Ko66`$_u84W^+58D{yFD?F*&9YfL*{y6`&VrC_QnKVo*kq?jO%3W6NR~8g z&&U``RAm>Rb4gWhslum}bIZTe*HjKZC%MFxkoS5d5ZGkIynfxUr~CEqee@$38A%%O z{QdQp;>MI={0%#U&k%IJg*QA)4TBr5!HG*ab?MG|ZgSQ%T@zZXX||Zlh#{CT8`d6i zZ5Xv-G~p(Qv0}6*nIRl8RHNJXiGe@PU`~QNZwxodhjcsq9gJ3tEd#zy!nY|m)f#a} zT4^`k8g)lu^+aRL9e-@_VV-(p@RS(YGu;VcH_kN9y5~STxlY76?>ul*&|c7zY4@V; zkBW&svQEWCEx!b9EKjE)jEs+-Z$agb$tvP@6*nLDFpX`qv0T#RB1 zdst$oH*=;p^O}2I&xAcbntQ!B_j+&c4fiI@xdkV=*^}JtNp8DYy-I%{Dzd#9+1`vh z?%m!#lc4Y2p7gGFfsgPsAU(@R`53gr!l)5G&L`dwcbcE!XSEe(_#{6MBUkwpzW^hj z^J#t&+H3q0zYOghzrwFVdz)wYXVBh3Yh|z1|8;P1Q2!^8_Y6GcJ-kLSOVmiAz9xOS zT?l+GBn&uP^>(zqDZ(mF=|2P*d>_O64_ts772_Q#z5}9&ClfHF$-jS<`)2idC}g-A zwu3FcnycLZ>dVz!M@rGIZqILSuFky@?N_U??`l|&#OIrS^`*Zq!qsZf45Z)kzW@#H z-<#XqR?dT_-&*7T!!g_zeA{4#9ERpp-K2$z*hsWW&LO9}7)E-5ab!|JvP@ZP+fvlj zP$iO`YSfWJ*;TK);Y*cxR$3}9=gY^ogO3c{;9GdZhd_h@!DhG=g3jbruo~s2rc783 z8+sPB321E`UAJ7P7g9rf2uzby)45WyQYz%VO0JyG7rlk&j~?aA-cs>VY3EF+waV1n z8Gxl4wC6VFl+Cv)^&O$c_!a;g2J%?|P}YOC8s3_ZB3WPSL?Tp9C|Bxj9&D*IeCw(I zy58!v;sN}+iuUY3$Riv%c*7?^IO!StS>^ir zMkFUe3_i<3(X1W$phPpPgy#Wvo|l16mg3Vw`C0kuEu%$$z;T<_B&7{~Fvw%-z- zr;?u63V5f9e9H5_@A%E01h(Qq6^5-`sZ?H+7$AzR0IQOfr}Kq^SI*~_VX0bOG!(9RDK>Ms&Ja%-<2YCDtU$_>HAB?W?+XNimz=OYlg!MheJf-tN zmS_dCRMEMgD6(-<{hifiV~0h34(*(Q4jdA2 zK}&BvHn(``#ez`1OM~4Y5Ys#O& z=gRUS#f7onC$v3(%BQ>VU5M~GBuV7YfmyDiPW=awKSUSLg)a1ah@&oP5Kdl_Fby1J z_?JYEp-Z70ByNmkul;>!1|XUs3Nre2Q7xL zc83LEdhWo$9mqa?8#}eR&${$2!PK?SI04RztS;-K%b1bfh3a+B+J&}}(07c6E$hVI zJ_@TU8_JCUN*df-S&KRuU-BN+o6TO%D|MpHPLzXt-mgYN&c`{=dgV7eBAbX2W4a8m zo1(oQZ73^@d>LtU)Ns4g^0s6>ibVU~gM@k(=*X_(k5182u=J~mSN@6wx zg+|cEssV&SAbEUY%w}#@5x{UI1|pMzj%9>FaOFn%n@V$@;yY1hQcF$TMzONkmE2(jgQ z)D$aFd{_~3C-oUU3Ku=|&#+vGi#tS?pgFcNrXmDOZ+sh=$k-=u@fwF}3(|V;8t>9@ zJYxISTjNJeOm<(fgm&^6ih)XOu zB_<+?fv#*Xt_-i?$T*HTFNJK2=KXsrHCQ>sk)z|q@#T7KHv7qZaj}qB2??bY{BIWD z1h;S*woob+KE>fg;aP5_vRu|i zme24TgjT*lg5{h}SlXWlY^1HFOG4)Xcor1Q4>7XBKLTMUBaBiSXFj|o(2dfB{%6Xv z=@@k;7_|=^)1lB3`@arD4$9yjM+Z2jiw^sPlZfXW@Ap@M;^f3Cj-6soBFUTyCka0@ GmG~b_S?OT_ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-310.pyc b/.venv/Lib/site-packages/colorama/__pycache__/winterm.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..960ef05421b1ea61704fa907c820302966277a8d GIT binary patch literal 5145 zcmaJ_Npl;=74Du5gM}ctNTjvclq|=E*peeFvCE2MlY~H;F$uZ=C^9FkngY>72{Z^W zJp)l>ft6IGt8>epJj#b0@>6o0LoTTtc=pW)E8pwEU=x*@>Nma4yngR{OHX@ZBE@k1 z_t{g7_8;wO2KL9zl1rxl<_PN73d&F832J^I|OPtXyG@-v>4&P!ee#nF& z%%;9?I0k2{OjsiEf{BD@KGz)!ZCfPKPO5eS?UYEPomOpIWW)sCloZ(t%TJ!;%Ph~s ziN{{xw*B2FwU%glbxz&Ai|QIm0mUbl1MvBr|CQ&p((z37NyA@g_^tPYg~LWmv=99o zcwJ(%Qk1eSQRVJSCQU5+X}xfN`=Reif7@@h55;z&a_^J7+l7vlUaNkzba1eJ=c(6v zy1m}m+4dWOcl)4L|E~7f^SA5mW?R6yObG5wru=HSva}t_V?9ZS!hoUeRu@9!H_cf+T=8H7-Zy*Dvg$7{j zLKg;}FcD$lX^I795FDz#A<`oAf##F^iRH^js2` z(UTGHia9Zl+Jv|zu86CsWl_5(uA??7-WKm*eoiDHs`tVKpi%`&U$Y`&yFhGz0TQrN z9F&0r7f!@uQPXsHV2DG#s%g1C!6D4{Cr53|Z8jc1310Hh@V(~lkg7?`WD<>5BXHff zNe~3r9M5oD-6``p*OT3yc-otVcnxbI7%E)wSzre>4Mkr@U5V(NkeN3meM>G7xk=;} zk@tuw^z|VaCdmsbQT!64%ClVK$5Sy+{n0vEetc2Auh~0jbivLdm~pA5eF<-=TD;2x zZBIurmVsW3n@W>I;CtGM z4lLwQ(@*q(pBi1g%g;1mo3zbKc~j=GQu$PQ1vTY7i{)}SSLr+0s`o7Dd(xibP&^9uG}GVHz-~rtbVTs<9*P~{oAv`?1I57Xr-Wea4lSeC zGP+t6DJUPo)+kcQw?M+2I7Hs%x8*l&WLk}OE9BpXd@CQRMSeze?1SFe*iOO>`N4Sb zkC>`d1bfx9*wXQAyq)1`Z`Ks;r>7~4w1Ak%m6oy;9ib(5st;>Peu4#%y4nn>NRl~) z^8@{i?krZ&?`SG1NbPQXPczDADUtNIR>$O?whX-(*){i|D+DkT{)f-8UG2oe9II<|ErA&Fy&fSnua{Qfc&(b)>-a%F zF(w2_d4>F($Zv^!34%!~V(@1nKN{LUiNl$SUgU}Xp2y`fQIBL2P29&KC6P!PDL#w) z_);v9k+~`^jHsRRPl`-RApb%|34{zX5=c+g5Qxz=_6&%Es5Q$Vptzl&Hd={2bB>)@ z01p37leekoB+)gy);v40Ti4L9q5nR>V?%&2ag16RnZ$^Wk=2nA6C+v#zSATEfYG(P zi8CCoFe?S{vD5S!i~D+Sc#N?O=9;nlP=V2k(lT{EkaYU{i7z1h5f&8br_G{2rx`yFT*&Z?MzBNz z?PKW&H2x2kB8*%o3@Id;WLShOV8v?P>S5&$^qD|{O(Qn&(nB9+%=9$=qIt)jOi&AiMQEkd4I>SzW@?zi8M3~-Q<*>h?0ipwd3j7+6RkAg4IYmOi2!;rh--E z!Xoz#lgCInIdIz5M$q))M9~bWHO{U&sHl;DV6n>1vqK3Y`QvDviV$#>D>x;=U*e&h z(Mo=5?5HZ=$BQB}q1;(g_O3ECNjZ_E6hu;diX7`A)gBNj5!obCCNdCf-v%Tdrzsou zDWA8Qt=Sn{Pno#WxGmdG*{KxDLgpEGG>7lkOqByMpJrJ<+FSA~& zwu4_OPmzYmcHQ&+M(goE@eYOHX(S;UJP8oXH6Ymd8A1n|tyeijaqX4-7BfrurDN^; zPwTR`jr7|7L0bmu`(cy-hE{uL&#MRO$BFt8p){q|U!?QU{yh4}^9B7P^6BKJ!G1Eh RwO1K4r{~f+ll?g}_di*Z7PtTa literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/ansi.py b/.venv/Lib/site-packages/colorama/ansi.py new file mode 100644 index 0000000..11ec695 --- /dev/null +++ b/.venv/Lib/site-packages/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\a' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/.venv/Lib/site-packages/colorama/ansitowin32.py b/.venv/Lib/site-packages/colorama/ansitowin32.py new file mode 100644 index 0000000..abf209e --- /dev/null +++ b/.venv/Lib/site-packages/colorama/ansitowin32.py @@ -0,0 +1,277 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style, BEL +from .winterm import enable_vt_processing, WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def __enter__(self, *args, **kwargs): + # special method lookup bypasses __getattr__/__getattribute__, see + # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit + # thus, contextlib magic methods are not proxied via __getattr__ + return self.__wrapped.__enter__(*args, **kwargs) + + def __exit__(self, *args, **kwargs): + return self.__wrapped.__exit__(*args, **kwargs) + + def __setstate__(self, state): + self.__dict__ = state + + def __getstate__(self): + return self.__dict__ + + def write(self, text): + self.__convertor.write(text) + + def isatty(self): + stream = self.__wrapped + if 'PYCHARM_HOSTED' in os.environ: + if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): + return True + try: + stream_isatty = stream.isatty + except AttributeError: + return False + else: + return stream_isatty() + + @property + def closed(self): + stream = self.__wrapped + try: + return stream.closed + # AttributeError in the case that the stream doesn't support being closed + # ValueError for the case that the stream has already been detached when atexit runs + except (AttributeError, ValueError): + return True + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]([^\a]*)(\a)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + try: + fd = wrapped.fileno() + except Exception: + fd = -1 + system_has_native_ansi = not on_windows or enable_vt_processing(fd) + have_tty = not self.stream.closed and self.stream.isatty() + need_conversion = conversion_supported and not system_has_native_ansi + + # should we strip ANSI sequences from our output? + if strip is None: + strip = need_conversion or not have_tty + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = need_conversion and have_tty + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not self.stream.closed: + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command == BEL: + if paramstring.count(";") == 1: + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text + + + def flush(self): + self.wrapped.flush() diff --git a/.venv/Lib/site-packages/colorama/initialise.py b/.venv/Lib/site-packages/colorama/initialise.py new file mode 100644 index 0000000..d5fd4b7 --- /dev/null +++ b/.venv/Lib/site-packages/colorama/initialise.py @@ -0,0 +1,121 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +def _wipe_internal_state_for_tests(): + global orig_stdout, orig_stderr + orig_stdout = None + orig_stderr = None + + global wrapped_stdout, wrapped_stderr + wrapped_stdout = None + wrapped_stderr = None + + global atexit_done + atexit_done = False + + global fixed_windows_console + fixed_windows_console = False + + try: + # no-op if it wasn't registered + atexit.unregister(reset_all) + except AttributeError: + # python 2: no atexit.unregister. Oh well, we did our best. + pass + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +def just_fix_windows_console(): + global fixed_windows_console + + if sys.platform != "win32": + return + if fixed_windows_console: + return + if wrapped_stdout is not None or wrapped_stderr is not None: + # Someone already ran init() and it did stuff, so we won't second-guess them + return + + # On newer versions of Windows, AnsiToWin32.__init__ will implicitly enable the + # native ANSI support in the console as a side-effect. We only need to actually + # replace sys.stdout/stderr if we're in the old-style conversion mode. + new_stdout = AnsiToWin32(sys.stdout, convert=None, strip=None, autoreset=False) + if new_stdout.convert: + sys.stdout = new_stdout + new_stderr = AnsiToWin32(sys.stderr, convert=None, strip=None, autoreset=False) + if new_stderr.convert: + sys.stderr = new_stderr + + fixed_windows_console = True + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + +# Use this for initial setup as well, to reduce code duplication +_wipe_internal_state_for_tests() diff --git a/.venv/Lib/site-packages/colorama/tests/__init__.py b/.venv/Lib/site-packages/colorama/tests/__init__.py new file mode 100644 index 0000000..8c5661e --- /dev/null +++ b/.venv/Lib/site-packages/colorama/tests/__init__.py @@ -0,0 +1 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. diff --git a/.venv/Lib/site-packages/colorama/tests/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/colorama/tests/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12f02548e86dcb26fba35a8da164da506f414038 GIT binary patch literal 176 zcmd1j<>g`kf~OURsop^PF^Gc<7=auIATDMB5-AM944RC7D;bJF!U*D5u(MT6XmM&$ zaZGVuetAlabFi_QVT^NWQBi7Ma;0NIL5yBmYF=54Pi9g~ab`)XZb4#lc4B&JaZGZ4 uPJU5hZlZokYH>-ietdjpUS>&ryk0@&Ee@O9{FKt1R6CGm#Y{kgg#iG`bu7pL literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/tests/__pycache__/ansi_test.cpython-310.pyc b/.venv/Lib/site-packages/colorama/tests/__pycache__/ansi_test.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09361c52ae950066c062531d78781e5745902fc6 GIT binary patch literal 2268 zcma)7TXWk)6yDX%@->cAQXqwL2LVl*#I$3EfjW*zGdS){>`bWQ8I7719lMrgR&ql! zyrn+`9{ZQ}mEobU^oG+B<>AT5?>1&}#b>=LIWY`Fm(=#YYu^9RQms22Q_&j5ZUzmb%t+E72Gsqwo; zXEWyc3?p6goOT?`s{~0B^0X7D?$6U;B#iWU5(+&zPK1@DES{#^2BVUMoIj_+NW#%i z&k3K0>A!oeulsvoAn7OL_=xpe-Ss=G{nnK8aC~^&oJ{)5Ps8!ketYn!pA6FQ)&wFK zJPwooVLXa?5CtnKc$BOJ5Ii4;%adbaCSkfash~&bT1{W1CzW&Wm*wK67+{2D45~0l zAp*XZ>VO9N%CXQKQxug;e#{4tc?srt89+{hb7~s5<#Pz=p@JH|Wv5}lH{+x6HDK~! z7A??|`Tq`fzJBR!=lOa07ig;d3?cio+zfT5WthSA3^Q3Ki$jZNn#*OY1Gr8Ct%7ulR-XIssdaZ6;%mfRZXl?7SD?**GsGfny6 z(G=)g;NZ&-04ns-PtVTO=*d#1a4*_ejR~f0RjMP;| z>MEgiNT{`RuzDNxr33>~f(0qTgp^=IN-!cNSdkJF%in~9a1#NY=5He`A>2TC2jN|W zn+WeAypMpv;U6M=gzz!KCkUS+U<2h2!c`qW1{{0;EZ{5n?iT%+&9-N4>|(`U>CggJki5WV9=Tv4 z!4Cz?1_hr>a2-Gx0bD4mJkS>| z<5I-QG(N&BT3&0i{d4T+T(})%*$1W6ZSXC#c%QAO;FXQReDV;QA@LERkyz@ IP~)F}0h1L0!TldSBg*aJR4+Np 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/tests/__pycache__/utils.cpython-310.pyc b/.venv/Lib/site-packages/colorama/tests/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..69074338f617a5881354ad218372d857ee43c1a4 GIT binary patch literal 1576 zcmaJ>-D?|15Z{l}>2x|fYMs&)OyW=o9Hn+dp@otb8zpT5tsE*R!H3{DYq!p|r#p4` zlvqXv2l+jJhySI0Eq&;--tv;p>_xU>lI}5c^Rc`0o0;7$R#tohm4|DDqMsmBS=Y4y6K%*DF<; zA3oac4sg!$V4!RR&94KKB%*>uOi;njNW|^Fj%mPhnGE;#_6HPZEe6U+9iTbZK~R9f zx_js3oEk^V>~~cMvt@4{cfRjG(NgKY&Wo3#-|2nxZM)wYD<$*6WM?$$Z@!TEi~cX^ zL0_k({CboO{sjEGKPa+7CBtN^l)BVg<1)?k=4fKvR3~LQX<&Fv!=cBm3#6NsvwQ9s zFOKtMDC5}paXc)Jr#1xQWyZ3?brC>Zg20w{jjF+T`_gI*{LdWdj=Jj&ZZI4sGb*j47d1d4eF!G z;CZ5kUtv;sa@na5C+Ir$==xiBx=sS7?tnQAjQ{Sv%hCgd=g6?MP#gqXc?-Z^+A279 q^b&#HV=1=ngl&R%uX-we#PVuvQ$PcV?$H)+In41XbAcL2tMotowlFUM literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/colorama/tests/__pycache__/winterm_test.cpython-310.pyc b/.venv/Lib/site-packages/colorama/tests/__pycache__/winterm_test.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e5ebe54c9cc4ebeb5f224405f7948511ed76c09 GIT binary patch literal 3169 zcma)8%Wo4$7@yf)uXp{52?w@^irrXf-YRcw^9vb0(}6R_EbnOPHJ zg;Th;r~U!SG57v8bFF&tnOhIg@0+!q5GTN{=C?EReKR}r`yMk%xm+Od{QLX{e^DXi zA8Z_d9BABzBL4(ngwc?A_%%Wr8J-cDo*7x5MM=K^y=It;Y|oDJUY?Ro5}&gOcXn!& z;H%~Ck^BLP={8{&%Y}ug=oO=qSBlDBnUWR4Y?gmXSe_eurdQ!p%z0vnWp3`_JhZM$ z%^kp+$a>9GPJ_#IDUe)QQP7T6K|X1B@5dpRvSujjZqj<9a@`-H3zsgv5Q zDh@Y?O!Y6caO*)7%x$;h6t;}t`I{{yXY}Bvu`EH6cK}kdM_w3=?ixOnUD`2xGqs@4 z+$HqBoF4gD1 zyU|?g3Blvm&O*1_oO{OOXU(;_ zJDq~xNQgRO8#Z;QO)KzD)BX&s3mvh614hcqgn9Z^!Jqcpg3BwQ!;)>;qA-5+p#6|g zZL`0iqHRXOX4KCR?MHpIn6*pya|aMfXqOaR7j=&Mv1cf8Kw`Wt0ja}`8FG zdsZBMq?3X?)717i*99(mPz9(JwdKSN)Ws~q1%&ee%6-IBKLEQ(fezx?50=-~?rnPc zy9+DJ>x~8B>fXhT)s;JqLqlA`ksl$T{WAC%YN~`Bf+wMkB`V0P06;p>Zqq7tjA}nAgxxBqbLxB6<6`vb6ZZG4{T=sk;TjV2phUXqXrk6B!3hYT%m zY@E%|g|`{H7uWUA1PngGROyJRt7kJcnqa+FRgUk+LBxGu6?{KRSTDqS$@lTfkVym* zDLz5Kl%q_!BbCz)gA~$11b53c5UJd5r;o*FsPrYm*9e&J#7%_n5q>~8N*B6@=aDD^ zl%eQj$N|e2Xw@xHdltUaPzqVG;cHhaRO{o)@oww;wW_!UgFUAQR|up^peG0u0T=9* zM}j%L*km~$_oRxeQ8$6>kr0XSEEIZqaB{r#=o3~Ss97e&C5j&rPT7ERZe`T{j3> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + self._light = 0 + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + elif mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + elif mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + else: + # invalid mode + return + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) + + +def enable_vt_processing(fd): + if win32.windll is None or not win32.winapi_test(): + return False + + try: + handle = get_osfhandle(fd) + mode = win32.GetConsoleMode(handle) + win32.SetConsoleMode( + handle, + mode | win32.ENABLE_VIRTUAL_TERMINAL_PROCESSING, + ) + + mode = win32.GetConsoleMode(handle) + if mode & win32.ENABLE_VIRTUAL_TERMINAL_PROCESSING: + return True + # Can get TypeError in testsuite where 'fd' is a Mock() + except (OSError, TypeError): + return False diff --git a/.venv/Lib/site-packages/distutils-precedence.pth b/.venv/Lib/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..7f009fe --- /dev/null +++ b/.venv/Lib/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'local') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/INSTALLER b/.venv/Lib/site-packages/flask-3.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/flask-3.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/LICENSE.rst b/.venv/Lib/site-packages/flask-3.0.0.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/.venv/Lib/site-packages/flask-3.0.0.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/METADATA b/.venv/Lib/site-packages/flask-3.0.0.dist-info/METADATA new file mode 100644 index 0000000..b802e93 --- /dev/null +++ b/.venv/Lib/site-packages/flask-3.0.0.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 3.0.0 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.8 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Requires-Dist: Werkzeug>=3.0.0 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.1.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.6.2 +Requires-Dist: importlib-metadata>=3.6.0; python_version < '3.10' +Requires-Dist: asgiref>=3.2 ; extra == "async" +Requires-Dist: python-dotenv ; extra == "dotenv" +Project-URL: Changes, https://flask.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://flask.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/ +Project-URL: Source Code, https://github.com/pallets/flask/ +Provides-Extra: async +Provides-Extra: dotenv + +Flask +===== + +Flask is a lightweight `WSGI`_ web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around `Werkzeug`_ +and `Jinja`_ and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + +.. _WSGI: https://wsgi.readthedocs.io/ +.. _Werkzeug: https://werkzeug.palletsprojects.com/ +.. _Jinja: https://jinja.palletsprojects.com/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Flask + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + # save this as app.py + from flask import Flask + + app = Flask(__name__) + + @app.route("/") + def hello(): + return "Hello, World!" + +.. code-block:: text + + $ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Contributing +------------ + +For guidance on setting up a development environment and how to make a +contribution to Flask, see the `contributing guidelines`_. + +.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst + + +Donate +------ + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://flask.palletsprojects.com/ +- Changes: https://flask.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Flask/ +- Source Code: https://github.com/pallets/flask/ +- Issue Tracker: https://github.com/pallets/flask/issues/ +- Chat: https://discord.gg/pallets + diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/RECORD b/.venv/Lib/site-packages/flask-3.0.0.dist-info/RECORD new file mode 100644 index 0000000..eb371fb --- /dev/null +++ b/.venv/Lib/site-packages/flask-3.0.0.dist-info/RECORD @@ -0,0 +1,58 @@ +../../Scripts/flask.exe,sha256=R4wc2ydw8V4MaKNEP25DKp7XkwD_piE3NtZvdHCjAP8,107891 +flask-3.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.0.0.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.0.0.dist-info/METADATA,sha256=02XP69VTiwn5blcRgHcyuSQ2cLTuJFV8FXw2x4QnxKo,3588 +flask-3.0.0.dist-info/RECORD,, +flask-3.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.0.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +flask-3.0.0.dist-info/entry_points.txt,sha256=bBP7hTOS5fz9zLtC7sPofBZAlMkEvBxu7KqS6l5lvc4,40 +flask/__init__.py,sha256=6xMqdVA0FIQ2U1KVaGX3lzNCdXPzoHPaa0hvQCNcfSk,2625 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-310.pyc,, +flask/__pycache__/__main__.cpython-310.pyc,, +flask/__pycache__/app.cpython-310.pyc,, +flask/__pycache__/blueprints.cpython-310.pyc,, +flask/__pycache__/cli.cpython-310.pyc,, +flask/__pycache__/config.cpython-310.pyc,, +flask/__pycache__/ctx.cpython-310.pyc,, +flask/__pycache__/debughelpers.cpython-310.pyc,, +flask/__pycache__/globals.cpython-310.pyc,, +flask/__pycache__/helpers.cpython-310.pyc,, +flask/__pycache__/logging.cpython-310.pyc,, +flask/__pycache__/sessions.cpython-310.pyc,, +flask/__pycache__/signals.cpython-310.pyc,, +flask/__pycache__/templating.cpython-310.pyc,, +flask/__pycache__/testing.cpython-310.pyc,, +flask/__pycache__/typing.cpython-310.pyc,, +flask/__pycache__/views.cpython-310.pyc,, +flask/__pycache__/wrappers.cpython-310.pyc,, +flask/app.py,sha256=voUkc9xk9B039AhVrU21GDpsQ6wqrr-NobqLx8fURfQ,59201 +flask/blueprints.py,sha256=zO8bLO9Xy1aVD92bDmzihutjVEXf8xdDaVfiy7c--Ck,3129 +flask/cli.py,sha256=PDwZCfPagi5GUzb-D6dEN7y20gWiVAg3ejRnxBKNHPA,33821 +flask/config.py,sha256=YZSZ-xpFj1iW1B1Kj1iDhpc5s7pHncloiRLqXhsU7Hs,12856 +flask/ctx.py,sha256=x2kGzUXtPzVyi2YSKrU_PV1AvtxTmh2iRdriJRTSPGM,14841 +flask/debughelpers.py,sha256=WKzD2FNTSimNSwCJVLr9_fFo1f2VlTWB5EZ6lmR5bwE,5548 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=ynEoMB7fdF5Y1P-ngxMjZDZWfrJ4St-9OGZZsTcUwx8,22992 +flask/json/__init__.py,sha256=pdtpoK2b0b1u7Sxbx3feM7VWhsI20l1yGAvbYWxaxvc,5572 +flask/json/__pycache__/__init__.cpython-310.pyc,, +flask/json/__pycache__/provider.cpython-310.pyc,, +flask/json/__pycache__/tag.cpython-310.pyc,, +flask/json/provider.py,sha256=VBKSK75t3OsTvZ3N10B3Fsu7-NdpfrGYcl41goQJ3q8,7640 +flask/json/tag.py,sha256=ihb7QWrNEr0YC3KD4TolZbftgSPCuLk7FAvK49huYC0,8871 +flask/logging.py,sha256=VcdJgW4Axm5l_-7vXLQjRTL0eckaMks7Ya_HaoDm0wg,2330 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228 +flask/sansio/__pycache__/app.cpython-310.pyc,, +flask/sansio/__pycache__/blueprints.cpython-310.pyc,, +flask/sansio/__pycache__/scaffold.cpython-310.pyc,, +flask/sansio/app.py,sha256=nZWCFMOW8qK95Ck9UvDzxvswQr-coLJhIFaa_OVobCc,37977 +flask/sansio/blueprints.py,sha256=caskVI1Zf3mM5msevK5-tWy3VqX_A8mlB0KGNyRx5_0,24319 +flask/sansio/scaffold.py,sha256=-Cus0cVS4PmLof4qLvfjSQzk4AKsLqPR6LBpv6ALw3Y,30580 +flask/sessions.py,sha256=rFH2QKXG24dEazkKGxAHqUpAUh_30hDHrddhVYgAcY0,14169 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=EtL8CE5z2aefdR1I-TWYVNg0cSuXBqz_lvOGKeggktk,7538 +flask/testing.py,sha256=h7AinggrMgGzKlDN66VfB0JjWW4Z1U_OD6FyjqBNiYM,10017 +flask/typing.py,sha256=2pGlhSaZqJVJOoh-QdH-20QVzl2r-zLXyP8otXfCCs4,3156 +flask/views.py,sha256=V5hOGZLx0Bn99QGcM6mh5x_uM-MypVT0-RysEFU84jc,6789 +flask/wrappers.py,sha256=PhMp3teK3SnEmIdog59cO_DHiZ9Btn0qI1EifrTdwP8,5709 diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/REQUESTED b/.venv/Lib/site-packages/flask-3.0.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/WHEEL b/.venv/Lib/site-packages/flask-3.0.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/.venv/Lib/site-packages/flask-3.0.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/flask-3.0.0.dist-info/entry_points.txt b/.venv/Lib/site-packages/flask-3.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/.venv/Lib/site-packages/flask-3.0.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/.venv/Lib/site-packages/flask/__init__.py b/.venv/Lib/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/.venv/Lib/site-packages/flask/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import typing as t + +from . import json as json +from .app import Flask as Flask +from .blueprints import Blueprint as Blueprint +from .config import Config as Config +from .ctx import after_this_request as after_this_request +from .ctx import copy_current_request_context as copy_current_request_context +from .ctx import has_app_context as has_app_context +from .ctx import has_request_context as has_request_context +from .globals import current_app as current_app +from .globals import g as g +from .globals import request as request +from .globals import session as session +from .helpers import abort as abort +from .helpers import flash as flash +from .helpers import get_flashed_messages as get_flashed_messages +from .helpers import get_template_attribute as get_template_attribute +from .helpers import make_response as make_response +from .helpers import redirect as redirect +from .helpers import send_file as send_file +from .helpers import send_from_directory as send_from_directory +from .helpers import stream_with_context as stream_with_context +from .helpers import url_for as url_for +from .json import jsonify as jsonify +from .signals import appcontext_popped as appcontext_popped +from .signals import appcontext_pushed as appcontext_pushed +from .signals import appcontext_tearing_down as appcontext_tearing_down +from .signals import before_render_template as before_render_template +from .signals import got_request_exception as got_request_exception +from .signals import message_flashed as message_flashed +from .signals import request_finished as request_finished +from .signals import request_started as request_started +from .signals import request_tearing_down as request_tearing_down +from .signals import template_rendered as template_rendered +from .templating import render_template as render_template +from .templating import render_template_string as render_template_string +from .templating import stream_template as stream_template +from .templating import stream_template_string as stream_template_string +from .wrappers import Request as Request +from .wrappers import Response as Response + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Flask 3.1. Use feature detection or" + " 'importlib.metadata.version(\"flask\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("flask") + + raise AttributeError(name) diff --git a/.venv/Lib/site-packages/flask/__main__.py b/.venv/Lib/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/.venv/Lib/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/.venv/Lib/site-packages/flask/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1cd9c139dec1171c9f3433e6e31518f3fc0ea0a4 GIT binary patch literal 2282 zcmb`I%W@k<6ozL;m(kU-Wm~@6faI5mFS!z=EQ(NJ3H7rK+isrX@|>bD_KC z3*~HpEh}CCmb}tzSx|Wa7O>%*6Dd)dEmHZ{*MIkPpFVwh99OF)13rIVpYSuFKd>?V z$w1>%!!XrfreXMoZwezcnQ0os!`|LjPzIYI}S)2F(_?R6NH-R6rhs1}#C+vi{B_4&R?3DNj_%VA7eBvMb z4}Z$Ck9_N;(R%b2E23qlWiN_i?dc$n)bqDc5NKv!t2lz++?T>r7XZc2#E2&{h%_|v z=W)~z20(SMueo&fFi@`K-;KD!{`Fp*+_=4wlswWC-|fYb=GWL?8+yw1l4Q!7M{7L8 zlwF=o0;AzU6W6pqEMzOL6a)@#&g;e!C(rdEA5=nc36zk$ByVIn-u zT~BKnbVr&)Pc`%|I7Fcm$ORe&$^Ag`9?n}-Jo4RsAh2WpT|>s9`))uiZ^+h?d!c(3 z=;72Z?2#01KbA1U#>57F96Sem8t24K;w0hzU2~*{WG+pO)ZBwp7`T3Xh1+g)IZTW} zM?N0Jcw5l3IEX*wo?rKPf=3J;wQ(*cxdCf-lKFlR1>;3)6HjSRYKmiFV%-U1ZnEq+ z3>pm2-wmm8$8r_qKEgAt0b$}M6M@yZV|^HGzj$A1g%{()O0$s{@-zbvrFqHqNJf9> zbo(s2>0wDvKKSO#!QVN){hk5b!rSk{lB>Su8^U;F(y#f(y0uHaT6HBKVgbCEU2)gZ% zYtQ$z*B%FQxPwK1vD0e8WD1VTZ@;x5GRSEO&a!tQ_$3#N?#V^VPV4`jDlJ@jGJ>N~ zX%;E1e?E>HmjCu$S6Y}XoZ91+)0wl$ZTdn=sP~M#2Medg_bbR#X#Z}=r||RlSLaVV zutBLhDvGcC&iTvJCnueAdTsP>&XS}9TZ%3_UkBZe3N(L^K=62pJG8-L*M(};uG>y- z@EqV;W1^uAldA=gf{EX(WtmpSGV}jb?1Cln)LU5!Ox_2U4^Z%#)|0g4y8RJm8%`5* zmgesq}2Bk)wLoO0XiJV1i4yBGVkAi!Wizp40C6r~96_iyFW~*Qj;pA&*t)pz9 zY@%$TI4IjFJ1Dy-dmyYdzI?Dg`kg69>6sd7O2F^GcjB~KD znPH4`X;D#XUUH>lK|zdOS!!Ncj8A4#OmSvOs%}AIa&}^RYH>_jPGWJketbO0{P=ji ag34PQHo5sJr8%i~AghZ(cJMH8F#!O!2r=3K literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/app.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c49a02db1a653d327bf3526e51afbb48c43c534 GIT binary patch literal 49686 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%0D;20vK^l3eD1=Z1@`$Ns7tDOJ`p%I7y zAE?1YB(NqyidmLx4S3lBo*n$94GDq?F5|KoK(JNt5F*6z1BKffmk}BOHQGeJ#5*az zvIpom9FD*j4PP=4Hh&q4IT7N=&`6qZ32l16I4Pr|7Zg?wOflZ7R!*0c>(kf>|pO5^K! zcphj6_)beS^~Ld*-jyv0mP!u{vd77OO$EeouE&K~4A%tNHl&RP8aeQx%NXQpRnPn?^5_AD=- z@ayp&o>}j%_)@!lp<0DCw{Q}dTs9f054paIrGbWB`*@TqnsJmF1 zciDJ2Qtl(ttI38kQ8i37ud(GY4E`i_`b8z5W}(C--wJgQcV^@MC?=HQE4jo9D~A*- zqiID5OjWLm;@N*aL{I7!f%hMx^)Ha7Jb+BTI0kA0m5z5b-n6s0*#?%91Lhq!M=~Xt zE9h_^)s~f;qglrqvlQD`937Sx-O;^>Ll<-nn%ML*WmN`bK&0g{Bv{-%iJX$-A2@6m z#5f|bg0NStBCg$yvm$+{{g`>Q__RKc2N-4-xL<-{aNtyBo;tyG7Pt>o+X%EDPJ}0o zR3fx!K_+P>@@(Hd7{EkYyx>FaO2;BIi5w0Q4d6eCm@iH-x=X(BiBl&Y6aM+k+1V!n zldyfuYo1fsz=DW$je8l$0Wz@2;!rF6)=8xShDphX7-?BZcdb6<<%Iy^4W1?T5(g}Y zI}S@>R^@crE=y1i6yu z{&DZM#bd%6=z;6V50bUK0~uM%?uE(+(Q^AbB5)b?QhP~8wbv0TYc_fdrjB4rxGlU|Nepx$b6CR3=xz|Wm%e-Murs6qg6Pw%ba#WnnUVbfSvlmC4Tz6m~z>I7X zxRE|QD@#10Z^+|dkOV=9kXmnKlf|YoWyj{{BWvp6*xa1fQ^?4IsQb7ON11HnSX}pg zy>-9am^h?<4WsLT&fJ;;rLC>P#0mC~3+tiS_FRJMU$Ww1^njZ+5&TZ(qT^!z4POvW zC4yU!NV$9@-YD4CA*Q1WEK|6P;*xrt)juZ%xDo?${bA+{eharu(_V?IbS2sp(N5A9 z|4RzAmDyBwiR%;B_aro;Qe3J9xKf_HPY;I}7zh-8ZT zV2pIf_&MrBOoXHV7H0CtMB&rOjO=2RwvAvpTFXQ;unw5GNeicTdAk-Px^4J65y#C~ zM+>E>MFa04)JNna-oXdTKGhq8Eq4lnXqL8Mia;V(ykYlNNo{%FRT{#v! zTud41RjN9YpkLF3w9vhbrubc5MkB4???#$pqTK9=>?jw3<4^JP$nNX-9rz)%pCm}r zOrdX`1`mNpFQvA>hw|8#t?R+5mkk-#n|vg&{8zIvIZ$z?RJGVf^EyaRJm1W?5qx*K^v z&D;C*m0$?E<5K9$N_(;JWq`26!s~;SM_5I|BSfaY%EzNj=8?n>{JY>eu^Gk%ImwJO zy@6b=5$AdOjyJFfk_o<6irSVA^~IMnwrYtzkrDK6lq=J|K|V$uy)u$sG*>2Q2I67F zW$VrMJRB}U9*9)Df-TVcJ2y2Ro_+4@sp`omPMv%TzDlivkFdMqvy2m$Sacn8{2`Re z9jR)Xxhj(dCTmDy=NWwn{qM2l^GGUtLrg&%mfIZrE$s+Q_xiL~4c`Tn9J6QaHJ?!XMm@JJM&R-OF z*}K!a&O61teUNv?riKpZ#%R&_LVmoI%YSlgBwrr8r&Jn+>cSSfmHm$GAbuukVZUwT z)>!_tzs>R;IT;l#dGO^XY8RvipK+DF{kB!S%N+Sc3Aab#VDK?Lg1&#&#y80Qw8z=P NdAC?9+Pt~;{{dZgIj8^t literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/config.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..367556a209824570b9c46852b74b4063726ed01c GIT binary patch literal 12864 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 d7XAr}JZl!xTEQ;oNuG literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..85403f28d8e27b96d5261e0337e870d413098dd2 GIT binary patch literal 6005 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/globals.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/globals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a01b50f5492a7fc6d0f22cbe8742cdcb804ec8d4 GIT binary patch literal 1575 zcmb_cPjA~c6qhX9a^$~p(zHq2l@YCau?;n5fQM}vrEO`D}J*2-kE$dIc*nS$Y z_|md$`M|cUR~E5|&8)=6wypIVt6>M;4yz{(+%Q<3H4_)Rwnd$vTH+CDkS5znJnX@4 zgSf1nba2P$EzrBTYxEt^d$?zGkM)xQ9vHpNc9S6G85c3dX9+4x!ZX3%ZdT3(a zCU*e4TVmwcpbox6?g4sSp{PRdl8*pI5VLk>jqbnI9FFXw9i}N)p^AAbU&7iO^HkB5 z`aTqT^@2wsI~9Djehc(!hsM_|loz1%g2!1lR;#CspNC9pYYmj{djC86b55mtk95wc zl#uA#conB$;Z_!#e}3TNB2MRs=Ss$eB0fW5ma#Z8g`ubn>U-W~5lf`j8SF5&MhOj5 zST90_);vd{QZ&gFB}j3UONwTB8tJ2jELQ8%E~S)E;;98iQ7!~c)pjZ$O*oRAEh$*X z@?#{aLV1S5bld8xAn!6(3%%jPKd7pFF!IqE)&3L_9_0z7D33AY0wr8f6sMpj2J|=G znI^Q1pjMlMiZ5uu>-T)VDcm4h29RcC<9?o=^E@R%0(^#ZDq7H*!ZkIhRpEdl;Hp?f zyE>uvE9|*&0o?rY0kTEes;hJTpG0fspa($cv&rNXRhfJQ$CNo!AE1e+NWt9bc>tQc zEwWGu=T>OJFLi^%C6A%gdLlBx&lyep&2C9%l_iLP(4#FvtAVSKH$_{MS{aKSL)n&V z;a+XE4Z*S;U!gxpqvOI0f?2L|L4!clv_Vr3W;!oy1<^TWy literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/helpers.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/helpers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c399574befd04078a9fa82a53cce86786ba4fda GIT binary patch literal 21571 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/logging.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/logging.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55d4b8b869e46d99b595e6cc06da7d2a9704acd6 GIT binary patch literal 2538 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/signals.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/signals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..725b2d61768a0cd396940c4b8a08367f8fd138cb GIT binary patch literal 805 zcmY+C&5GMF5P+pP>m<(KF7yZb203`kQs|*9r6s3A*~`+4FbE}{q$akkO7d>j*FvA8 zJ@%Dy?Vgokj%P@BJ10?Gf^;8FX8KgLi~b^9>;-Da}bi z8Kn*P@?H_JfD#D464rzkL0Raik2G*}hBR~(B8?mkkRnGzq_LwB(!^1OG<7sa znmL*v&C}^ESCl?w~82AP6}w0^dNO{sk# z_6hY|!r4MLPKxogb=lg-=4IQn=O}6^z(IyvaqAbF(-7$o7iC)I@RnkA^8&jGne@US>P7VQo6-NFaRh+? literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/templating.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/templating.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c5b2f2a67278e416b486fdc60b8e4c3425111fe GIT binary patch literal 7082 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 CDa()m literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/testing.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d44b9971cae4c0446f83e733b82d36827eac8195 GIT binary patch literal 9691 zcmb_i&2t>bb)T=D{lEeQK=50##*}1g%j8m&70cPslxYa0C{rKQr78!MEams!eCz_GQaNP7 z?d_TFe*OCO>-T=|HN)xYnu5=NJh|b1`--CcJ3UN(3_ScuQPfCL6-6jQ^_8C5R#mEN zzSh?H*JzjUtNUiJ+%9vQfqJD~;d;rh_NwhF*G<3Hn`%#Sz3kU})9q=lYyM386lhfZ z+1^}xj^9=NncjSRp6fOLbZ?=32K6aX_s{muwa;;V+CSgB(7vE5ZfX0X{1g;sFzQnK z61Sf6U+TTwepyxSDq>d5JyXP-dusbz+pj#;+pmau#}b#s8FBWR(f&4ioD=8KF(gc=!X40{7$b)r|Yic<=S4~#f!>7`cdEaVj8jNdn8$eUnR=d*c$M=Gb5Kr}0H;TZ;hu#w}pyxGoU2&s67^4YFcYG(>=@Q$MpHlju zM&C!pRobdh+L}+^`9c(sZFx5QXxpUQux189DogFu_guCGk z{5Y~UWY|N4TeI+S`VdW*rQEFXn^xbEPLCQ|*4mb9@#-e~S#fA#FE+f*fpm$G<)%FL zAWf#;oFvqD;;okT(aL>`YSy~z1)G*k1@4MtUDut+wXt0->&K|^nB6Tmn*01)SFPPGue-&w(PBCsnxfO8e$w@^s>fh3Y+Cm=Ea;N8iRa*|wGLUPj20tX!ik+$ z=i$oIou!qPrT1*`Yp*W8zx3e}q}b_1gLM)1953i}uAUsUy0r4sr4@VmHurS`VP({A zKYV!q-s0`Gdk>cFl?M;jI>#1UkZf72Idv;=dc-k_+XW%iGFp?993um9*->}P?YW@C zzcgw9@p(ZMyNQ}`?R1*fZ9fXf%Gc@eF%Duo#__~f#o@%532nSiEMPph<~k`iqm~sy<)qaQ zBadu@<6Dm09FXosIUf@=|8EE7*epA{AXv<^Q-63hL6n&e2mzMSY-s5}L`kQk(~ zi5|r=spRT^RKue+vX;ZZO{#^SB(?EgCkF9&REnFogT2H|Sx!vp#se87294~R6V|AX zdKq8LsYd^a%1DpQk%4bXE{xz|25PK~jQ;ef^i4 zRQs<8eZNA_!nmO9S4W0yj*QSgY z&`%vH_EcPds%%fAMc>p$=HII;il>aq|DgV@O1=%IbZU9{gGF{JtR>dvLavvsP+FJA zvb}8WdN5R%^X<6YY)?%bzohDiUB}-FqqseL@`xvDv%T=5<2BS<*RRVtNdCXb$-H}{ zzT22djP)?|6En4@iN5K^l6EOE(-WPTfg5AC#Pp#NUSFQ3#u9v$+)HX+L?_${x^7Zh z--G>^^V}Q_`YyD|w!OfMZM#uVjL7vjxRoi$Gw3JJQE{G%3shV}(XMXAao^^pRiL7_ z48u6lAsT3?+y4R%)VA64*!CC7(Y?jiqmN(_qDN5>?uti?tKa+njYo?EDczvEce~$z z)P%i#{OG>7{s@QFz1D|UhVPCZZIH*jPA&`1pxNJ(S26o_e51Ef)N7`ysrY_vex(`4 zmlbnXt*M4KqgJ#UzUQ@yYJ81W!_*ek8P(J*b$IT$?`!7EPxNqoyQ_h0{(%RDe^r#9 z&{;T(%1GH(w$*KD(uNAH(MW5cG3xN2R&#R)7XUJBt}KV`-nETT_MA9|*`vL|GE(g|Nep`Z2=A_8osxvh8!g|W8W-O~EvZpwoBMu@=ZM60)*N0qK3#L% zt6{J%FE1}QW>du?YnE!)0@YZ>NVutsg=}Da_uFmy^Nw^ri{L*ooF}8 zq}=2wZ9A#ib}tkIpXznn{%qj*SxecrMcB1%)-CxC1}4*)_I6$0N5fbMZ_?Z(2|0^` zxQnP#Q4AH@24&RL*`xV4xHVBEvr4Qy2l`027D=zDHCCcZ481zgg?gwuc!pMK%Sj~% zZ4D!tv-1c0F-{U3T2l3T{ZPifx1LmbZtRdFP0Cs81k>Z~J7dFgJV%I_i^vHWdL5@n zg0JTpE>LQW)*PjN1mlmeLvszG-&DkFj8dzj_N?A6xu$qs)W!5O1TalGG3xAW z#E??zU1FFbT2Usa7tICB=yqfD&uMg0KAJH86ua2uN%O@3*?V2!Q}_V_l-Mla3t&XO zfcK$=Gu!IquAyUL#eFc70<;t|O<}ot%#!-9v85=CNSC~9{?Sn(i_hri7AmmwWFR=C4cuKz|p$R=UpDI8lnlOH=;a!=rL}~fXuzKUIcbaeF@5Zp2tLF8F z)}C5f`tZTpl70KV_g31c-d|gLXnzFsVBfyGw7k}+$nRo$Hc81WZw=xYJJV3ur@-CK zpCU;tCo}o84PW2g;ZvN{CncL(_ri@!HfM!-;Mqo?70sZShhsI>imJht*1sAqOq{*K zXCA#CH}A4m$D#b$WcYiPL1|ikdQ8TITPpa5Wc`j%`33t`p#llkVpRbD0Zl5~8t|RI zt&e5DZ;X@!V`OZXw#`FT1q%JuEJ}U5d{7zb^!`xWFMW(1GO&qHbyW!}H{SexvOCnylEC8&Dv|y4?+X>t2w90l>=%TY`;^ z5x*gLW(yG_^ouMfKTJRpoPMxk=>(C}rPJ6XjDgdW9^G^jST}e=Z)12JeYLO zAz6#)}WK7 zK0w5^gePHt{k>u}SvVf2t4?hvNppF4YcULWJn)u|i-=Ltv=*fc6@+-wjY>D|3e*GB zasMB#Nr=BWyt10<0qr_@Md1lft&q}Ud?u~tk=l}EfrqtKH@=om+Bgl|meEV9l$~3W zGL&)&{n`t(9rlSuwij$ih)-Wd8Uj6PzgKMY@)H25!|{amP| zW1dAa>aU@K@Cd=u@8CLrry}%*6P2@M)M3z(+q{Y3i6QRrl>*NQcOBWuldcZ&!#$9b zcc{3FA~E6Bp-`DKOG=#OLGU(+PfBDO3en%Qv%UXk435b0P#j1&cX(lPg~$4KX)XDO zyep04wcSSrZV3Dzr~BU3%hdfAi^`d3U7 z(QU(7^*lU$MP1N_-#I3Z{DiRzPY%8Fg@z2&U<0_+70K*I==rGqMY^5AMg(ZHz1Sl_Ot%3H?Q=crzc4}9WV+^d9W+h5 z9?OWEz0Ol{g>x zc@j6OsrvCY^A3;gREMZ86ICSSGNY$;dnaM$7JB>}zR?d*nB{p`rFlf2^RPQJs)1kQ zYeO@>s+VTfx?U@pS{hiJe?VOa7*)-$3}ZMusjjq$Ld!rE+XJJAFCSXUCqU|oECXM1 zwo(vA$2;tSzC8R^mhTHD0!A-*jO-m@sAvuQ!}jMP=zO83>u1zlKxfK#rDC%G8=ctB z5O_ARp5d8EPK$m?#eLG{V*I($-sdNi2>VJ_Lpdk zXg1TFQBQ^mX%`qbR+4e}#kC>^``_9>0Odw)V*CmFa+!ELksKnMgFR#V?@_%Xc`<$J z%PW#p<7H7gBkjp4r5Q;|DgT&?78QSjA~|K-6PJv6sz|5yPpDwi&8LfWTLx4NsJKbR zSaKY1ar%hZ^6`yG5;et8E7LQGwCZZ*Mx~I8Qa@Vpu}_hUc^j|uTnuMo zPH{G+BC5#17}XkOTlmein8D5A_`YyHnaPzhz2+SLpQZ4~%2%`HkQeGux8yU2!3_ z>bh1736NGNW91r}vx}aIT;hq%r)_)=n~;7^5jG*6;EMpb8klcjkvx%GoCw}8oQipL zWgE$HaUMMLTb}X-!E+sECp`=5S!9}zi@1oIajk=euu4A%Gzvy(<43Soh*m3q!+Ga@ z_^XlrSe55ujW<;n#3C6yD^P?%na7|Alcit83E6%Xn$RTch@{(1tm8$RlC|GrjVY*X06AL}wuA@=!Y*IM zv4#Dnt!905pEwk$MH8VTt{W*h%2Vxmd_+;*#O*ByH&`(im|cGyyW!08X;}b;g*3;P z`M7PQ`*2DYMp<&s@lv#VxOQo5%unzGACkZxIv>AA476c}RgRD@0I zz4W@Bm?!F>mmMbx#OTw)<$)|BJ+x=h9_V(gO~kAHao~3B{_{S92};MM*AAT4%=V2Y z%1$bWaFa}@SA#8RN}h5&VGmZ^2>(5xlPzUD_cCYWpEFkEiBHqfBhW{h44 zi)~|%P8!$9HYSyuzSCP5&aKz!IFS=GmEn~Whba@^O}=A`ZZ-2U4YgfM4UP>_HA?9; zPiTfZ6%2aJbad|NxOEI;_+T?nY^sMChD1|}mn(A>Tr8bc&uU}0o?6gM=i$rPL;&7C z=a<;SXt)ZgNS>0t;5T|kYDFyg0)Ld=R1ja^>|l1$Y8G6>!OWDj()q6?z0Z9k!GgwX zbTzUuz=-1hV_Ln13guu2VcMdw|K{Y0EBDQuCOR1~|KRI&gy zlGA9w|LytY;gXI2m9hAfd&_q@2AS9um&VRg@h%mMRFJu4*-UurNsUZV@hwv3sEMMk eR48yR{@}CII({j0jnbe%ABv)=tvI$3H!*BEMHd2uwK!5}uSj;6 zjP3qIf&NB+iBARkQ1la86jf(eq@)-K1+8YzIWv29xC$zjqJht!*H55ZHjF=1viK}v z@||H2`MYTtuHh1Hj0q(~#U?kY1=fWv9$;qi+&EA3nz4Cd>`+I?IleS5(jqZXS#tAG zh6+Yi{4TF4tcD22LsMsWpq&0z){J3c&7gH;OIlM+xfLk81*IQa$Tt-4I%%gy+UG9j zr~{p+%2nM-^;>~Dtfop8-&>54!M^U&Fo)fns9tl6Zr&~ZV$v37>&gYauX|Y+8_*gN zXr=Yj%(~cw7VfDW;+H$c`PjMkw!t;cv{s?N}b-tW!W_vdre z-9A93q*z_`;hHfb^WEndMsK_L2oYVU_q^2=xw)4GZo$#VO5+xA)$f#kax4Ed&9}A7 z&s2uaACAnaJNmgs(m7+i4iC|L#y&zMJJm8yzM0Jvah0ptr*qT&+nF96&9vIx+q%cD zd1`Ez|5A5=_M<_?qGnU5z+ zEG$DuHxbChKJsLgSUdhrQuv;Q+KO`+fnZS}=^;zb>ol&Elo!-#hg?4DF%N4 zw46?6id&u^(UoitCx9;fDO2d;v0gDD^6LD~%TSG*ae4;_{Zj1WMxnss=Wvra9mY93 z=a4MzTrn?FA#Lmo(cg*MRz{hCwsv6{2zcfR8QtdYPPtofVn6i;5#2a_4V-rZKZ5J% zSOf!*G7wqcq_WE->|GB)+oZKFFyRJQekPz>T^NU)Mewc`bTv~v^Ef)6RnG8z9-K3t z;fZ}71e`Xqs_w!u6Wdju>t`oNPhrSnJ|Dn+#PooV1rG4mF=%5?h(H`L-{lJqDknjV z#?vAHW{6F7h1K%ULFen<8D4GKlYVgJ_By9ue)Xi+iG{$IeS@#6*M0;3o8FOk-jiMg zk3u%MWFwHhA>R4R$J1-w4)G;^GY;IC!?y(c%3pCQ8;+Sb%S3%_%OvVkBvsQP4l)0> zCtDSTmPwtM|Jf6}pyD#AD&4>Kq*^MPHf9ZCPLQ>?2(DJ0GSW@|&Yw2XbS&Esj5HvGJ4%ot zfIb|hNToZS$Q|1+`2wBJ*qyxi19bXb@Y;t?9{ScNzqr3WfFLEseJVHr?+$x=d%JtT z-9>upRMW!sudgo4KVPt{e^O`qa?$z7vRKwfLs){v)(-13Mr}K`yN+;#8@oGpw}vrC z)M9U^-mROqhjydeV3wTOv_$=H?2vVvpID+HX6{>J=FslWqSq9&=*`O6L#Nvk_Nvux zeMb_sSw0&iNvZ=KrAfB(9V-Ssy+4SOO?n*;m6D0}gTVmZx{`N?GSlrw?rch(yMr{t zb4vyyucrgUCHI7krIxuf80x&HRS?R&HVAaM71E;9SGDynMy1td!s^<$paN{#?z+N} zHQ`=?8oHjSq3vCFYvJ7>Tn~BgDm5EE6RA$3=+Z9U8z(gBwyN*dTXgCqRa^GmwWDUoi;hHP{}|` z9`H?>NEL+zkBb{YCI#QcG9A7g#POIR$2(aHx))6VWWeL#&+f2)*9P9rQSDEfw6b36gz&>&EAW zEP;xGjaX)#rs=Or=s~36Qjes}dc2=1>{v)0L@~CxIfSN4+D?ausgM^p;xxRow8RJd zSR*O;7=0OSe=6fRUAPTy?Ip7Wy`n2hBJE2ke}AlL{sI3uh%-51L3Bd)`Ei>pWHRnA z@+8=i$GFlACG}7xygzT&UgUoux_fWUPx!*CJAn}XP{qC)#&Y3^Wb>D{Na#yfXx@kO zi^jMU+3iWAQ!=7Dt&T51P=9y_kH;I52#?~DD4Z_zjZ=6CtbjtmR`@eL9g&W+3!bTB$IG|kq;BN zYG&5oPlr5_g@759Az^ldQ5QGkbR&ql2y{SN@AXLLUaw=OtsK0qJImymw*&PhnrR$M za}vMIv|8sQzLF+#J+GHGIe2x7d?QWcisJQwN_TM@{9vfl9Uy7wmq>W<=F}Xr1g(Sf zNe69xJ#S8oa`WKy6e+P^&(EIJO70ad{p@^ScW%gR0MM20YML z;-R6fL+fkSW(WVc3EKyu9zr`uL1;s61-ntII(&?hGUGc#@}UwPjq>Pl8T2H?DNk9z zcY`>hZXs5OUj@GGj&X(eRk~w5Xbd^#gyPKc05%)I5U^p8@jG&VFI8xcVXd$iQ6m7o zyprnAb_TH|#FOH>QmJ~%a+gf|)Kafwo6kO3URt}ANtLZ-NxCQ2mRH~Z<>j?y6Uf5- ztAoK>2iUp0_Ib3imPJ}#90cK=U{hvmefYzjO9t^egZ=#Uak%*c>@yn=uXgYXL0RWG zMeY(-Z)XpF3F zOPvxk53C35fzwAKAiVpnM@}*~vL0HI^^kqbzG07SP}qGY>cv~kV(QX}J#>5iE z6?-E~5$S0q6KuvXQAJG(n$?UK<^Tm8boggQRG#9T$?5q8>YqHqM}e)_R|c1v$WGg; zGi%xGre&#hJYDu z7+0WKbmd-gWYmvv4%9h%yn;uFySnJ?(0O@-&dX2GcxZ1=or`-+v&Z&`Z97kxU=dCe zot9PWsl8%gqwVHR+O2Q=MA7NXXJwKNmGrayBvjyQwQV(zKlK{59rZ(Mb3AgFrW!s9 zDZZs>{Rnr~!oy`Yv!C0{dw$+IxNw_rqs$ySSCBIy)%mbP^N(zYpu5`6d33b(m_4+% z?W5wWALA87A$iq1^e}R=Le5udfIx8~l|s*8*m<_{)Gf%4YPH=^FVmE>c;pS=Czta5 zyy^QpsQ_U6zIvNp)qNisB6_EZ`V1cJTJD5#rrxB1iE?JDKv!yd^3G_|Xv;{L*Gt9R z1c!{{;k|s$o~zHyEC+t%>2ex74_(3I%*(Ncaa-+AZ6f2vf%u4%(YM}@XX?I@QhqbLrCx<~{@`ICon4j?+A zx|NZJn{bcTe5=-Kv|3HuuAgR#-W~A;^o=jzk7bK^j!Pv|D9t{w0Qa7#-*2I0YKa-q zL>W|jfGJ%MKz%B2eqqvn(p2zooRe#1X@lTiCQFmlvrO|+lzkM)1?s>FHWfQVE=q^; zV}jDJ0*c0qJnD1G#G-L*<^c{lO2i5)K%!B10G7s>R+dx9e+9CDUhk9ZH$hzrG|qQ# znj)1`B|6dXA#%EiBbDthVp;O}vf{ChdhCVF`Mdn`5s;@PN~sXxBZZ`Tfyyg{mWf!? zGNEYrpEcNID}<3n`8Cnp7)hsiSK<`)*fEI9T}teaWXgn{bkEZ9`Xd^YDQ`1jBTAT@ z3ZGgSavyt_sb6d7(7H#Nl#2{%?w+G-BS+x7#i66-NA_cHs zz*6m+dKXIKNVVjfeGK@&ItC;vZn3fZm|}#|J1OXY!3e} z{@wq$vj=ZZyuEW`Q$=8>=r_I`G$<1Oj?A-$hDPw#Y}}#go$F&i~Q+I4=pk-|(cR#&;^_r?FDneA+-1n}nv1h{T9= z8LdaSvj!dw#HYCnXU`}arC8#_bMRe-(f~@i6qzPxI=6DWui<#6>dp!k7~RaE^gBQ% uCGj1ECQx`Y+@=;cV$kAw<4Tcbd`K>kQ8aH^4ZBtN5|RM-`CRSX!G8fT$=^Hx literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/__pycache__/wrappers.cpython-310.pyc b/.venv/Lib/site-packages/flask/__pycache__/wrappers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7984d6f02c7eae6c5df55bbf6cc085a2072a3bf7 GIT binary patch literal 5193 zcmai2TW{RP6(+gdt5(uViXA&m9L5RYs^cPVkn z^>8S87fKMs1_Jc4k9}#Jw*dVu{Q-RKLlN{36h?aa&hVm(<%R~wGqb}pXTEdhJLf2x zoo#7&{_*ezzk6QO{!WAAkBPyrG)<5Hgbve~9%v)o)^+L|fnitheIS0w(2*6+0mRmr~1uce$=r$y2dNJ3*r}$)(RF!OZJkkeW0-! z)_$z9Hg7zt*maC&*&N1myoGU-8JpVj{CA}7vYyVkVHinQ`cW9KW88YrWgGlK!efb1 z{ixg6;PDuX_;-5trMVkNAxZEOA$TYqcRa@MoD+`&UphNM!pFkL{MeO4{9tY*0rzOz z;|~FaN00xEmTR`oG~2ij!0ZY)?J6^Pja6=H%(UyQihfP?8?26gL-m`iiGJ&*##`)? zI;#0dw`VYVm37#{V;Z&9Xpt?c(JV$5JIBte(Hwj2E3L1y3+&?Kwmr`-tI^Bs6^uGx zX{Kf`0I=5uY3lwBhu<1+SvwPp@xGe`((*&={lJa)x|X%UM|`xy zMQq6-Z&`RouJndj&qFqj0FdQ|%-Z+)f#r%pG6Ixwx20CzhNRd!7`l=c$5t}7+}K+2 zAUa;@eco4FeP=Z03C>?pC&5?hi+F_%h- z6<118?v@=Z-_uc_^k^^05v7n^{WE|f*+&OB;9_selR@`Dz?gS>GJzjrVjLv2S0At{ot2Py%ss#Fdsc)cT{ZQzD!aGB zNjgLB?2IA?FI}I`kh5Bc);boZjYI^Fz{K=L=6muFu@qM=_0^}vk|x>Df&JoXXYHZK z$8@2J9~VTFNIx7ny!a)p2`&>6K5dcxvu!-OSH(kp1MezbjYV{%ChAh#)tP=#+XRQe zB`eckZg7`fi^5=%`A-f@uXp#>@0`_p>sxE8}p$5ttQT4`sqijE8F*D7->5WqXV|Ry7~4yH?~*R<@YAH#^deo zJ`eY|@Ay00u`l_xvFq)*10HWHKfPYscsxlLNA5!h+eqS#fQJJ)dWtV_S6| z(u5we`7Cfs8wC(z2}5P@tRWP|MKtf?RrYDM8f2eNVV~m56aGuSTfwXR_s8fE{-5cG z@LyPCkr{{jz9tqA^{;hiJkeQ2c{SO_bazXR9r&^20!oK;mfXAZaATDL<}`|DnTG%= z6eUh2yNq2SNvK;wSc<$#puwsHpK^-lTlUDJrI<4;%OX$`Z5ncq$FVDX+*u`A*-D*{ zbSyOhiN~ctPjFWP26Bk5g{UxcCvdNQtcPzwCSYPpXTeL%l=mE+4d(9yOVAB%mT{kQ zfmH7bq8qpZ**R?q0>&o-!_*6yQuC*LB5jtc-o=ubn4{M27<1$s3x#i#Yo0a(*pis@ z(`Wpoi@wDmJx*ADeV?GgTG6r4`I%jWuY zX@s=MC&#)@^mmQ9(iOz^NDMC_jJw{@;h`rdWA1PvBH^eHDBLbL(rTQ5H`941h+O87 z07nT>;i}5`PBKUvBY(u{`?T5z1IKn-%@27%iG_HL_R8Iv`iO2#C(B3|C+v7pn6K9ROe3@e(NIjU86%3F^W9Ac&Jac zgM#`dI#a}T0{c*ZqJIMDOh7()MF(5z+O#Dr;+(APn&RA-n12MIzcd(r`&>WJ4}jkK za#dW0l=M8Z7nQ;gMwD!1fk!HHXMhX+;P&Dlc!_o zw;ks};s*IIb;n_m2fNkj>oywrhI6cv!A}&{#2hvA^m_yOBOF0a#EUdXOqX4+SE)x< z7j*t~Hg^h-2SMQ&3L*uT!ifq2I%aI4X=$e3rpIj845O_Zb-Z(U7u)(==lr}X8$2vL z@l>;s9+Lx{ta_MXo2~qpHVl@Fr`is-(f1kK3qcFhX52gK#+`NS6CoxK&1u zS&>#0CMvB#y!$@|$|sT7i@|VvoajyQkH|~CLP}pmqoWKP2{%z7>H|vrRTu(MezM6y2Gytj^eXgrRPuK*wwF9`bM>Rv4^Sd@9)ES6=) z?<8uHqCf^uA(+w1NWZM5v-vg*a64C*8-Bl@W2|ZiRCE z>0i#Sj#lVMD|v}@@8jER&gN}K$Ro{gDCg;ULK0m8k%?zB^C`X6H9{@@;ipum# zY=N}$s*_~f^H~vA>Htoph$g7s%Se6x6na^9eu}q$j^*Fr&8nw*OK()B7dCP?KCN28 z$3Mdd%WZL$wz@`5mzwL;yiLuU)RgpU|Hw^bGH13{id}THm0xq=k5k z8bz0>O#TN( C^orI1 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/app.py b/.venv/Lib/site-packages/flask/app.py new file mode 100644 index 0000000..d710cb9 --- /dev/null +++ b/.venv/Lib/site-packages/flask/app.py @@ -0,0 +1,1478 @@ +from __future__ import annotations + +import os +import sys +import typing as t +import weakref +from collections.abc import Iterator as _abc_Iterator +from datetime import timedelta +from inspect import iscoroutinefunction +from itertools import chain +from types import TracebackType +from urllib.parse import quote as _url_quote + +import click +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.routing import BuildError +from werkzeug.routing import MapAdapter +from werkzeug.routing import RequestRedirect +from werkzeug.routing import RoutingException +from werkzeug.routing import Rule +from werkzeug.serving import is_running_from_reloader +from werkzeug.wrappers import Response as BaseResponse + +from . import cli +from . import typing as ft +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import g +from .globals import request +from .globals import request_ctx +from .globals import session +from .helpers import get_debug_flag +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import send_from_directory +from .sansio.app import App +from .sansio.scaffold import _sentinel +from .sessions import SecureCookieSessionInterface +from .sessions import SessionInterface +from .signals import appcontext_tearing_down +from .signals import got_request_exception +from .signals import request_finished +from .signals import request_started +from .signals import request_tearing_down +from .templating import Environment +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: # pragma: no cover + from .testing import FlaskClient + from .testing import FlaskCliRunner + +T_shell_context_processor = t.TypeVar( + "T_shell_context_processor", bound=ft.ShellContextProcessorCallable +) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) + + +def _make_timedelta(value: timedelta | int | None) -> timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(App): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + default_config = ImmutableDict( + { + "DEBUG": None, + "TESTING": False, + "PROPAGATE_EXCEPTIONS": None, + "SECRET_KEY": None, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "SERVER_NAME": None, + "APPLICATION_ROOT": "/", + "SESSION_COOKIE_NAME": "session", + "SESSION_COOKIE_DOMAIN": None, + "SESSION_COOKIE_PATH": None, + "SESSION_COOKIE_HTTPONLY": True, + "SESSION_COOKIE_SECURE": False, + "SESSION_COOKIE_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "SEND_FILE_MAX_AGE_DEFAULT": None, + "TRAP_BAD_REQUEST_ERRORS": None, + "TRAP_HTTP_EXCEPTIONS": False, + "EXPLAIN_TEMPLATE_LOADING": False, + "PREFERRED_URL_SCHEME": "http", + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + } + ) + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class = Response + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface: SessionInterface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_url_path=static_url_path, + static_folder=static_folder, + static_host=static_host, + host_matching=host_matching, + subdomain_matching=subdomain_matching, + template_folder=template_folder, + instance_path=instance_path, + instance_relative_config=instance_relative_config, + root_path=root_path, + ) + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert ( + bool(static_host) == host_matching + ), "Invalid static_host/host_matching combination" + # Use a weakref to avoid creating a reference cycle between the app + # and the view function (see #3761). + self_ref = weakref.ref(self) + self.add_url_rule( + f"{self.static_url_path}/", + endpoint="static", + host=static_host, + view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950 + ) + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for + reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to + :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is + supported, valid values are "r" (or "rt") and "rb". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) + + def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Opens a resource from the application's instance folder + (:attr:`instance_path`). Otherwise works like + :meth:`open_resource`. Instance resources can also be opened for + writing. + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + return open(os.path.join(self.instance_path, resource), mode) + + def create_jinja_environment(self) -> Environment: + """Create the Jinja environment based on :attr:`jinja_options` + and the various Jinja-related methods of the app. Changing + :attr:`jinja_options` after this will have no effect. Also adds + Flask-related globals and filters to the environment. + + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + + .. versionadded:: 0.5 + """ + options = dict(self.jinja_options) + + if "autoescape" not in options: + options["autoescape"] = self.select_jinja_autoescape + + if "auto_reload" not in options: + auto_reload = self.config["TEMPLATES_AUTO_RELOAD"] + + if auto_reload is None: + auto_reload = self.debug + + options["auto_reload"] = auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=self.url_for, + get_flashed_messages=get_flashed_messages, + config=self.config, + # request, session and g are normally added with the + # context processor for efficiency reasons but for imported + # templates we also want the proxies in there. + request=request, + session=session, + g=g, + ) + rv.policies["json.dumps_function"] = self.json.dumps + return rv + + def create_url_adapter(self, request: Request | None) -> MapAdapter | None: + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + if not self.subdomain_matching: + subdomain = self.url_map.default_subdomain or None + else: + subdomain = None + + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config["SERVER_NAME"], + subdomain=subdomain, + ) + # We need at the very least the server name to be set for this + # to work. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + def raise_routing_exception(self, request: Request) -> t.NoReturn: + """Intercept routing exceptions and possibly do something else. + + In debug mode, intercept a routing redirect and replace it with + an error if the body will be discarded. + + With modern Werkzeug this shouldn't occur, since it now uses a + 308 status which tells the browser to resend the method and + body. + + .. versionchanged:: 2.1 + Don't intercept 307 and 308 redirects. + + :meta private: + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.routing_exception.code in {307, 308} + or request.method in {"GET", "HEAD", "OPTIONS"} + ): + raise request.routing_exception # type: ignore + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def update_template_context(self, context: dict) -> None: + """Update the template context with some commonly used variables. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overridden if a context processor + decides to return a value with the same key. + + :param context: the context as a dictionary that is updated in place + to add extra variables. + """ + names: t.Iterable[str | None] = (None,) + + # A template may be rendered outside a request context. + if request: + names = chain(names, reversed(request.blueprints)) + + # The values passed to render_template take precedence. Keep a + # copy to re-apply after all context functions. + orig_ctx = context.copy() + + for name in names: + if name in self.template_context_processors: + for func in self.template_context_processors[name]: + context.update(self.ensure_sync(func)()) + + context.update(orig_ctx) + + def make_shell_context(self) -> dict: + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {"app": self, "g": g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + def run( + self, + host: str | None = None, + port: int | None = None, + debug: bool | None = None, + load_dotenv: bool = True, + **options: t.Any, + ) -> None: + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :doc:`/deploying/index` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Ignore this call so that it doesn't start another server if + # the 'flask run' command is used. + if os.environ.get("FLASK_RUN_FROM_CLI") == "true": + if not is_running_from_reloader(): + click.secho( + " * Ignoring a call to 'app.run()' that would block" + " the current 'flask' CLI command.\n" + " Only call 'app.run()' in an 'if __name__ ==" + ' "__main__"\' guard.', + fg="red", + ) + + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, env var overrides existing value + if "FLASK_DEBUG" in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + server_name = self.config.get("SERVER_NAME") + sn_host = sn_port = None + + if server_name: + sn_host, _, sn_port = server_name.partition(":") + + if not host: + if sn_host: + host = sn_host + else: + host = "127.0.0.1" + + if port or port == 0: + port = int(port) + elif sn_port: + port = int(sn_port) + else: + port = 5000 + + options.setdefault("use_reloader", self.debug) + options.setdefault("use_debugger", self.debug) + options.setdefault("threaded", True) + + cli.show_server_banner(self.debug, self.name) + + from werkzeug.serving import run_simple + + try: + run_simple(t.cast(str, host), port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient: + """Creates a test client for this application. For information + about unit testing head over to :doc:`/testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from .testing import FlaskClient as cls + return cls( # type: ignore + self, self.response_class, use_cookies=use_cookies, **kwargs + ) + + def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner: + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from .testing import FlaskCliRunner as cls + + return cls(self, **kwargs) # type: ignore + + def handle_http_exception( + self, e: HTTPException + ) -> HTTPException | ft.ResponseReturnValue: + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionchanged:: 1.0.3 + ``RoutingException``, used internally for actions such as + slash redirects during routing, is not passed to error + handlers. + + .. versionchanged:: 1.0 + Exceptions are looked up by code *and* by MRO, so + ``HTTPException`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + return e + + handler = self._find_error_handler(e, request.blueprints) + if handler is None: + return e + return self.ensure_sync(handler)(e) + + def handle_user_exception( + self, e: Exception + ) -> HTTPException | ft.ResponseReturnValue: + """This method is called whenever an exception occurs that + should be handled. A special case is :class:`~werkzeug + .exceptions.HTTPException` which is forwarded to the + :meth:`handle_http_exception` method. This function will either + return a response value or reraise the exception with the same + traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the + bad key in debug mode rather than a generic bad request + message. + + .. versionadded:: 0.7 + """ + if isinstance(e, BadRequestKeyError) and ( + self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"] + ): + e.show_exception = True + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e, request.blueprints) + + if handler is None: + raise + + return self.ensure_sync(handler)(e) + + def handle_exception(self, e: Exception) -> Response: + """Handle an exception that did not have an error handler + associated with it, or that was raised from an error handler. + This always causes a 500 ``InternalServerError``. + + Always sends the :data:`got_request_exception` signal. + + If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug + mode, the error will be re-raised so that the debugger can + display it. Otherwise, the original exception is logged, and + an :exc:`~werkzeug.exceptions.InternalServerError` is returned. + + If an error handler is registered for ``InternalServerError`` or + ``500``, it will be used. For consistency, the handler will + always receive the ``InternalServerError``. The original + unhandled exception is available as ``e.original_exception``. + + .. versionchanged:: 1.1.0 + Always passes the ``InternalServerError`` instance to the + handler, setting ``original_exception`` to the unhandled + error. + + .. versionchanged:: 1.1.0 + ``after_request`` functions and other finalization is done + even for the default 500 response when there is no handler. + + .. versionadded:: 0.3 + """ + exc_info = sys.exc_info() + got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e) + propagate = self.config["PROPAGATE_EXCEPTIONS"] + + if propagate is None: + propagate = self.testing or self.debug + + if propagate: + # Re-raise if called with an active exception, otherwise + # raise the passed in exception. + if exc_info[1] is e: + raise + + raise e + + self.log_exception(exc_info) + server_error: InternalServerError | ft.ResponseReturnValue + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error, request.blueprints) + + if handler is not None: + server_error = self.ensure_sync(handler)(server_error) + + return self.finalize_request(server_error, from_error_handler=True) + + def log_exception( + self, + exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]), + ) -> None: + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error( + f"Exception on {request.path} [{request.method}]", exc_info=exc_info + ) + + def dispatch_request(self) -> ft.ResponseReturnValue: + """Does the request dispatching. Matches the URL and returns the + return value of the view or error handler. This does not have to + be a response object. In order to convert the return value to a + proper response object, call :func:`make_response`. + + .. versionchanged:: 0.7 + This no longer does the exception handling, this code was + moved to the new :meth:`full_dispatch_request`. + """ + req = request_ctx.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule: Rule = req.url_rule # type: ignore[assignment] + # if we provide automatic options for this URL and the + # request came with the OPTIONS method, reply automatically + if ( + getattr(rule, "provide_automatic_options", False) + and req.method == "OPTIONS" + ): + return self.make_default_options_response() + # otherwise dispatch to the handler for that endpoint + view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment] + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) + + def full_dispatch_request(self) -> Response: + """Dispatches the request and on top of that performs request + pre and postprocessing as well as HTTP exception catching and + error handling. + + .. versionadded:: 0.7 + """ + self._got_first_request = True + + try: + request_started.send(self, _async_wrapper=self.ensure_sync) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request( + self, + rv: ft.ResponseReturnValue | HTTPException, + from_error_handler: bool = False, + ) -> Response: + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send( + self, _async_wrapper=self.ensure_sync, response=response + ) + except Exception: + if not from_error_handler: + raise + self.logger.exception( + "Request finalizing failed with an error while handling an error" + ) + return response + + def make_default_options_response(self) -> Response: + """This method is called to create the default ``OPTIONS`` response. + This can be changed through subclassing to change the default + behavior of ``OPTIONS`` responses. + + .. versionadded:: 0.7 + """ + adapter = request_ctx.url_adapter + methods = adapter.allowed_methods() # type: ignore[union-attr] + rv = self.response_class() + rv.allow.update(methods) + return rv + + def ensure_sync(self, func: t.Callable) -> t.Callable: + """Ensure that the function is synchronous for WSGI workers. + Plain ``def`` functions are returned as-is. ``async def`` + functions are wrapped to run and wait for the response. + + Override this method to change how the app runs async views. + + .. versionadded:: 2.0 + """ + if iscoroutinefunction(func): + return self.async_to_sync(func) + + return func + + def async_to_sync( + self, func: t.Callable[..., t.Coroutine] + ) -> t.Callable[..., t.Any]: + """Return a sync function that will run the coroutine function. + + .. code-block:: python + + result = app.async_to_sync(func)(*args, **kwargs) + + Override this method to change how the app converts async code + to be synchronously callable. + + .. versionadded:: 2.0 + """ + try: + from asgiref.sync import async_to_sync as asgiref_async_to_sync + except ImportError: + raise RuntimeError( + "Install Flask with the 'async' extra in order to use async views." + ) from None + + return asgiref_async_to_sync(func) + + def url_for( + self, + /, + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, + ) -> str: + """Generate a URL to the given endpoint with the given values. + + This is called by :func:`flask.url_for`, and can be called + directly as well. + + An *endpoint* is the name of a URL rule, usually added with + :meth:`@app.route() `, and usually the same name as the + view function. A route defined in a :class:`~flask.Blueprint` + will prepend the blueprint's name separated by a ``.`` to the + endpoint. + + In some cases, such as email messages, you want URLs to include + the scheme and domain, like ``https://example.com/hello``. When + not in an active request, URLs will be external by default, but + this requires setting :data:`SERVER_NAME` so Flask knows what + domain to use. :data:`APPLICATION_ROOT` and + :data:`PREFERRED_URL_SCHEME` should also be configured as + needed. This config is only used when not in an active request. + + Functions can be decorated with :meth:`url_defaults` to modify + keyword arguments before the URL is built. + + If building fails for some reason, such as an unknown endpoint + or incorrect values, the app's :meth:`handle_url_build_error` + method is called. If that returns a string, that is returned, + otherwise a :exc:`~werkzeug.routing.BuildError` is raised. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it + is external. + :param _external: If given, prefer the URL to be internal + (False) or require it to be external (True). External URLs + include the scheme and domain. When not in an active + request, URLs are external by default. + :param values: Values to use for the variable parts of the URL + rule. Unknown keys are appended as query string arguments, + like ``?a=b&c=d``. + + .. versionadded:: 2.2 + Moved from ``flask.url_for``, which calls this method. + """ + req_ctx = _cv_request.get(None) + + if req_ctx is not None: + url_adapter = req_ctx.url_adapter + blueprint_name = req_ctx.request.blueprint + + # If the endpoint starts with "." and the request matches a + # blueprint, the endpoint is relative to the blueprint. + if endpoint[:1] == ".": + if blueprint_name is not None: + endpoint = f"{blueprint_name}{endpoint}" + else: + endpoint = endpoint[1:] + + # When in a request, generate a URL without scheme and + # domain by default, unless a scheme is given. + if _external is None: + _external = _scheme is not None + else: + app_ctx = _cv_app.get(None) + + # If called by helpers.url_for, an app context is active, + # use its url_adapter. Otherwise, app.url_for was called + # directly, build an adapter. + if app_ctx is not None: + url_adapter = app_ctx.url_adapter + else: + url_adapter = self.create_url_adapter(None) + + if url_adapter is None: + raise RuntimeError( + "Unable to build URLs outside an active request" + " without 'SERVER_NAME' configured. Also configure" + " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as" + " needed." + ) + + # When outside a request, generate a URL with scheme and + # domain by default. + if _external is None: + _external = True + + # It is an error to set _scheme when _external=False, in order + # to avoid accidental insecure URLs. + if _scheme is not None and not _external: + raise ValueError("When specifying '_scheme', '_external' must be True.") + + self.inject_url_defaults(endpoint, values) + + try: + rv = url_adapter.build( # type: ignore[union-attr] + endpoint, + values, + method=_method, + url_scheme=_scheme, + force_external=_external, + ) + except BuildError as error: + values.update( + _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external + ) + return self.handle_url_build_error(error, endpoint, values) + + if _anchor is not None: + _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@") + rv = f"{rv}#{_anchor}" + + return rv + + def make_response(self, rv: ft.ResponseReturnValue) -> Response: + """Convert the return value from a view function to an instance of + :attr:`response_class`. + + :param rv: the return value from the view function. The view function + must return a response. Returning ``None``, or the view ending + without returning, is not allowed. The following types are allowed + for ``view_rv``: + + ``str`` + A response object is created with the string encoded to UTF-8 + as the body. + + ``bytes`` + A response object is created with the bytes as the body. + + ``dict`` + A dictionary that will be jsonify'd before being returned. + + ``list`` + A list that will be jsonify'd before being returned. + + ``generator`` or ``iterator`` + A generator that returns ``str`` or ``bytes`` to be + streamed as the response. + + ``tuple`` + Either ``(body, status, headers)``, ``(body, status)``, or + ``(body, headers)``, where ``body`` is any of the other types + allowed here, ``status`` is a string or an integer, and + ``headers`` is a dictionary or a list of ``(key, value)`` + tuples. If ``body`` is a :attr:`response_class` instance, + ``status`` overwrites the exiting value and ``headers`` are + extended. + + :attr:`response_class` + The object is returned unchanged. + + other :class:`~werkzeug.wrappers.Response` class + The object is coerced to :attr:`response_class`. + + :func:`callable` + The function is called as a WSGI application. The result is + used to create a response object. + + .. versionchanged:: 2.2 + A generator will be converted to a streaming response. + A list will be converted to a JSON response. + + .. versionchanged:: 1.1 + A dict will be converted to a JSON response. + + .. versionchanged:: 0.9 + Previously a tuple was interpreted as the arguments for the + response object. + """ + + status = headers = None + + # unpack tuple returns + if isinstance(rv, tuple): + len_rv = len(rv) + + # a 3-tuple is unpacked directly + if len_rv == 3: + rv, status, headers = rv # type: ignore[misc] + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv + else: + rv, status = rv # type: ignore[assignment,misc] + # other sized tuples are not allowed + else: + raise TypeError( + "The view function did not return a valid response tuple." + " The tuple must have the form (body, status, headers)," + " (body, status), or (body, headers)." + ) + + # the body must not be None + if rv is None: + raise TypeError( + f"The view function for {request.endpoint!r} did not" + " return a valid response. The function either returned" + " None or ended without a return statement." + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, _abc_Iterator): + # let the response class set the status and headers instead of + # waiting to do it manually, so that the class can handle any + # special logic + rv = self.response_class( + rv, + status=status, + headers=headers, # type: ignore[arg-type] + ) + status = headers = None + elif isinstance(rv, (dict, list)): + rv = self.json.response(rv) + elif isinstance(rv, BaseResponse) or callable(rv): + # evaluate a WSGI callable, or coerce a different response + # class to the correct type + try: + rv = self.response_class.force_type( + rv, request.environ # type: ignore[arg-type] + ) + except TypeError as e: + raise TypeError( + f"{e}\nThe view function did not return a valid" + " response. The return type must be a string," + " dict, list, tuple with headers or status," + " Response instance, or WSGI callable, but it" + f" was a {type(rv).__name__}." + ).with_traceback(sys.exc_info()[2]) from None + else: + raise TypeError( + "The view function did not return a valid" + " response. The return type must be a string," + " dict, list, tuple with headers or status," + " Response instance, or WSGI callable, but it was a" + f" {type(rv).__name__}." + ) + + rv = t.cast(Response, rv) + # prefer the status if it was provided + if status is not None: + if isinstance(status, (str, bytes, bytearray)): + rv.status = status + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.update(headers) # type: ignore[arg-type] + + return rv + + def preprocess_request(self) -> ft.ResponseReturnValue | None: + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + names = (None, *reversed(request.blueprints)) + + for name in names: + if name in self.url_value_preprocessors: + for url_func in self.url_value_preprocessors[name]: + url_func(request.endpoint, request.view_args) + + for name in names: + if name in self.before_request_funcs: + for before_func in self.before_request_funcs[name]: + rv = self.ensure_sync(before_func)() + + if rv is not None: + return rv + + return None + + def process_response(self, response: Response) -> Response: + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = request_ctx._get_current_object() # type: ignore[attr-defined] + + for func in ctx._after_request_functions: + response = self.ensure_sync(func)(response) + + for name in chain(request.blueprints, (None,)): + if name in self.after_request_funcs: + for func in reversed(self.after_request_funcs[name]): + response = self.ensure_sync(func)(response) + + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + + return response + + def do_teardown_request( + self, exc: BaseException | None = _sentinel # type: ignore + ) -> None: + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for name in chain(request.blueprints, (None,)): + if name in self.teardown_request_funcs: + for func in reversed(self.teardown_request_funcs[name]): + self.ensure_sync(func)(exc) + + request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def do_teardown_appcontext( + self, exc: BaseException | None = _sentinel # type: ignore + ) -> None: + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for func in reversed(self.teardown_appcontext_funcs): + self.ensure_sync(func)(exc) + + appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def app_context(self) -> AppContext: + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ: dict) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with app.test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from .testing import EnvironBuilder + + builder = EnvironBuilder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any: + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error: BaseException | None = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: # noqa: B001 + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if "werkzeug.debug.preserve_context" in environ: + environ["werkzeug.debug.preserve_context"](_cv_app.get()) + environ["werkzeug.debug.preserve_context"](_cv_request.get()) + + if error is not None and self.should_ignore_error(error): + error = None + + ctx.pop(error) + + def __call__(self, environ: dict, start_response: t.Callable) -> t.Any: + """The WSGI server calls the Flask application object as the + WSGI application. This calls :meth:`wsgi_app`, which can be + wrapped to apply middleware. + """ + return self.wsgi_app(environ, start_response) diff --git a/.venv/Lib/site-packages/flask/blueprints.py b/.venv/Lib/site-packages/flask/blueprints.py new file mode 100644 index 0000000..3a37a2c --- /dev/null +++ b/.venv/Lib/site-packages/flask/blueprints.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +from .globals import current_app +from .helpers import send_from_directory +from .sansio.blueprints import Blueprint as SansioBlueprint +from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for + reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to + :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is + supported, valid values are "r" (or "rt") and "rb". + + Note this is a duplicate of the same method in the Flask + class. + + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + return open(os.path.join(self.root_path, resource), mode) diff --git a/.venv/Lib/site-packages/flask/cli.py b/.venv/Lib/site-packages/flask/cli.py new file mode 100644 index 0000000..dda266b --- /dev/null +++ b/.venv/Lib/site-packages/flask/cli.py @@ -0,0 +1,1068 @@ +from __future__ import annotations + +import ast +import importlib.metadata +import inspect +import os +import platform +import re +import sys +import traceback +import typing as t +from functools import update_wrapper +from operator import itemgetter + +import click +from click.core import ParameterSource +from werkzeug import run_simple +from werkzeug.serving import is_running_from_reloader +from werkzeug.utils import import_string + +from .globals import current_app +from .helpers import get_debug_flag +from .helpers import get_load_dotenv + +if t.TYPE_CHECKING: + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module): + """Given a module instance this tries to find the best possible + application in the module or raises an exception. + """ + from . import Flask + + # Search for the most common names first. + for attr_name in ("app", "application"): + app = getattr(module, attr_name, None) + + if isinstance(app, Flask): + return app + + # Otherwise find the only object that is a Flask instance. + matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] + + if len(matches) == 1: + return matches[0] + elif len(matches) > 1: + raise NoAppException( + "Detected multiple Flask applications in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify the correct one." + ) + + # Search for app factory functions. + for attr_name in ("create_app", "make_app"): + app_factory = getattr(module, attr_name, None) + + if inspect.isfunction(app_factory): + try: + app = app_factory() + + if isinstance(app, Flask): + return app + except TypeError as e: + if not _called_with_wrong_args(app_factory): + raise + + raise NoAppException( + f"Detected factory '{attr_name}' in module '{module.__name__}'," + " but could not call it without arguments. Use" + f" '{module.__name__}:{attr_name}(args)'" + " to specify arguments." + ) from e + + raise NoAppException( + "Failed to find Flask application or factory in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify one." + ) + + +def _called_with_wrong_args(f): + """Check whether calling a function raised a ``TypeError`` because + the call failed or because something in the factory raised the + error. + + :param f: The function that was called. + :return: ``True`` if the call failed. + """ + tb = sys.exc_info()[2] + + try: + while tb is not None: + if tb.tb_frame.f_code is f.__code__: + # In the function, it was called successfully. + return False + + tb = tb.tb_next + + # Didn't reach the function. + return True + finally: + # Delete tb to break a circular reference. + # https://docs.python.org/2/library/sys.html#sys.exc_info + del tb + + +def find_app_by_string(module, app_name): + """Check if the given string is a variable name or a function. Call + a function to get the app instance, or return the variable directly. + """ + from . import Flask + + # Parse app_name as a single expression to determine if it's a valid + # attribute name or function call. + try: + expr = ast.parse(app_name.strip(), mode="eval").body + except SyntaxError: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) from None + + if isinstance(expr, ast.Name): + name = expr.id + args = [] + kwargs = {} + elif isinstance(expr, ast.Call): + # Ensure the function name is an attribute name only. + if not isinstance(expr.func, ast.Name): + raise NoAppException( + f"Function reference must be a simple name: {app_name!r}." + ) + + name = expr.func.id + + # Parse the positional and keyword arguments as literals. + try: + args = [ast.literal_eval(arg) for arg in expr.args] + kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr.keywords} + except ValueError: + # literal_eval gives cryptic error messages, show a generic + # message with the full expression instead. + raise NoAppException( + f"Failed to parse arguments as literal values: {app_name!r}." + ) from None + else: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) + + try: + attr = getattr(module, name) + except AttributeError as e: + raise NoAppException( + f"Failed to find attribute {name!r} in {module.__name__!r}." + ) from e + + # If the attribute is a function, call it with any args and kwargs + # to get the real application. + if inspect.isfunction(attr): + try: + app = attr(*args, **kwargs) + except TypeError as e: + if not _called_with_wrong_args(attr): + raise + + raise NoAppException( + f"The factory {app_name!r} in module" + f" {module.__name__!r} could not be called with the" + " specified arguments." + ) from e + else: + app = attr + + if isinstance(app, Flask): + return app + + raise NoAppException( + "A valid Flask application was not obtained from" + f" '{module.__name__}:{app_name}'." + ) + + +def prepare_import(path): + """Given a filename this will try to calculate the python path, add it + to the search path and return the actual module name that is expected. + """ + path = os.path.realpath(path) + + fname, ext = os.path.splitext(path) + if ext == ".py": + path = fname + + if os.path.basename(path) == "__init__": + path = os.path.dirname(path) + + module_name = [] + + # move up until outside package structure (no __init__.py) + while True: + path, name = os.path.split(path) + module_name.append(name) + + if not os.path.exists(os.path.join(path, "__init__.py")): + break + + if sys.path[0] != path: + sys.path.insert(0, path) + + return ".".join(module_name[::-1]) + + +def locate_app(module_name, app_name, raise_if_not_found=True): + try: + __import__(module_name) + except ImportError: + # Reraise the ImportError if it occurred within the imported module. + # Determine this by checking whether the trace has a depth > 1. + if sys.exc_info()[2].tb_next: + raise NoAppException( + f"While importing {module_name!r}, an ImportError was" + f" raised:\n\n{traceback.format_exc()}" + ) from None + elif raise_if_not_found: + raise NoAppException(f"Could not import {module_name!r}.") from None + else: + return + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(module) + else: + return find_app_by_string(module, app_name) + + +def get_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + flask_version = importlib.metadata.version("flask") + werkzeug_version = importlib.metadata.version("werkzeug") + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {flask_version}\n" + f"Werkzeug {werkzeug_version}", + color=ctx.color, + ) + ctx.exit() + + +version_option = click.Option( + ["--version"], + help="Show the Flask version.", + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True, +) + + +class ScriptInfo: + """Helper object to deal with Flask applications. This is usually not + necessary to interface with as it's used internally in the dispatching + to click. In future versions of Flask this object will most likely play + a bigger role. Typically it's created automatically by the + :class:`FlaskGroup` but you can also manually create it and pass it + onwards as click object. + """ + + def __init__( + self, + app_import_path: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: bool = True, + ) -> None: + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path + #: Optionally a function that is passed the script info to create + #: the instance of the application. + self.create_app = create_app + #: A dictionary with arbitrary data that can be associated with + #: this script info. + self.data: dict[t.Any, t.Any] = {} + self.set_debug_flag = set_debug_flag + self._loaded_app: Flask | None = None + + def load_app(self) -> Flask: + """Loads the Flask app (if not yet loaded) and returns it. Calling + this multiple times will just result in the already loaded app to + be returned. + """ + if self._loaded_app is not None: + return self._loaded_app + + if self.create_app is not None: + app = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, maxsplit=1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(import_name, None, raise_if_not_found=False) + + if app: + break + + if not app: + raise NoAppException( + "Could not locate a Flask application. Use the" + " 'flask --app' option, 'FLASK_APP' environment" + " variable, or a 'wsgi.py' or 'app.py' file in the" + " current directory." + ) + + if self.set_debug_flag: + # Update the app's debug flag through the descriptor so that + # other values repopulate as well. + app.debug = get_debug_flag() + + self._loaded_app = app + return app + + +pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) + + +def with_appcontext(f): + """Wraps a callback so that it's guaranteed to be executed with the + script's application context. + + Custom commands (and their options) registered under ``app.cli`` or + ``blueprint.cli`` will always have an app context available, this + decorator is not required in that case. + + .. versionchanged:: 2.2 + The app context is active for subcommands as well as the + decorated callback. The app context is always available to + ``app.cli`` command and parameter callbacks. + """ + + @click.pass_context + def decorator(__ctx, *args, **kwargs): + if not current_app: + app = __ctx.ensure_object(ScriptInfo).load_app() + __ctx.with_resource(app.app_context()) + + return __ctx.invoke(f, *args, **kwargs) + + return update_wrapper(decorator, f) + + +class AppGroup(click.Group): + """This works similar to a regular click :class:`~click.Group` but it + changes the behavior of the :meth:`command` decorator so that it + automatically wraps the functions in :func:`with_appcontext`. + + Not to be confused with :class:`FlaskGroup`. + """ + + def command(self, *args, **kwargs): + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` + unless it's disabled by passing ``with_appcontext=False``. + """ + wrap_for_ctx = kwargs.pop("with_appcontext", True) + + def decorator(f): + if wrap_for_ctx: + f = with_appcontext(f) + return click.Group.command(self, *args, **kwargs)(f) + + return decorator + + def group(self, *args, **kwargs): + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it defaults the group class to + :class:`AppGroup`. + """ + kwargs.setdefault("cls", AppGroup) + return click.Group.group(self, *args, **kwargs) + + +def _set_app(ctx: click.Context, param: click.Option, value: str | None) -> str | None: + if value is None: + return None + + info = ctx.ensure_object(ScriptInfo) + info.app_import_path = value + return value + + +# This option is eager so the app will be available if --help is given. +# --help is also eager, so --app must be before it in the param list. +# no_args_is_help bypasses eager processing, so this option must be +# processed manually in that case to ensure FLASK_APP gets picked up. +_app_option = click.Option( + ["-A", "--app"], + metavar="IMPORT", + help=( + "The Flask application or factory function to load, in the form 'module:name'." + " Module can be a dotted import or file path. Name is not required if it is" + " 'app', 'application', 'create_app', or 'make_app', and can be 'name(args)' to" + " pass arguments." + ), + is_eager=True, + expose_value=False, + callback=_set_app, +) + + +def _set_debug(ctx: click.Context, param: click.Option, value: bool) -> bool | None: + # If the flag isn't provided, it will default to False. Don't use + # that, let debug be set by env in that case. + source = ctx.get_parameter_source(param.name) # type: ignore[arg-type] + + if source is not None and source in ( + ParameterSource.DEFAULT, + ParameterSource.DEFAULT_MAP, + ): + return None + + # Set with env var instead of ScriptInfo.load so that it can be + # accessed early during a factory function. + os.environ["FLASK_DEBUG"] = "1" if value else "0" + return value + + +_debug_option = click.Option( + ["--debug/--no-debug"], + help="Set debug mode.", + expose_value=False, + callback=_set_debug, +) + + +def _env_file_callback( + ctx: click.Context, param: click.Option, value: str | None +) -> str | None: + if value is None: + return None + + import importlib + + try: + importlib.import_module("dotenv") + except ImportError: + raise click.BadParameter( + "python-dotenv must be installed to load an env file.", + ctx=ctx, + param=param, + ) from None + + # Don't check FLASK_SKIP_DOTENV, that only disables automatically + # loading .env and .flaskenv files. + load_dotenv(value) + return value + + +# This option is eager so env vars are loaded as early as possible to be +# used by other options. +_env_file_option = click.Option( + ["-e", "--env-file"], + type=click.Path(exists=True, dir_okay=False), + help="Load environment variables from this file. python-dotenv must be installed.", + is_eager=True, + expose_value=False, + callback=_env_file_callback, +) + + +class FlaskGroup(AppGroup): + """Special subclass of the :class:`AppGroup` group that supports + loading more commands from the configured Flask app. Normally a + developer does not have to interface with this class but there are + some very advanced use cases for which it makes sense to create an + instance of this. see :ref:`custom-scripts`. + + :param add_default_commands: if this is True then the default run and + shell commands will be added. + :param add_version_option: adds the ``--version`` option. + :param create_app: an optional callback that is passed the script info and + returns the loaded app. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param set_debug_flag: Set the app's debug flag. + + .. versionchanged:: 2.2 + Added the ``-A/--app``, ``--debug/--no-debug``, ``-e/--env-file`` options. + + .. versionchanged:: 2.2 + An app context is pushed when running ``app.cli`` commands, so + ``@with_appcontext`` is no longer required for those commands. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment variables + from :file:`.env` and :file:`.flaskenv` files. + """ + + def __init__( + self, + add_default_commands: bool = True, + create_app: t.Callable[..., Flask] | None = None, + add_version_option: bool = True, + load_dotenv: bool = True, + set_debug_flag: bool = True, + **extra: t.Any, + ) -> None: + params = list(extra.pop("params", None) or ()) + # Processing is done with option callbacks instead of a group + # callback. This allows users to make a custom group callback + # without losing the behavior. --env-file must come first so + # that it is eagerly evaluated before --app. + params.extend((_env_file_option, _app_option, _debug_option)) + + if add_version_option: + params.append(version_option) + + if "context_settings" not in extra: + extra["context_settings"] = {} + + extra["context_settings"].setdefault("auto_envvar_prefix", "FLASK") + + super().__init__(params=params, **extra) + + self.create_app = create_app + self.load_dotenv = load_dotenv + self.set_debug_flag = set_debug_flag + + if add_default_commands: + self.add_command(run_command) + self.add_command(shell_command) + self.add_command(routes_command) + + self._loaded_plugin_commands = False + + def _load_plugin_commands(self): + if self._loaded_plugin_commands: + return + + if sys.version_info >= (3, 10): + from importlib import metadata + else: + # Use a backport on Python < 3.10. We technically have + # importlib.metadata on 3.8+, but the API changed in 3.10, + # so use the backport for consistency. + import importlib_metadata as metadata + + for ep in metadata.entry_points(group="flask.commands"): + self.add_command(ep.load(), ep.name) + + self._loaded_plugin_commands = True + + def get_command(self, ctx, name): + self._load_plugin_commands() + # Look up built-in and plugin commands, which should be + # available even if the app fails to load. + rv = super().get_command(ctx, name) + + if rv is not None: + return rv + + info = ctx.ensure_object(ScriptInfo) + + # Look up commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + app = info.load_app() + except NoAppException as e: + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + return None + + # Push an app context for the loaded app unless it is already + # active somehow. This makes the context available to parameter + # and command callbacks without needing @with_appcontext. + if not current_app or current_app._get_current_object() is not app: + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + def list_commands(self, ctx): + self._load_plugin_commands() + # Start with the built-in and plugin commands. + rv = set(super().list_commands(ctx)) + info = ctx.ensure_object(ScriptInfo) + + # Add commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + rv.update(info.load_app().cli.list_commands(ctx)) + except NoAppException as e: + # When an app couldn't be loaded, show the error message + # without the traceback. + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + except Exception: + # When any other errors occurred during loading, show the + # full traceback. + click.secho(f"{traceback.format_exc()}\n", err=True, fg="red") + + return sorted(rv) + + def make_context( + self, + info_name: str | None, + args: list[str], + parent: click.Context | None = None, + **extra: t.Any, + ) -> click.Context: + # Set a flag to tell app.run to become a no-op. If app.run was + # not in a __name__ == __main__ guard, it would start the server + # when importing, blocking whatever command is being called. + os.environ["FLASK_RUN_FROM_CLI"] = "true" + + # Attempt to load .env and .flask env files. The --env-file + # option can cause another file to be loaded. + if get_load_dotenv(self.load_dotenv): + load_dotenv() + + if "obj" not in extra and "obj" not in self.context_settings: + extra["obj"] = ScriptInfo( + create_app=self.create_app, set_debug_flag=self.set_debug_flag + ) + + return super().make_context(info_name, args, parent=parent, **extra) + + def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: + if not args and self.no_args_is_help: + # Attempt to load --env-file and --app early in case they + # were given as env vars. Otherwise no_args_is_help will not + # see commands from app.cli. + _env_file_option.handle_parse_result(ctx, {}, []) + _app_option.handle_parse_result(ctx, {}, []) + + return super().parse_args(ctx, args) + + +def _path_is_ancestor(path, other): + """Take ``other`` and remove the length of ``path`` from it. Then join it + to ``path``. If it is the original value, ``path`` is an ancestor of + ``other``.""" + return os.path.join(path, other[len(path) :].lstrip(os.sep)) == other + + +def load_dotenv(path: str | os.PathLike | None = None) -> bool: + """Load "dotenv" files in order of precedence to set environment variables. + + If an env var is already set it is not overwritten, so earlier files in the + list are preferred over later files. + + This is a no-op if `python-dotenv`_ is not installed. + + .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme + + :param path: Load the file at this location instead of searching. + :return: ``True`` if a file was loaded. + + .. versionchanged:: 2.0 + The current directory is not changed to the location of the + loaded file. + + .. versionchanged:: 2.0 + When loading the env files, set the default encoding to UTF-8. + + .. versionchanged:: 1.1.0 + Returns ``False`` when python-dotenv is not installed, or when + the given path isn't a file. + + .. versionadded:: 1.0 + """ + try: + import dotenv + except ImportError: + if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"): + click.secho( + " * Tip: There are .env or .flaskenv files present." + ' Do "pip install python-dotenv" to use them.', + fg="yellow", + err=True, + ) + + return False + + # Always return after attempting to load a given path, don't load + # the default files. + if path is not None: + if os.path.isfile(path): + return dotenv.load_dotenv(path, encoding="utf-8") + + return False + + loaded = False + + for name in (".env", ".flaskenv"): + path = dotenv.find_dotenv(name, usecwd=True) + + if not path: + continue + + dotenv.load_dotenv(path, encoding="utf-8") + loaded = True + + return loaded # True if at least one file was located and loaded. + + +def show_server_banner(debug, app_import_path): + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if is_running_from_reloader(): + return + + if app_import_path is not None: + click.echo(f" * Serving Flask app '{app_import_path}'") + + if debug is not None: + click.echo(f" * Debug mode: {'on' if debug else 'off'}") + + +class CertParamType(click.ParamType): + """Click option type for the ``--cert`` option. Allows either an + existing file, the string ``'adhoc'``, or an import for a + :class:`~ssl.SSLContext` object. + """ + + name = "path" + + def __init__(self): + self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) + + def convert(self, value, param, ctx): + try: + import ssl + except ImportError: + raise click.BadParameter( + 'Using "--cert" requires Python to be compiled with SSL support.', + ctx, + param, + ) from None + + try: + return self.path_type(value, param, ctx) + except click.BadParameter: + value = click.STRING(value, param, ctx).lower() + + if value == "adhoc": + try: + import cryptography # noqa: F401 + except ImportError: + raise click.BadParameter( + "Using ad-hoc certificates requires the cryptography library.", + ctx, + param, + ) from None + + return value + + obj = import_string(value, silent=True) + + if isinstance(obj, ssl.SSLContext): + return obj + + raise + + +def _validate_key(ctx, param, value): + """The ``--key`` option must be specified when ``--cert`` is a file. + Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. + """ + cert = ctx.params.get("cert") + is_adhoc = cert == "adhoc" + + try: + import ssl + except ImportError: + is_context = False + else: + is_context = isinstance(cert, ssl.SSLContext) + + if value is not None: + if is_adhoc: + raise click.BadParameter( + 'When "--cert" is "adhoc", "--key" is not used.', ctx, param + ) + + if is_context: + raise click.BadParameter( + 'When "--cert" is an SSLContext object, "--key is not used.', ctx, param + ) + + if not cert: + raise click.BadParameter('"--cert" must also be specified.', ctx, param) + + ctx.params["cert"] = cert, value + + else: + if cert and not (is_adhoc or is_context): + raise click.BadParameter('Required when using "--cert".', ctx, param) + + return value + + +class SeparatedPathType(click.Path): + """Click option type that accepts a list of values separated by the + OS's path separator (``:``, ``;`` on Windows). Each value is + validated as a :class:`click.Path` type. + """ + + def convert(self, value, param, ctx): + items = self.split_envvar_value(value) + super_convert = super().convert + return [super_convert(item, param, ctx) for item in items] + + +@click.command("run", short_help="Run a development server.") +@click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.") +@click.option("--port", "-p", default=5000, help="The port to bind to.") +@click.option( + "--cert", + type=CertParamType(), + help="Specify a certificate file to use HTTPS.", + is_eager=True, +) +@click.option( + "--key", + type=click.Path(exists=True, dir_okay=False, resolve_path=True), + callback=_validate_key, + expose_value=False, + help="The key file to use when specifying a certificate.", +) +@click.option( + "--reload/--no-reload", + default=None, + help="Enable or disable the reloader. By default the reloader " + "is active if debug is enabled.", +) +@click.option( + "--debugger/--no-debugger", + default=None, + help="Enable or disable the debugger. By default the debugger " + "is active if debug is enabled.", +) +@click.option( + "--with-threads/--without-threads", + default=True, + help="Enable or disable multithreading.", +) +@click.option( + "--extra-files", + default=None, + type=SeparatedPathType(), + help=( + "Extra files that trigger a reload on change. Multiple paths" + f" are separated by {os.path.pathsep!r}." + ), +) +@click.option( + "--exclude-patterns", + default=None, + type=SeparatedPathType(), + help=( + "Files matching these fnmatch patterns will not trigger a reload" + " on change. Multiple patterns are separated by" + f" {os.path.pathsep!r}." + ), +) +@pass_script_info +def run_command( + info, + host, + port, + reload, + debugger, + with_threads, + cert, + extra_files, + exclude_patterns, +): + """Run a local development server. + + This server is for development purposes only. It does not provide + the stability, security, or performance of production WSGI servers. + + The reloader and debugger are enabled by default with the '--debug' + option. + """ + try: + app = info.load_app() + except Exception as e: + if is_running_from_reloader(): + # When reloading, print out the error immediately, but raise + # it later so the debugger or server can handle it. + traceback.print_exc() + err = e + + def app(environ, start_response): + raise err from None + + else: + # When not reloading, raise the error immediately so the + # command fails. + raise e from None + + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + show_server_banner(debug, info.app_import_path) + + run_simple( + host, + port, + app, + use_reloader=reload, + use_debugger=debugger, + threaded=with_threads, + ssl_context=cert, + extra_files=extra_files, + exclude_patterns=exclude_patterns, + ) + + +run_command.params.insert(0, _debug_option) + + +@click.command("shell", short_help="Run a shell in the app context.") +@with_appcontext +def shell_command() -> None: + """Run an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to its configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + + banner = ( + f"Python {sys.version} on {sys.platform}\n" + f"App: {current_app.import_name}\n" + f"Instance: {current_app.instance_path}" + ) + ctx: dict = {} + + # Support the regular Python interpreter startup script if someone + # is using it. + startup = os.environ.get("PYTHONSTARTUP") + if startup and os.path.isfile(startup): + with open(startup) as f: + eval(compile(f.read(), startup, "exec"), ctx) + + ctx.update(current_app.make_shell_context()) + + # Site, customize, or startup script can set a hook to call when + # entering interactive mode. The default one sets up readline with + # tab and history completion. + interactive_hook = getattr(sys, "__interactivehook__", None) + + if interactive_hook is not None: + try: + import readline + from rlcompleter import Completer + except ImportError: + pass + else: + # rlcompleter uses __main__.__dict__ by default, which is + # flask.__main__. Use the shell context instead. + readline.set_completer(Completer(ctx).complete) + + interactive_hook() + + code.interact(banner=banner, local=ctx) + + +@click.command("routes", short_help="Show the routes for the app.") +@click.option( + "--sort", + "-s", + type=click.Choice(("endpoint", "methods", "domain", "rule", "match")), + default="endpoint", + help=( + "Method to sort routes by. 'match' is the order that Flask will match routes" + " when dispatching a request." + ), +) +@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.") +@with_appcontext +def routes_command(sort: str, all_methods: bool) -> None: + """Show all registered routes with endpoints and methods.""" + rules = list(current_app.url_map.iter_rules()) + + if not rules: + click.echo("No routes were registered.") + return + + ignored_methods = set() if all_methods else {"HEAD", "OPTIONS"} + host_matching = current_app.url_map.host_matching + has_domain = any(rule.host if host_matching else rule.subdomain for rule in rules) + rows = [] + + for rule in rules: + row = [ + rule.endpoint, + ", ".join(sorted((rule.methods or set()) - ignored_methods)), + ] + + if has_domain: + row.append((rule.host if host_matching else rule.subdomain) or "") + + row.append(rule.rule) + rows.append(row) + + headers = ["Endpoint", "Methods"] + sorts = ["endpoint", "methods"] + + if has_domain: + headers.append("Host" if host_matching else "Subdomain") + sorts.append("domain") + + headers.append("Rule") + sorts.append("rule") + + try: + rows.sort(key=itemgetter(sorts.index(sort))) + except ValueError: + pass + + rows.insert(0, headers) + widths = [max(len(row[i]) for row in rows) for i in range(len(headers))] + rows.insert(1, ["-" * w for w in widths]) + template = " ".join(f"{{{i}:<{w}}}" for i, w in enumerate(widths)) + + for row in rows: + click.echo(template.format(*row)) + + +cli = FlaskGroup( + name="flask", + help="""\ +A general utility script for Flask applications. + +An application to load must be given with the '--app' option, +'FLASK_APP' environment variable, or with a 'wsgi.py' or 'app.py' file +in the current directory. +""", +) + + +def main() -> None: + cli.main() + + +if __name__ == "__main__": + main() diff --git a/.venv/Lib/site-packages/flask/config.py b/.venv/Lib/site-packages/flask/config.py new file mode 100644 index 0000000..5f921b4 --- /dev/null +++ b/.venv/Lib/site-packages/flask/config.py @@ -0,0 +1,347 @@ +from __future__ import annotations + +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + + +class ConfigAttribute: + """Makes an attribute forward to the config""" + + def __init__(self, name: str, get_converter: t.Callable | None = None) -> None: + self.__name__ = name + self.get_converter = get_converter + + def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any: + if obj is None: + return self + rv = obj.config[self.__name__] + if self.get_converter is not None: + rv = self.get_converter(rv) + return rv + + def __set__(self, obj: t.Any, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__( + self, root_path: str | os.PathLike, defaults: dict | None = None + ) -> None: + super().__init__(defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name: str, silent: bool = False) -> bool: + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError( + f"The environment variable {variable_name!r} is not set" + " and as such configuration could not be loaded. Set" + " this variable and make it point to a configuration" + " file" + ) + return self.from_pyfile(rv, silent=silent) + + def from_prefixed_env( + self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + ) -> bool: + """Load any environment variables that start with ``FLASK_``, + dropping the prefix from the env key for the config key. Values + are passed through a loading function to attempt to convert them + to more specific types than strings. + + Keys are loaded in :func:`sorted` order. + + The default loading function attempts to parse values as any + valid JSON type, including dicts and lists. + + Specific items in nested dicts can be set by separating the + keys with double underscores (``__``). If an intermediate key + doesn't exist, it will be initialized to an empty dict. + + :param prefix: Load env vars that start with this prefix, + separated with an underscore (``_``). + :param loads: Pass each string value to this function and use + the returned value as the config value. If any error is + raised it is ignored and the value remains a string. The + default is :func:`json.loads`. + + .. versionadded:: 2.1 + """ + prefix = f"{prefix}_" + len_prefix = len(prefix) + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + # Change to key.removeprefix(prefix) on Python >= 3.9. + key = key[len_prefix:] + + if "__" not in key: + # A non-nested key, set directly. + self[key] = value + continue + + # Traverse nested dictionaries with keys separated by "__". + current = self + *parts, tail = key.split("__") + + for part in parts: + # If an intermediate dict does not exist, create it. + if part not in current: + current[part] = {} + + current = current[part] + + current[tail] = value + + return True + + def from_pyfile(self, filename: str | os.PathLike, silent: bool = False) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: object | str) -> None: + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, str): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_file( + self, + filename: str | os.PathLike, + load: t.Callable[[t.IO[t.Any]], t.Mapping], + silent: bool = False, + text: bool = True, + ) -> bool: + """Update the values in the config from a file that is loaded + using the ``load`` parameter. The loaded data is passed to the + :meth:`from_mapping` method. + + .. code-block:: python + + import json + app.config.from_file("config.json", load=json.load) + + import tomllib + app.config.from_file("config.toml", load=tomllib.load, text=False) + + :param filename: The path to the data file. This can be an + absolute path or relative to the config root path. + :param load: A callable that takes a file handle and returns a + mapping of loaded data from the file. + :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` + implements a ``read`` method. + :param silent: Ignore the file if it doesn't exist. + :param text: Open the file in text or binary mode. + :return: ``True`` if the file was loaded successfully. + + .. versionchanged:: 2.3 + The ``text`` parameter was added. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename, "r" if text else "rb") as f: + obj = load(f) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + + return self.from_mapping(obj) + + def from_mapping( + self, mapping: t.Mapping[str, t.Any] | None = None, **kwargs: t.Any + ) -> bool: + """Updates the config like :meth:`update` ignoring items with + non-upper keys. + + :return: Always returns ``True``. + + .. versionadded:: 0.11 + """ + mappings: dict[str, t.Any] = {} + if mapping is not None: + mappings.update(mapping) + mappings.update(kwargs) + for key, value in mappings.items(): + if key.isupper(): + self[key] = value + return True + + def get_namespace( + self, namespace: str, lowercase: bool = True, trim_namespace: bool = True + ) -> dict[str, t.Any]: + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in self.items(): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace) :] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self) -> str: + return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/.venv/Lib/site-packages/flask/ctx.py b/.venv/Lib/site-packages/flask/ctx.py new file mode 100644 index 0000000..b37e4e0 --- /dev/null +++ b/.venv/Lib/site-packages/flask/ctx.py @@ -0,0 +1,440 @@ +from __future__ import annotations + +import contextvars +import sys +import typing as t +from functools import update_wrapper +from types import TracebackType + +from werkzeug.exceptions import HTTPException + +from . import typing as ft +from .globals import _cv_app +from .globals import _cv_request +from .signals import appcontext_popped +from .signals import appcontext_pushed + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sessions import SessionMixin + from .wrappers import Request + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals: + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + # Define attr methods to let mypy know this is a namespace object + # that has arbitrary attributes. + + def __getattr__(self, name: str) -> t.Any: + try: + return self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def __setattr__(self, name: str, value: t.Any) -> None: + self.__dict__[name] = value + + def __delattr__(self, name: str) -> None: + try: + del self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def get(self, name: str, default: t.Any | None = None) -> t.Any: + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name: str, default: t.Any = _sentinel) -> t.Any: + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raising a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name: str, default: t.Any = None) -> t.Any: + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item: str) -> bool: + return item in self.__dict__ + + def __iter__(self) -> t.Iterator[str]: + return iter(self.__dict__) + + def __repr__(self) -> str: + ctx = _cv_app.get(None) + if ctx is not None: + return f"" + return object.__repr__(self) + + +def after_this_request(f: ft.AfterRequestCallable) -> ft.AfterRequestCallable: + """Executes a function after this request. This is useful to modify + response objects. The function is passed the response object and has + to return the same or a new one. + + Example:: + + @app.route('/') + def index(): + @after_this_request + def add_header(response): + response.headers['X-Foo'] = 'Parachute' + return response + return 'Hello World!' + + This is more useful if a function other than the view function wants to + modify a response. For instance think of a decorator that wants to add + some headers without converting the return value into a response object. + + .. versionadded:: 0.9 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'after_this_request' can only be used when a request" + " context is active, such as in a view function." + ) + + ctx._after_request_functions.append(f) + return f + + +def copy_current_request_context(f: t.Callable) -> t.Callable: + """A helper function that decorates a function to retain the current + request context. This is useful when working with greenlets. The moment + the function is decorated a copy of the request context is created and + then pushed when the function is called. The current session is also + included in the copied request context. + + Example:: + + import gevent + from flask import copy_current_request_context + + @app.route('/') + def index(): + @copy_current_request_context + def do_some_work(): + # do some work here, it can access flask.request or + # flask.session like you would otherwise in the view function. + ... + gevent.spawn(do_some_work) + return 'Regular response' + + .. versionadded:: 0.10 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'copy_current_request_context' can only be used when a" + " request context is active, such as in a view function." + ) + + ctx = ctx.copy() + + def wrapper(*args, **kwargs): + with ctx: + return ctx.app.ensure_sync(f)(*args, **kwargs) + + return update_wrapper(wrapper, f) + + +def has_request_context() -> bool: + """If you have code that wants to test if a request context is there or + not this function can be used. For instance, you may want to take advantage + of request information if the request object is available, but fail + silently if it is unavailable. + + :: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and has_request_context(): + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + Alternatively you can also just test any of the context bound objects + (such as :class:`request` or :class:`g`) for truthness:: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and request: + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + .. versionadded:: 0.7 + """ + return _cv_request.get(None) is not None + + +def has_app_context() -> bool: + """Works like :func:`has_request_context` but for the application + context. You can also just do a boolean check on the + :data:`current_app` object instead. + + .. versionadded:: 0.9 + """ + return _cv_app.get(None) is not None + + +class AppContext: + """The app context contains application-specific information. An app + context is created and pushed at the beginning of each request if + one is not already active. An app context is also pushed when + running CLI commands. + """ + + def __init__(self, app: Flask) -> None: + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g: _AppCtxGlobals = app.app_ctx_globals_class() + self._cv_tokens: list[contextvars.Token] = [] + + def push(self) -> None: + """Binds the app context to the current context.""" + self._cv_tokens.append(_cv_app.set(self)) + appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync) + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the app context.""" + try: + if len(self._cv_tokens) == 1: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + ctx = _cv_app.get() + _cv_app.reset(self._cv_tokens.pop()) + + if ctx is not self: + raise AssertionError( + f"Popped wrong app context. ({ctx!r} instead of {self!r})" + ) + + appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync) + + def __enter__(self) -> AppContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + +class RequestContext: + """The request context contains per-request information. The Flask + app creates and pushes it at the beginning of the request, then pops + it at the end of the request. It will create the URL adapter and + request object for the WSGI environment provided. + + Do not attempt to use this class directly, instead use + :meth:`~flask.Flask.test_request_context` and + :meth:`~flask.Flask.request_context` to create this object. + + When the request context is popped, it will evaluate all the + functions registered on the application for teardown execution + (:meth:`~flask.Flask.teardown_request`). + + The request context is automatically popped at the end of the + request. When using the interactive debugger, the context will be + restored so ``request`` is still accessible. Similarly, the test + client can preserve the context after the request ends. However, + teardown functions may already have closed some resources such as + database connections. + """ + + def __init__( + self, + app: Flask, + environ: dict, + request: Request | None = None, + session: SessionMixin | None = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + request.json_module = app.json + self.request: Request = request + self.url_adapter = None + try: + self.url_adapter = app.create_url_adapter(self.request) + except HTTPException as e: + self.request.routing_exception = e + self.flashes: list[tuple[str, str]] | None = None + self.session: SessionMixin | None = session + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions: list[ft.AfterRequestCallable] = [] + + self._cv_tokens: list[tuple[contextvars.Token, AppContext | None]] = [] + + def copy(self) -> RequestContext: + """Creates a copy of this request context with the same request object. + This can be used to move a request context to a different greenlet. + Because the actual request object is the same this cannot be used to + move a request context to a different thread unless access to the + request object is locked. + + .. versionadded:: 0.10 + + .. versionchanged:: 1.1 + The current session object is used instead of reloading the original + data. This prevents `flask.session` pointing to an out-of-date object. + """ + return self.__class__( + self.app, + environ=self.request.environ, + request=self.request, + session=self.session, + ) + + def match_request(self) -> None: + """Can be overridden by a subclass to hook into the matching + of the request. + """ + try: + result = self.url_adapter.match(return_rule=True) # type: ignore + self.request.url_rule, self.request.view_args = result # type: ignore + except HTTPException as e: + self.request.routing_exception = e + + def push(self) -> None: + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _cv_app.get(None) + + if app_ctx is None or app_ctx.app is not self.app: + app_ctx = self.app.app_context() + app_ctx.push() + else: + app_ctx = None + + self._cv_tokens.append((_cv_request.set(self), app_ctx)) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session(self.app, self.request) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + # Match the request URL after loading the session, so that the + # session is available in custom URL converters. + if self.url_adapter is not None: + self.match_request() + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + clear_request = len(self._cv_tokens) == 1 + + try: + if clear_request: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_request(exc) + + request_close = getattr(self.request, "close", None) + if request_close is not None: + request_close() + finally: + ctx = _cv_request.get() + token, app_ctx = self._cv_tokens.pop() + _cv_request.reset(token) + + # get rid of circular dependencies at the end of the request + # so that we don't require the GC to be active. + if clear_request: + ctx.request.environ["werkzeug.request"] = None + + if app_ctx is not None: + app_ctx.pop(exc) + + if ctx is not self: + raise AssertionError( + f"Popped wrong request context. ({ctx!r} instead of {self!r})" + ) + + def __enter__(self) -> RequestContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__} {self.request.url!r}" + f" [{self.request.method}] of {self.app.name}>" + ) diff --git a/.venv/Lib/site-packages/flask/debughelpers.py b/.venv/Lib/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..e836004 --- /dev/null +++ b/.venv/Lib/site-packages/flask/debughelpers.py @@ -0,0 +1,160 @@ +from __future__ import annotations + +import typing as t + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + + +class UnexpectedUnicodeError(AssertionError, UnicodeError): + """Raised in places where we want some better error reporting for + unexpected unicode or binary data. + """ + + +class DebugFilesKeyError(KeyError, AssertionError): + """Raised from request.files during debugging. The idea is that it can + provide a better error message than just a generic KeyError/BadRequest. + """ + + def __init__(self, request, key): + form_matches = request.form.getlist(key) + buf = [ + f"You tried to access the file {key!r} in the request.files" + " dictionary but it does not exist. The mimetype for the" + f" request is {request.mimetype!r} instead of" + " 'multipart/form-data' which means that no file contents" + " were transmitted. To fix this error you should provide" + ' enctype="multipart/form-data" in your form.' + ] + if form_matches: + names = ", ".join(repr(x) for x in form_matches) + buf.append( + "\n\nThe browser instead transmitted some file names. " + f"This was submitted: {names}" + ) + self.msg = "".join(buf) + + def __str__(self): + return self.msg + + +class FormDataRoutingRedirect(AssertionError): + """This exception is raised in debug mode if a routing redirect + would cause the browser to drop the method or body. This happens + when method is not GET, HEAD or OPTIONS and the status code is not + 307 or 308. + """ + + def __init__(self, request): + exc = request.routing_exception + buf = [ + f"A request was sent to '{request.url}', but routing issued" + f" a redirect to the canonical URL '{exc.new_url}'." + ] + + if f"{request.base_url}/" == exc.new_url.partition("?")[0]: + buf.append( + " The URL was defined with a trailing slash. Flask" + " will redirect to the URL with a trailing slash if it" + " was accessed without one." + ) + + buf.append( + " Send requests to the canonical URL, or use 307 or 308 for" + " routing redirects. Otherwise, browsers will drop form" + " data.\n\n" + "This exception is only raised in debug mode." + ) + super().__init__("".join(buf)) + + +def attach_enctype_error_multidict(request): + """Patch ``request.files.__getitem__`` to raise a descriptive error + about ``enctype=multipart/form-data``. + + :param request: The request to patch. + :meta private: + """ + oldcls = request.files.__class__ + + class newcls(oldcls): + def __getitem__(self, key): + try: + return super().__getitem__(key) + except KeyError as e: + if key not in request.form: + raise + + raise DebugFilesKeyError(request, key).with_traceback( + e.__traceback__ + ) from None + + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader) -> t.Generator: + yield f"class: {type(loader).__module__}.{type(loader).__name__}" + for key, value in sorted(loader.__dict__.items()): + if key.startswith("_"): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, str) for x in value): + continue + yield f"{key}:" + for item in value: + yield f" - {item}" + continue + elif not isinstance(value, (str, int, float, bool)): + continue + yield f"{key}: {value!r}" + + +def explain_template_loading_attempts(app: App, template, attempts) -> None: + """This should help developers understand what failed""" + info = [f"Locating template {template!r}:"] + total_found = 0 + blueprint = None + if request_ctx and request_ctx.request.blueprint is not None: + blueprint = request_ctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, App): + src_info = f"application {srcobj.import_name!r}" + elif isinstance(srcobj, Blueprint): + src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})" + else: + src_info = repr(srcobj) + + info.append(f"{idx + 1:5}: trying loader of {src_info}") + + for line in _dump_loader_info(loader): + info.append(f" {line}") + + if triple is None: + detail = "no match" + else: + detail = f"found ({triple[1] or ''!r})" + total_found += 1 + info.append(f" -> {detail}") + + seems_fishy = False + if total_found == 0: + info.append("Error: the template could not be found.") + seems_fishy = True + elif total_found > 1: + info.append("Warning: multiple loaders returned a match for the template.") + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append( + " The template was looked up from an endpoint that belongs" + f" to the blueprint {blueprint!r}." + ) + info.append(" Maybe you did not place a template in the right folder?") + info.append(" See https://flask.palletsprojects.com/blueprints/#templates") + + app.logger.info("\n".join(info)) diff --git a/.venv/Lib/site-packages/flask/globals.py b/.venv/Lib/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/.venv/Lib/site-packages/flask/globals.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +import typing as t +from contextvars import ContextVar + +from werkzeug.local import LocalProxy + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .ctx import _AppCtxGlobals + from .ctx import AppContext + from .ctx import RequestContext + from .sessions import SessionMixin + from .wrappers import Request + + +_no_app_msg = """\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +the current application. To solve this, set up an application context +with app.app_context(). See the documentation for more information.\ +""" +_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx") +app_ctx: AppContext = LocalProxy( # type: ignore[assignment] + _cv_app, unbound_message=_no_app_msg +) +current_app: Flask = LocalProxy( # type: ignore[assignment] + _cv_app, "app", unbound_message=_no_app_msg +) +g: _AppCtxGlobals = LocalProxy( # type: ignore[assignment] + _cv_app, "g", unbound_message=_no_app_msg +) + +_no_req_msg = """\ +Working outside of request context. + +This typically means that you attempted to use functionality that needed +an active HTTP request. Consult the documentation on testing for +information about how to avoid this problem.\ +""" +_cv_request: ContextVar[RequestContext] = ContextVar("flask.request_ctx") +request_ctx: RequestContext = LocalProxy( # type: ignore[assignment] + _cv_request, unbound_message=_no_req_msg +) +request: Request = LocalProxy( # type: ignore[assignment] + _cv_request, "request", unbound_message=_no_req_msg +) +session: SessionMixin = LocalProxy( # type: ignore[assignment] + _cv_request, "session", unbound_message=_no_req_msg +) diff --git a/.venv/Lib/site-packages/flask/helpers.py b/.venv/Lib/site-packages/flask/helpers.py new file mode 100644 index 0000000..13a5aa2 --- /dev/null +++ b/.venv/Lib/site-packages/flask/helpers.py @@ -0,0 +1,623 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import lru_cache +from functools import update_wrapper + +import werkzeug.utils +from werkzeug.exceptions import abort as _wz_abort +from werkzeug.utils import redirect as _wz_redirect + +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .globals import request_ctx +from .globals import session +from .signals import message_flashed + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.wrappers import Response as BaseResponse + from .wrappers import Response + + +def get_debug_flag() -> bool: + """Get whether debug mode should be enabled for the app, indicated by the + :envvar:`FLASK_DEBUG` environment variable. The default is ``False``. + """ + val = os.environ.get("FLASK_DEBUG") + return bool(val and val.lower() not in {"0", "false", "no"}) + + +def get_load_dotenv(default: bool = True) -> bool: + """Get whether the user has disabled loading default dotenv files by + setting :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load + the files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get("FLASK_SKIP_DOTENV") + + if not val: + return default + + return val.lower() in ("0", "false", "no") + + +def stream_with_context( + generator_or_function: ( + t.Iterator[t.AnyStr] | t.Callable[..., t.Iterator[t.AnyStr]] + ) +) -> t.Iterator[t.AnyStr]: + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) # type: ignore + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore + + def generator() -> t.Generator: + ctx = _cv_request.get(None) + if ctx is None: + raise RuntimeError( + "'stream_with_context' can only be used when a request" + " context is active, such as in a view function." + ) + with ctx: + # Dummy sentinel. Has to be inside the context block or we're + # not actually keeping the context around. + yield None + + # The try/finally is here so that if someone passes a WSGI level + # iterator in we're still running the cleanup logic. Generators + # don't need that because they are closed on their destruction + # automatically. + try: + yield from gen + finally: + if hasattr(gen, "close"): + gen.close() + + # The trick is to start the generator. Then the code execution runs until + # the first dummy None is yielded at which point the context was already + # pushed. This item is discarded. Then when the iteration continues the + # real generator is executed. + wrapped_g = generator() + next(wrapped_g) + return wrapped_g + + +def make_response(*args: t.Any) -> Response: + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) # type: ignore + + +def url_for( + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, +) -> str: + """Generate a URL to the given endpoint with the given values. + + This requires an active request or application context, and calls + :meth:`current_app.url_for() `. See that method + for full documentation. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it is + external. + :param _external: If given, prefer the URL to be internal (False) or + require it to be external (True). External URLs include the + scheme and domain. When not in an active request, URLs are + external by default. + :param values: Values to use for the variable parts of the URL rule. + Unknown keys are appended as query string arguments, like + ``?a=b&c=d``. + + .. versionchanged:: 2.2 + Calls ``current_app.url_for``, allowing an app to override the + behavior. + + .. versionchanged:: 0.10 + The ``_scheme`` parameter was added. + + .. versionchanged:: 0.9 + The ``_anchor`` and ``_method`` parameters were added. + + .. versionchanged:: 0.9 + Calls ``app.handle_url_build_error`` on build errors. + """ + return current_app.url_for( + endpoint, + _anchor=_anchor, + _method=_method, + _scheme=_scheme, + _external=_external, + **values, + ) + + +def redirect( + location: str, code: int = 302, Response: type[BaseResponse] | None = None +) -> BaseResponse: + """Create a redirect response object. + + If :data:`~flask.current_app` is available, it will use its + :meth:`~flask.Flask.redirect` method, otherwise it will use + :func:`werkzeug.utils.redirect`. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + :param Response: The response class to use. Not used when + ``current_app`` is active, which uses ``app.response_class``. + + .. versionadded:: 2.2 + Calls ``current_app.redirect`` if available instead of always + using Werkzeug's default ``redirect``. + """ + if current_app: + return current_app.redirect(location, code=code) + + return _wz_redirect(location, code=code, Response=Response) + + +def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given + status code. + + If :data:`~flask.current_app` is available, it will call its + :attr:`~flask.Flask.aborter` object, otherwise it will use + :func:`werkzeug.exceptions.abort`. + + :param code: The status code for the exception, which must be + registered in ``app.aborter``. + :param args: Passed to the exception. + :param kwargs: Passed to the exception. + + .. versionadded:: 2.2 + Calls ``current_app.aborter`` if available instead of always + using Werkzeug's default ``abort``. + """ + if current_app: + current_app.aborter(code, *args, **kwargs) + + _wz_abort(code, *args, **kwargs) + + +def get_template_attribute(template_name: str, attribute: str) -> t.Any: + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, attribute) + + +def flash(message: str, category: str = "message") -> None: + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get("_flashes", []) + flashes.append((category, message)) + session["_flashes"] = flashes + app = current_app._get_current_object() # type: ignore + message_flashed.send( + app, + _async_wrapper=app.ensure_sync, + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> list[str] | list[tuple[str, str]]: + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :doc:`/patterns/flashing` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: filter of categories to limit return values. Only + categories in the list will be returned. + """ + flashes = request_ctx.flashes + if flashes is None: + flashes = session.pop("_flashes") if "_flashes" in session else [] + request_ctx.flashes = flashes + if category_filter: + flashes = list(filter(lambda f: f[0] in category_filter, flashes)) + if not with_categories: + return [x[1] for x in flashes] + return flashes + + +def _prepare_send_file_kwargs(**kwargs: t.Any) -> dict[str, t.Any]: + if kwargs.get("max_age") is None: + kwargs["max_age"] = current_app.get_send_file_max_age + + kwargs.update( + environ=request.environ, + use_x_sendfile=current_app.config["USE_X_SENDFILE"], + response_class=current_app.response_class, + _root_path=current_app.root_path, # type: ignore + ) + return kwargs + + +def send_file( + path_or_file: os.PathLike | str | t.BinaryIO, + mimetype: str | None = None, + as_attachment: bool = False, + download_name: str | None = None, + conditional: bool = True, + etag: bool | str = True, + last_modified: datetime | int | float | None = None, + max_age: None | (int | t.Callable[[str | None], int | None]) = None, +) -> Response: + """Send the contents of a file to the client. + + The first argument can be a file path or a file-like object. Paths + are preferred in most cases because Werkzeug can manage the file and + get extra information from the path. Passing a file-like object + requires that the file is opened in binary mode, and is mostly + useful when building a file in memory with :class:`io.BytesIO`. + + Never pass file paths provided by a user. The path is assumed to be + trusted, so a user could craft a path to access a file you didn't + intend. Use :func:`send_from_directory` to safely serve + user-requested paths from within a directory. + + If the WSGI server sets a ``file_wrapper`` in ``environ``, it is + used, otherwise Werkzeug's built-in wrapper is used. Alternatively, + if the HTTP server supports ``X-Sendfile``, configuring Flask with + ``USE_X_SENDFILE = True`` will tell the server to send the given + path, which is much more efficient than reading it in Python. + + :param path_or_file: The path to the file to send, relative to the + current working directory if a relative path is given. + Alternatively, a file-like object opened in binary mode. Make + sure the file pointer is seeked to the start of the data. + :param mimetype: The MIME type to send for the file. If not + provided, it will try to detect it from the file name. + :param as_attachment: Indicate to a browser that it should offer to + save the file instead of displaying it. + :param download_name: The default name browsers will use when saving + the file. Defaults to the passed file name. + :param conditional: Enable conditional and range responses based on + request headers. Requires passing a file path and ``environ``. + :param etag: Calculate an ETag for the file, which requires passing + a file path. Can also be a string to use instead. + :param last_modified: The last modified time to send for the file, + in seconds. If not provided, it will try to detect it from the + file path. + :param max_age: How long the client should cache the file, in + seconds. If set, ``Cache-Control`` will be ``public``, otherwise + it will be ``no-cache`` to prefer conditional caching. + + .. versionchanged:: 2.0 + ``download_name`` replaces the ``attachment_filename`` + parameter. If ``as_attachment=False``, it is passed with + ``Content-Disposition: inline`` instead. + + .. versionchanged:: 2.0 + ``max_age`` replaces the ``cache_timeout`` parameter. + ``conditional`` is enabled and ``max_age`` is not set by + default. + + .. versionchanged:: 2.0 + ``etag`` replaces the ``add_etags`` parameter. It can be a + string to use instead of generating one. + + .. versionchanged:: 2.0 + Passing a file-like object that inherits from + :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather + than sending an empty file. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionchanged:: 1.1 + ``filename`` may be a :class:`~os.PathLike` object. + + .. versionchanged:: 1.1 + Passing a :class:`~io.BytesIO` object supports range requests. + + .. versionchanged:: 1.0.3 + Filenames are encoded with ASCII instead of Latin-1 for broader + compatibility with WSGI servers. + + .. versionchanged:: 1.0 + UTF-8 filenames as specified in :rfc:`2231` are supported. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file + objects. If you want to use automatic MIME and etag support, + pass a filename via ``filename_or_fp`` or + ``attachment_filename``. + + .. versionchanged:: 0.12 + ``attachment_filename`` is preferred over ``filename`` for MIME + detection. + + .. versionchanged:: 0.9 + ``cache_timeout`` defaults to + :meth:`Flask.get_send_file_max_age`. + + .. versionchanged:: 0.7 + MIME guessing and etag support for file-like objects was + removed because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. + + .. versionchanged:: 0.5 + The ``add_etags``, ``cache_timeout`` and ``conditional`` + parameters were added. The default behavior is to add etags. + + .. versionadded:: 0.2 + """ + return werkzeug.utils.send_file( # type: ignore[return-value] + **_prepare_send_file_kwargs( + path_or_file=path_or_file, + environ=request.environ, + mimetype=mimetype, + as_attachment=as_attachment, + download_name=download_name, + conditional=conditional, + etag=etag, + last_modified=last_modified, + max_age=max_age, + ) + ) + + +def send_from_directory( + directory: os.PathLike | str, + path: os.PathLike | str, + **kwargs: t.Any, +) -> Response: + """Send a file from within a directory using :func:`send_file`. + + .. code-block:: python + + @app.route("/uploads/") + def download_file(name): + return send_from_directory( + app.config['UPLOAD_FOLDER'], name, as_attachment=True + ) + + This is a secure way to serve files from a folder, such as static + files or uploads. Uses :func:`~werkzeug.security.safe_join` to + ensure the path coming from the client is not maliciously crafted to + point outside the specified directory. + + If the final path does not point to an existing regular file, + raises a 404 :exc:`~werkzeug.exceptions.NotFound` error. + + :param directory: The directory that ``path`` must be located under, + relative to the current application's root path. + :param path: The path to the file to send, relative to + ``directory``. + :param kwargs: Arguments to pass to :func:`send_file`. + + .. versionchanged:: 2.0 + ``path`` replaces the ``filename`` parameter. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionadded:: 0.5 + """ + return werkzeug.utils.send_from_directory( # type: ignore[return-value] + directory, path, **_prepare_send_file_kwargs(**kwargs) + ) + + +def get_root_path(import_name: str) -> str: + """Find the root path of a package, or the path that contains a + module. If it cannot be found, returns the current working + directory. + + Not to be confused with the value returned by :func:`find_package`. + + :meta private: + """ + # Module already imported and has a file attribute. Use that first. + mod = sys.modules.get(import_name) + + if mod is not None and hasattr(mod, "__file__") and mod.__file__ is not None: + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + try: + spec = importlib.util.find_spec(import_name) + + if spec is None: + raise ValueError + except (ImportError, ValueError): + loader = None + else: + loader = spec.loader + + # Loader does not exist or we're referring to an unloaded main + # module or a main module without path (interactive sessions), go + # with the current working directory. + if loader is None: + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +@lru_cache(maxsize=None) +def _split_blueprint_path(name: str) -> list[str]: + out: list[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/.venv/Lib/site-packages/flask/json/__init__.py b/.venv/Lib/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..f15296f --- /dev/null +++ b/.venv/Lib/site-packages/flask/json/__init__.py @@ -0,0 +1,170 @@ +from __future__ import annotations + +import json as _json +import typing as t + +from ..globals import current_app +from .provider import _default + +if t.TYPE_CHECKING: # pragma: no cover + from ..wrappers import Response + + +def dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dumps() ` + method, otherwise it will use :func:`json.dumps`. + + :param obj: The data to serialize. + :param kwargs: Arguments passed to the ``dumps`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dumps``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.dumps(obj, **kwargs) + + kwargs.setdefault("default", _default) + return _json.dumps(obj, **kwargs) + + +def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dump() ` + method, otherwise it will use :func:`json.dump`. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: Arguments passed to the ``dump`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dump``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, will be + removed in Flask 2.1. + """ + if current_app: + current_app.json.dump(obj, fp, **kwargs) + else: + kwargs.setdefault("default", _default) + _json.dump(obj, fp, **kwargs) + + +def loads(s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.loads() ` + method, otherwise it will use :func:`json.loads`. + + :param s: Text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``loads`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.loads``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The data must be a + string or UTF-8 bytes. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.loads(s, **kwargs) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.load() ` + method, otherwise it will use :func:`json.load`. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``load`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.load``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The file must be text + mode, or binary mode with UTF-8 bytes. + """ + if current_app: + return current_app.json.load(fp, **kwargs) + + return _json.load(fp, **kwargs) + + +def jsonify(*args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. A dict or list returned from a view will be converted to a + JSON response automatically without needing to call this. + + This requires an active request or application context, and calls + :meth:`app.json.response() `. + + In debug mode, the output is formatted with indentation to make it + easier to read. This may also be controlled by the provider. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + + .. versionchanged:: 2.2 + Calls ``current_app.json.response``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 0.11 + Added support for serializing top-level arrays. This was a + security risk in ancient browsers. See :ref:`security-json`. + + .. versionadded:: 0.2 + """ + return current_app.json.response(*args, **kwargs) diff --git a/.venv/Lib/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5de66e7dbf708e6cf8f2f2e3b9f514043a76ea22 GIT binary patch literal 5989 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 to an instance of the class. + + :param app: An application instance. This will be stored as a + :class:`weakref.proxy` on the :attr:`_app` attribute. + + .. versionadded:: 2.2 + """ + + def __init__(self, app: App) -> None: + self._app = weakref.proxy(app) + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + :param obj: The data to serialize. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def dump(self, obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: May be passed to the underlying JSON library. + """ + fp.write(self.dumps(obj, **kwargs)) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + :param s: Text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + return self.loads(fp.read(), **kwargs) + + def _prepare_response_obj( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> t.Any: + if args and kwargs: + raise TypeError("app.json.response() takes either args or kwargs, not both") + + if not args and not kwargs: + return None + + if len(args) == 1: + return args[0] + + return args or kwargs + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. + + The :func:`~flask.json.jsonify` function calls this method for + the current application. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + return self._app.response_class(self.dumps(obj), mimetype="application/json") + + +def _default(o: t.Any) -> t.Any: + if isinstance(o, date): + return http_date(o) + + if isinstance(o, (decimal.Decimal, uuid.UUID)): + return str(o) + + if dataclasses and dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + + if hasattr(o, "__html__"): + return str(o.__html__()) + + raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable") + + +class DefaultJSONProvider(JSONProvider): + """Provide JSON operations using Python's built-in :mod:`json` + library. Serializes the following additional data types: + + - :class:`datetime.datetime` and :class:`datetime.date` are + serialized to :rfc:`822` strings. This is the same as the HTTP + date format. + - :class:`uuid.UUID` is serialized to a string. + - :class:`dataclasses.dataclass` is passed to + :func:`dataclasses.asdict`. + - :class:`~markupsafe.Markup` (or any object with a ``__html__`` + method) will call the ``__html__`` method to get a string. + """ + + default: t.Callable[[t.Any], t.Any] = staticmethod( + _default + ) # type: ignore[assignment] + """Apply this function to any object that :meth:`json.dumps` does + not know how to serialize. It should return a valid JSON type or + raise a ``TypeError``. + """ + + ensure_ascii = True + """Replace non-ASCII characters with escape sequences. This may be + more compatible with some clients, but can be disabled for better + performance and size. + """ + + sort_keys = True + """Sort the keys in any serialized dicts. This may be useful for + some caching situations, but can be disabled for better performance. + When enabled, keys must all be strings, they are not converted + before sorting. + """ + + compact: bool | None = None + """If ``True``, or ``None`` out of debug mode, the :meth:`response` + output will not add indentation, newlines, or spaces. If ``False``, + or ``None`` in debug mode, it will use a non-compact representation. + """ + + mimetype = "application/json" + """The mimetype set in :meth:`response`.""" + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON to a string. + + Keyword arguments are passed to :func:`json.dumps`. Sets some + parameter defaults from the :attr:`default`, + :attr:`ensure_ascii`, and :attr:`sort_keys` attributes. + + :param obj: The data to serialize. + :param kwargs: Passed to :func:`json.dumps`. + """ + kwargs.setdefault("default", self.default) + kwargs.setdefault("ensure_ascii", self.ensure_ascii) + kwargs.setdefault("sort_keys", self.sort_keys) + return json.dumps(obj, **kwargs) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON from a string or bytes. + + :param s: Text or UTF-8 bytes. + :param kwargs: Passed to :func:`json.loads`. + """ + return json.loads(s, **kwargs) + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with it. The response mimetype + will be "application/json" and can be changed with + :attr:`mimetype`. + + If :attr:`compact` is ``False`` or debug mode is enabled, the + output will be formatted to be easier to read. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + dump_args: dict[str, t.Any] = {} + + if (self.compact is None and self._app.debug) or self.compact is False: + dump_args.setdefault("indent", 2) + else: + dump_args.setdefault("separators", (",", ":")) + + return self._app.response_class( + f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype + ) diff --git a/.venv/Lib/site-packages/flask/json/tag.py b/.venv/Lib/site-packages/flask/json/tag.py new file mode 100644 index 0000000..91cc441 --- /dev/null +++ b/.venv/Lib/site-packages/flask/json/tag.py @@ -0,0 +1,314 @@ +""" +Tagged JSON +~~~~~~~~~~~ + +A compact representation for lossless serialization of non-standard JSON +types. :class:`~flask.sessions.SecureCookieSessionInterface` uses this +to serialize the session data, but it may be useful in other places. It +can be extended to support other types. + +.. autoclass:: TaggedJSONSerializer + :members: + +.. autoclass:: JSONTag + :members: + +Let's see an example that adds support for +:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so +to handle this we will dump the items as a list of ``[key, value]`` +pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to +identify the type. The session serializer processes dicts first, so +insert the new tag at the front of the order since ``OrderedDict`` must +be processed before ``dict``. + +.. code-block:: python + + from flask.json.tag import JSONTag + + class TagOrderedDict(JSONTag): + __slots__ = ('serializer',) + key = ' od' + + def check(self, value): + return isinstance(value, OrderedDict) + + def to_json(self, value): + return [[k, self.serializer.tag(v)] for k, v in iteritems(value)] + + def to_python(self, value): + return OrderedDict(value) + + app.session_interface.serializer.register(TagOrderedDict, index=0) +""" +from __future__ import annotations + +import typing as t +from base64 import b64decode +from base64 import b64encode +from datetime import datetime +from uuid import UUID + +from markupsafe import Markup +from werkzeug.http import http_date +from werkzeug.http import parse_date + +from ..json import dumps +from ..json import loads + + +class JSONTag: + """Base class for defining type tags for :class:`TaggedJSONSerializer`.""" + + __slots__ = ("serializer",) + + #: The tag to mark the serialized object with. If ``None``, this tag is + #: only used as an intermediate step during tagging. + key: str | None = None + + def __init__(self, serializer: TaggedJSONSerializer) -> None: + """Create a tagger for the given serializer.""" + self.serializer = serializer + + def check(self, value: t.Any) -> bool: + """Check if the given value should be tagged by this tag.""" + raise NotImplementedError + + def to_json(self, value: t.Any) -> t.Any: + """Convert the Python object to an object that is a valid JSON type. + The tag will be added later.""" + raise NotImplementedError + + def to_python(self, value: t.Any) -> t.Any: + """Convert the JSON representation back to the correct type. The tag + will already be removed.""" + raise NotImplementedError + + def tag(self, value: t.Any) -> t.Any: + """Convert the value to a valid JSON type and add the tag structure + around it.""" + return {self.key: self.to_json(value)} + + +class TagDict(JSONTag): + """Tag for 1-item dicts whose only key matches a registered tag. + + Internally, the dict key is suffixed with `__`, and the suffix is removed + when deserializing. + """ + + __slots__ = () + key = " di" + + def check(self, value: t.Any) -> bool: + return ( + isinstance(value, dict) + and len(value) == 1 + and next(iter(value)) in self.serializer.tags + ) + + def to_json(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {f"{key}__": self.serializer.tag(value[key])} + + def to_python(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {key[:-2]: value[key]} + + +class PassDict(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, dict) + + def to_json(self, value: t.Any) -> t.Any: + # JSON objects may only have string keys, so don't bother tagging the + # key here. + return {k: self.serializer.tag(v) for k, v in value.items()} + + tag = to_json + + +class TagTuple(JSONTag): + __slots__ = () + key = " t" + + def check(self, value: t.Any) -> bool: + return isinstance(value, tuple) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + def to_python(self, value: t.Any) -> t.Any: + return tuple(value) + + +class PassList(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, list) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + tag = to_json + + +class TagBytes(JSONTag): + __slots__ = () + key = " b" + + def check(self, value: t.Any) -> bool: + return isinstance(value, bytes) + + def to_json(self, value: t.Any) -> t.Any: + return b64encode(value).decode("ascii") + + def to_python(self, value: t.Any) -> t.Any: + return b64decode(value) + + +class TagMarkup(JSONTag): + """Serialize anything matching the :class:`~markupsafe.Markup` API by + having a ``__html__`` method to the result of that method. Always + deserializes to an instance of :class:`~markupsafe.Markup`.""" + + __slots__ = () + key = " m" + + def check(self, value: t.Any) -> bool: + return callable(getattr(value, "__html__", None)) + + def to_json(self, value: t.Any) -> t.Any: + return str(value.__html__()) + + def to_python(self, value: t.Any) -> t.Any: + return Markup(value) + + +class TagUUID(JSONTag): + __slots__ = () + key = " u" + + def check(self, value: t.Any) -> bool: + return isinstance(value, UUID) + + def to_json(self, value: t.Any) -> t.Any: + return value.hex + + def to_python(self, value: t.Any) -> t.Any: + return UUID(value) + + +class TagDateTime(JSONTag): + __slots__ = () + key = " d" + + def check(self, value: t.Any) -> bool: + return isinstance(value, datetime) + + def to_json(self, value: t.Any) -> t.Any: + return http_date(value) + + def to_python(self, value: t.Any) -> t.Any: + return parse_date(value) + + +class TaggedJSONSerializer: + """Serializer that uses a tag system to compactly represent objects that + are not JSON types. Passed as the intermediate serializer to + :class:`itsdangerous.Serializer`. + + The following extra types are supported: + + * :class:`dict` + * :class:`tuple` + * :class:`bytes` + * :class:`~markupsafe.Markup` + * :class:`~uuid.UUID` + * :class:`~datetime.datetime` + """ + + __slots__ = ("tags", "order") + + #: Tag classes to bind when creating the serializer. Other tags can be + #: added later using :meth:`~register`. + default_tags = [ + TagDict, + PassDict, + TagTuple, + PassList, + TagBytes, + TagMarkup, + TagUUID, + TagDateTime, + ] + + def __init__(self) -> None: + self.tags: dict[str, JSONTag] = {} + self.order: list[JSONTag] = [] + + for cls in self.default_tags: + self.register(cls) + + def register( + self, + tag_class: type[JSONTag], + force: bool = False, + index: int | None = None, + ) -> None: + """Register a new tag with this serializer. + + :param tag_class: tag class to register. Will be instantiated with this + serializer instance. + :param force: overwrite an existing tag. If false (default), a + :exc:`KeyError` is raised. + :param index: index to insert the new tag in the tag order. Useful when + the new tag is a special case of an existing tag. If ``None`` + (default), the tag is appended to the end of the order. + + :raise KeyError: if the tag key is already registered and ``force`` is + not true. + """ + tag = tag_class(self) + key = tag.key + + if key is not None: + if not force and key in self.tags: + raise KeyError(f"Tag '{key}' is already registered.") + + self.tags[key] = tag + + if index is None: + self.order.append(tag) + else: + self.order.insert(index, tag) + + def tag(self, value: t.Any) -> dict[str, t.Any]: + """Convert a value to a tagged representation if necessary.""" + for tag in self.order: + if tag.check(value): + return tag.tag(value) + + return value + + def untag(self, value: dict[str, t.Any]) -> t.Any: + """Convert a tagged representation back to the original type.""" + if len(value) != 1: + return value + + key = next(iter(value)) + + if key not in self.tags: + return value + + return self.tags[key].to_python(value[key]) + + def dumps(self, value: t.Any) -> str: + """Tag the value and dump it to a compact JSON string.""" + return dumps(self.tag(value), separators=(",", ":")) + + def loads(self, value: str) -> t.Any: + """Load data from a JSON string and deserialized any tagged objects.""" + return loads(value, object_hook=self.untag) diff --git a/.venv/Lib/site-packages/flask/logging.py b/.venv/Lib/site-packages/flask/logging.py new file mode 100644 index 0000000..b452f71 --- /dev/null +++ b/.venv/Lib/site-packages/flask/logging.py @@ -0,0 +1,76 @@ +from __future__ import annotations + +import logging +import sys +import typing as t + +from werkzeug.local import LocalProxy + +from .globals import request + +if t.TYPE_CHECKING: # pragma: no cover + from .sansio.app import App + + +@LocalProxy +def wsgi_errors_stream() -> t.TextIO: + """Find the most appropriate error stream for the application. If a request + is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``. + + If you configure your own :class:`logging.StreamHandler`, you may want to + use this for the stream. If you are using file or dict configuration and + can't import this directly, you can refer to it as + ``ext://flask.logging.wsgi_errors_stream``. + """ + return request.environ["wsgi.errors"] if request else sys.stderr + + +def has_level_handler(logger: logging.Logger) -> bool: + """Check if there is a handler in the logging chain that will handle the + given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`. + """ + level = logger.getEffectiveLevel() + current = logger + + while current: + if any(handler.level <= level for handler in current.handlers): + return True + + if not current.propagate: + break + + current = current.parent # type: ignore + + return False + + +#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format +#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``. +default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore +default_handler.setFormatter( + logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s") +) + + +def create_logger(app: App) -> logging.Logger: + """Get the Flask app's logger and configure it if needed. + + The logger name will be the same as + :attr:`app.import_name `. + + When :attr:`~flask.Flask.debug` is enabled, set the logger level to + :data:`logging.DEBUG` if it is not set. + + If there is no handler for the logger's effective level, add a + :class:`~logging.StreamHandler` for + :func:`~flask.logging.wsgi_errors_stream` with a basic format. + """ + logger = logging.getLogger(app.name) + + if app.debug and not logger.level: + logger.setLevel(logging.DEBUG) + + if not has_level_handler(logger): + logger.addHandler(default_handler) + + return logger diff --git a/.venv/Lib/site-packages/flask/py.typed b/.venv/Lib/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/flask/sansio/README.md b/.venv/Lib/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/.venv/Lib/site-packages/flask/sansio/README.md @@ -0,0 +1,6 @@ +# Sansio + +This folder contains code that can be used by alternative Flask +implementations, for example Quart. The code therefore cannot do any +IO, nor be part of a likely IO path. Finally this code cannot use the +Flask globals. diff --git a/.venv/Lib/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc b/.venv/Lib/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfa18b13979885f9d3e2457cc1ba413d630ade3f GIT binary patch literal 28534 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc b/.venv/Lib/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72d88b81a0e21d858679c12a91bb2a334f941e81 GIT binary patch literal 23924 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 timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class App(Scaffold): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + #: The class of the object assigned to :attr:`aborter`, created by + #: :meth:`create_aborter`. That object is called by + #: :func:`flask.abort` to raise HTTP errors, and can be + #: called directly as well. + #: + #: Defaults to :class:`werkzeug.exceptions.Aborter`. + #: + #: .. versionadded:: 2.2 + aborter_class = Aborter + + #: The class that is used for the Jinja environment. + #: + #: .. versionadded:: 0.11 + jinja_environment = Environment + + #: The class that is used for the :data:`~flask.g` instance. + #: + #: Example use cases for a custom class: + #: + #: 1. Store arbitrary attributes on flask.g. + #: 2. Add a property for lazy per-request database connectors. + #: 3. Return None instead of AttributeError on unexpected attributes. + #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. + #: + #: In Flask 0.9 this property was called `request_globals_class` but it + #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the + #: flask.g object is now application context scoped. + #: + #: .. versionadded:: 0.10 + app_ctx_globals_class = _AppCtxGlobals + + #: The class that is used for the ``config`` attribute of this app. + #: Defaults to :class:`~flask.Config`. + #: + #: Example use cases for a custom class: + #: + #: 1. Default values for certain config options. + #: 2. Access to config values through attributes in addition to keys. + #: + #: .. versionadded:: 0.11 + config_class = Config + + #: The testing flag. Set this to ``True`` to enable the test mode of + #: Flask extensions (and in the future probably also Flask itself). + #: For example this might activate test helpers that have an + #: additional runtime cost which should not be enabled by default. + #: + #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the + #: default it's implicitly enabled. + #: + #: This attribute can also be configured from the config with the + #: ``TESTING`` configuration key. Defaults to ``False``. + testing = ConfigAttribute("TESTING") + + #: If a secret key is set, cryptographic components can use this to + #: sign cookies and other things. Set this to a complex random value + #: when you want to use the secure cookie for instance. + #: + #: This attribute can also be configured from the config with the + #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. + secret_key = ConfigAttribute("SECRET_KEY") + + #: A :class:`~datetime.timedelta` which is used to set the expiration + #: date of a permanent session. The default is 31 days which makes a + #: permanent session survive for roughly one month. + #: + #: This attribute can also be configured from the config with the + #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to + #: ``timedelta(days=31)`` + permanent_session_lifetime = ConfigAttribute( + "PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta + ) + + json_provider_class: type[JSONProvider] = DefaultJSONProvider + """A subclass of :class:`~flask.json.provider.JSONProvider`. An + instance is created and assigned to :attr:`app.json` when creating + the app. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses + Python's built-in :mod:`json` library. A different provider can use + a different JSON library. + + .. versionadded:: 2.2 + """ + + #: Options that are passed to the Jinja environment in + #: :meth:`create_jinja_environment`. Changing these options after + #: the environment is created (accessing :attr:`jinja_env`) will + #: have no effect. + #: + #: .. versionchanged:: 1.1.0 + #: This is a ``dict`` instead of an ``ImmutableDict`` to allow + #: easier configuration. + #: + jinja_options: dict = {} + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: The map object to use for storing the URL rules and routing + #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`. + #: + #: .. versionadded:: 1.1.0 + url_map_class = Map + + #: The :meth:`test_client` method creates an instance of this test + #: client class. Defaults to :class:`~flask.testing.FlaskClient`. + #: + #: .. versionadded:: 0.7 + test_client_class: type[FlaskClient] | None = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class: type[FlaskCliRunner] | None = None + + default_config: dict + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + "If an instance path is provided it must be absolute." + " A relative path was given instead." + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: An instance of :attr:`aborter_class` created by + #: :meth:`make_aborter`. This is called by :func:`flask.abort` + #: to raise HTTP errors, and can be called directly as well. + #: + #: .. versionadded:: 2.2 + #: Moved from ``flask.abort``, which calls this object. + self.aborter = self.make_aborter() + + self.json: JSONProvider = self.json_provider_class(self) + """Provides access to JSON methods. Functions in ``flask.json`` + will call methods on this provider when the application context + is active. Used for handling JSON requests and responses. + + An instance of :attr:`json_provider_class`. Can be customized by + changing that attribute on a subclass, or by assigning to this + attribute afterwards. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, + uses Python's built-in :mod:`json` library. A different provider + can use a different JSON library. + + .. versionadded:: 2.2 + """ + + #: A list of functions that are called by + #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function is called + #: with ``error``, ``endpoint`` and ``values``. If a function + #: returns ``None`` or raises a ``BuildError``, it is skipped. + #: Otherwise, its return value is returned by ``url_for``. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers: list[ + t.Callable[[Exception, str, dict[str, t.Any]], str] + ] = [] + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs: list[ft.TeardownCallable] = [] + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors: list[ft.ShellContextProcessorCallable] = [] + + #: Maps registered blueprint names to blueprint objects. The + #: dict retains the order the blueprints were registered in. + #: Blueprints can be registered multiple times, this dict does + #: not track how often they were attached. + #: + #: .. versionadded:: 0.7 + self.blueprints: dict[str, Blueprint] = {} + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions: dict = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = self.url_map_class(host_matching=host_matching) + + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_first_request: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called" + " on the application. It has already handled its first" + " request, any changes will not be applied" + " consistently.\n" + "Make sure all imports, decorators, functions, etc." + " needed to set up the application are done before" + " running it." + ) + + @cached_property + def name(self) -> str: # type: ignore + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == "__main__": + fn = getattr(sys.modules["__main__"], "__file__", None) + if fn is None: + return "__main__" + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @cached_property + def logger(self) -> logging.Logger: + """A standard Python :class:`~logging.Logger` for the app, with + the same name as :attr:`name`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will + be set to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be + added. See :doc:`/logging` for more information. + + .. versionchanged:: 1.1.0 + The logger takes the same name as :attr:`name` rather than + hard-coding ``"flask.app"``. + + .. versionchanged:: 1.0.0 + Behavior was simplified. The logger is always named + ``"flask.app"``. The level is only set during configuration, + it doesn't check ``app.debug`` each time. Only one format is + used, not different ones depending on ``app.debug``. No + handlers are removed, and a handler is only added if no + handlers are already configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @cached_property + def jinja_env(self) -> Environment: + """The Jinja environment used to load templates. + + The environment is created the first time this property is + accessed. Changing :attr:`jinja_options` after that will have no + effect. + """ + return self.create_jinja_environment() + + def create_jinja_environment(self) -> Environment: + raise NotImplementedError() + + def make_config(self, instance_relative: bool = False) -> Config: + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults["DEBUG"] = get_debug_flag() + return self.config_class(root_path, defaults) + + def make_aborter(self) -> Aborter: + """Create the object to assign to :attr:`aborter`. That object + is called by :func:`flask.abort` to raise HTTP errors, and can + be called directly as well. + + By default, this creates an instance of :attr:`aborter_class`, + which defaults to :class:`werkzeug.exceptions.Aborter`. + + .. versionadded:: 2.2 + """ + return self.aborter_class() + + def auto_find_instance_path(self) -> str: + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, "instance") + return os.path.join(prefix, "var", f"{self.name}-instance") + + def create_global_jinja_loader(self) -> DispatchingJinjaLoader: + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename: str) -> bool: + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionchanged:: 2.2 + Autoescaping is now enabled by default for ``.svg`` files. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml", ".svg")) + + @property + def debug(self) -> bool: + """Whether debug mode is enabled. When using ``flask run`` to start the + development server, an interactive debugger will be shown for unhandled + exceptions, and the server will be reloaded when code changes. This maps to the + :data:`DEBUG` config key. It may not behave as expected if set late. + + **Do not enable debug mode when deploying in production.** + + Default: ``False`` + """ + return self.config["DEBUG"] + + @debug.setter + def debug(self, value: bool) -> None: + self.config["DEBUG"] = value + + if self.config["TEMPLATES_AUTO_RELOAD"] is None: + self.jinja_env.auto_reload = value + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 0.7 + """ + blueprint.register(self, options) + + def iter_blueprints(self) -> t.ValuesView[Blueprint]: + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return self.blueprints.values() + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + options["endpoint"] = endpoint + methods = options.pop("methods", None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, "methods", None) or ("GET",) + if isinstance(methods, str): + raise TypeError( + "Allowed methods must be a list of strings, for" + ' example: @app.route(..., methods=["POST"])' + ) + methods = {item.upper() for item in methods} + + # Methods that should always be added + required_methods = set(getattr(view_func, "required_methods", ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr( + view_func, "provide_automatic_options", None + ) + + if provide_automatic_options is None: + if "OPTIONS" not in methods: + provide_automatic_options = True + required_methods.add("OPTIONS") + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule = self.url_rule_class(rule, methods=methods, **options) + rule.provide_automatic_options = provide_automatic_options # type: ignore + + self.url_map.add(rule) + if view_func is not None: + old_func = self.view_functions.get(endpoint) + if old_func is not None and old_func != view_func: + raise AssertionError( + "View function mapping is overwriting an existing" + f" endpoint function: {endpoint}" + ) + self.view_functions[endpoint] = view_func + + @setupmethod + def template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """A decorator that is used to register custom template test. + You can specify a name for the test, otherwise the function + name will be used. Example:: + + @app.template_test() + def is_prime(n): + if n == 2: + return True + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): + if n % i == 0: + return False + return True + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def teardown_appcontext(self, f: T_teardown) -> T_teardown: + """Registers a function to be called when the application + context is popped. The application context is typically popped + after the request context for each request, at the end of CLI + commands, or after a manually pushed context ends. + + .. code-block:: python + + with app.app_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the app context is + made inactive. Since a request context typically also manages an + application context it would also be called when you pop a + request context. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + .. versionadded:: 0.9 + """ + self.teardown_appcontext_funcs.append(f) + return f + + @setupmethod + def shell_context_processor( + self, f: T_shell_context_processor + ) -> T_shell_context_processor: + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + def _find_error_handler( + self, e: Exception, blueprints: list[str] + ) -> ft.ErrorHandlerCallable | None: + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + names = (*blueprints, None) + + for c in (code, None) if code is not None else (None,): + for name in names: + handler_map = self.error_handler_spec[name][c] + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + return None + + def trap_http_exception(self, e: Exception) -> bool: + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config["TRAP_HTTP_EXCEPTIONS"]: + return True + + trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None + and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def should_ignore_error(self, error: BaseException | None) -> bool: + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def redirect(self, location: str, code: int = 302) -> BaseResponse: + """Create a redirect response object. + + This is called by :func:`flask.redirect`, and can be called + directly as well. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + + .. versionadded:: 2.2 + Moved from ``flask.redirect``, which calls this method. + """ + return _wz_redirect( + location, code=code, Response=self.response_class # type: ignore[arg-type] + ) + + def inject_url_defaults(self, endpoint: str, values: dict) -> None: + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + names: t.Iterable[str | None] = (None,) + + # url_for may be called outside a request context, parse the + # passed endpoint instead of using request.blueprints. + if "." in endpoint: + names = chain( + names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0])) + ) + + for name in names: + if name in self.url_default_functions: + for func in self.url_default_functions[name]: + func(endpoint, values) + + def handle_url_build_error( + self, error: BuildError, endpoint: str, values: dict[str, t.Any] + ) -> str: + """Called by :meth:`.url_for` if a + :exc:`~werkzeug.routing.BuildError` was raised. If this returns + a value, it will be returned by ``url_for``, otherwise the error + will be re-raised. + + Each function in :attr:`url_build_error_handlers` is called with + ``error``, ``endpoint`` and ``values``. If a function returns + ``None`` or raises a ``BuildError``, it is skipped. Otherwise, + its return value is returned by ``url_for``. + + :param error: The active ``BuildError`` being handled. + :param endpoint: The endpoint being built. + :param values: The keyword arguments passed to ``url_for``. + """ + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + except BuildError as e: + # make error available outside except block + error = e + else: + if rv is not None: + return rv + + # Re-raise if called with an active exception, otherwise raise + # the passed in exception. + if error is sys.exc_info()[1]: + raise + + raise error diff --git a/.venv/Lib/site-packages/flask/sansio/blueprints.py b/.venv/Lib/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..38c92f4 --- /dev/null +++ b/.venv/Lib/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,626 @@ +from __future__ import annotations + +import os +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from .. import typing as ft +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from .app import App + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) + + +class BlueprintSetupState: + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__( + self, + blueprint: Blueprint, + app: App, + options: t.Any, + first_registration: bool, + ) -> None: + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get("subdomain") + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get("url_prefix") + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + self.name = self.options.get("name", blueprint.name) + self.name_prefix = self.options.get("name_prefix", "") + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get("url_defaults", ())) + + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: t.Callable | None = None, + **options: t.Any, + ) -> None: + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/"))) + else: + rule = self.url_prefix + options.setdefault("subdomain", self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + defaults = self.url_defaults + if "defaults" in options: + defaults = dict(defaults, **options.pop("defaults")) + + self.app.add_url_rule( + rule, + f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."), + view_func, + defaults=defaults, + **options, + ) + + +class Blueprint(Scaffold): + """Represents a blueprint, a collection of routes and other + app-related functions that can be registered on a real application + later. + + A blueprint is an object that allows defining application functions + without requiring an application object ahead of time. It uses the + same decorators as :class:`~flask.Flask`, but defers the need for an + application by recording them for later registration. + + Decorating a function with a blueprint creates a deferred function + that is called with :class:`~flask.blueprints.BlueprintSetupState` + when the blueprint is registered on an application. + + See :doc:`/blueprints` for more information. + + :param name: The name of the blueprint. Will be prepended to each + endpoint name. + :param import_name: The name of the blueprint package, usually + ``__name__``. This helps locate the ``root_path`` for the + blueprint. + :param static_folder: A folder with static files that should be + served by the blueprint's static route. The path is relative to + the blueprint's root path. Blueprint static files are disabled + by default. + :param static_url_path: The url to serve static files from. + Defaults to ``static_folder``. If the blueprint does not have + a ``url_prefix``, the app's static route will take precedence, + and the blueprint's static files won't be accessible. + :param template_folder: A folder with templates that should be added + to the app's template search path. The path is relative to the + blueprint's root path. Blueprint templates are disabled by + default. Blueprint templates have a lower precedence than those + in the app's templates folder. + :param url_prefix: A path to prepend to all of the blueprint's URLs, + to make them distinct from the rest of the app's routes. + :param subdomain: A subdomain that blueprint routes will match on by + default. + :param url_defaults: A dict of default values that blueprint routes + will receive by default. + :param root_path: By default, the blueprint will automatically set + this based on ``import_name``. In certain situations this + automatic detection can fail, so the path can be specified + manually instead. + + .. versionchanged:: 1.1.0 + Blueprints have a ``cli`` group to register nested CLI commands. + The ``cli_group`` parameter controls the name of the group under + the ``flask`` command. + + .. versionadded:: 0.7 + """ + + _got_registered_once = False + + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if not name: + raise ValueError("'name' may not be empty.") + + if "." in name: + raise ValueError("'name' may not contain a dot '.' character.") + + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.deferred_functions: list[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: list[tuple[Blueprint, dict]] = [] + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_registered_once: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called on the blueprint" + f" '{self.name}'. It has already been registered at least once, any" + " changes will not be applied consistently.\n" + "Make sure all imports, decorators, functions, etc. needed to set up" + " the blueprint are done before registering it." + ) + + @setupmethod + def record(self, func: t.Callable) -> None: + """Registers a function that is called when the blueprint is + registered on the application. This function is called with the + state as argument as returned by the :meth:`make_setup_state` + method. + """ + self.deferred_functions.append(func) + + @setupmethod + def record_once(self, func: t.Callable) -> None: + """Works like :meth:`record` but wraps the function in another + function that will ensure the function is only called once. If the + blueprint is registered a second time on the application, the + function passed is not called. + """ + + def wrapper(state: BlueprintSetupState) -> None: + if state.first_registration: + func(state) + + self.record(update_wrapper(wrapper, func)) + + def make_setup_state( + self, app: App, options: dict, first_registration: bool = False + ) -> BlueprintSetupState: + """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` + object that is later passed to the register callback functions. + Subclasses can override this to return a subclass of the setup state. + """ + return BlueprintSetupState(self, app, options, first_registration) + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on this blueprint. Keyword + arguments passed to this method will override the defaults set + on the blueprint. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 2.0 + """ + if blueprint is self: + raise ValueError("Cannot register a blueprint on itself") + self._blueprints.append((blueprint, options)) + + def register(self, app: App, options: dict) -> None: + """Called by :meth:`Flask.register_blueprint` to register all + views and callbacks registered on the blueprint with the + application. Creates a :class:`.BlueprintSetupState` and calls + each :meth:`record` callback with it. + + :param app: The application this blueprint is being registered + with. + :param options: Keyword arguments forwarded from + :meth:`~Flask.register_blueprint`. + + .. versionchanged:: 2.3 + Nested blueprints now correctly apply subdomains. + + .. versionchanged:: 2.1 + Registering the same blueprint with the same name multiple + times is an error. + + .. versionchanged:: 2.0.1 + Nested blueprints are registered with their dotted name. + This allows different blueprints with the same name to be + nested at different locations. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + """ + name_prefix = options.get("name_prefix", "") + self_name = options.get("name", self.name) + name = f"{name_prefix}.{self_name}".lstrip(".") + + if name in app.blueprints: + bp_desc = "this" if app.blueprints[name] is self else "a different" + existing_at = f" '{name}'" if self_name != name else "" + + raise ValueError( + f"The name '{self_name}' is already registered for" + f" {bp_desc} blueprint{existing_at}. Use 'name=' to" + f" provide a unique name." + ) + + first_bp_registration = not any(bp is self for bp in app.blueprints.values()) + first_name_registration = name not in app.blueprints + + app.blueprints[name] = self + self._got_registered_once = True + state = self.make_setup_state(app, options, first_bp_registration) + + if self.has_static_folder: + state.add_url_rule( + f"{self.static_url_path}/", + view_func=self.send_static_file, # type: ignore[attr-defined] + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + self._merge_blueprint_funcs(app, name) + + for deferred in self.deferred_functions: + deferred(state) + + cli_resolved_group = options.get("cli_group", self.cli_group) + + if self.cli.commands: + if cli_resolved_group is None: + app.cli.commands.update(self.cli.commands) + elif cli_resolved_group is _sentinel: + self.cli.name = name + app.cli.add_command(self.cli) + else: + self.cli.name = cli_resolved_group + app.cli.add_command(self.cli) + + for blueprint, bp_options in self._blueprints: + bp_options = bp_options.copy() + bp_url_prefix = bp_options.get("url_prefix") + bp_subdomain = bp_options.get("subdomain") + + if bp_subdomain is None: + bp_subdomain = blueprint.subdomain + + if state.subdomain is not None and bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + "." + state.subdomain + elif bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + elif state.subdomain is not None: + bp_options["subdomain"] = state.subdomain + + if bp_url_prefix is None: + bp_url_prefix = blueprint.url_prefix + + if state.url_prefix is not None and bp_url_prefix is not None: + bp_options["url_prefix"] = ( + state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") + ) + elif bp_url_prefix is not None: + bp_options["url_prefix"] = bp_url_prefix + elif state.url_prefix is not None: + bp_options["url_prefix"] = state.url_prefix + + bp_options["name_prefix"] = name + blueprint.register(app, bp_options) + + def _merge_blueprint_funcs(self, app: App, name: str) -> None: + def extend(bp_dict, parent_dict): + for key, values in bp_dict.items(): + key = name if key is None else f"{name}.{key}" + parent_dict[key].extend(values) + + for key, value in self.error_handler_spec.items(): + key = name if key is None else f"{name}.{key}" + value = defaultdict( + dict, + { + code: {exc_class: func for exc_class, func in code_values.items()} + for code, code_values in value.items() + }, + ) + app.error_handler_spec[key] = value + + for endpoint, func in self.view_functions.items(): + app.view_functions[endpoint] = func + + extend(self.before_request_funcs, app.before_request_funcs) + extend(self.after_request_funcs, app.after_request_funcs) + extend( + self.teardown_request_funcs, + app.teardown_request_funcs, + ) + extend(self.url_default_functions, app.url_default_functions) + extend(self.url_value_preprocessors, app.url_value_preprocessors) + extend(self.template_context_processors, app.template_context_processors) + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for + full documentation. + + The URL rule is prefixed with the blueprint's URL prefix. The endpoint name, + used with :func:`url_for`, is prefixed with the blueprint's name. + """ + if endpoint and "." in endpoint: + raise ValueError("'endpoint' may not contain a dot '.' character.") + + if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__: + raise ValueError("'view_func' name may not contain a dot '.' character.") + + self.record( + lambda s: s.add_url_rule( + rule, + endpoint, + view_func, + provide_automatic_options=provide_automatic_options, + **options, + ) + ) + + @setupmethod + def app_template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """Register a template filter, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_app_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a template filter, available in any template rendered by the + application. Works like the :meth:`app_template_filter` decorator. Equivalent to + :meth:`.Flask.add_template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.filters[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """Register a template test, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_app_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a template test, available in any template rendered by the + application. Works like the :meth:`app_template_test` decorator. Equivalent to + :meth:`.Flask.add_template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.tests[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """Register a template global, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_app_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a template global, available in any template rendered by the + application. Works like the :meth:`app_template_global` decorator. Equivalent to + :meth:`.Flask.add_template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.globals[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def before_app_request(self, f: T_before_request) -> T_before_request: + """Like :meth:`before_request`, but before every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.before_request`. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def after_app_request(self, f: T_after_request) -> T_after_request: + """Like :meth:`after_request`, but after every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.after_request`. + """ + self.record_once( + lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def teardown_app_request(self, f: T_teardown) -> T_teardown: + """Like :meth:`teardown_request`, but after every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.teardown_request`. + """ + self.record_once( + lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_context_processor( + self, f: T_template_context_processor + ) -> T_template_context_processor: + """Like :meth:`context_processor`, but for templates rendered by every view, not + only by the blueprint. Equivalent to :meth:`.Flask.context_processor`. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_errorhandler( + self, code: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Like :meth:`errorhandler`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.errorhandler`. + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.record_once(lambda s: s.app.errorhandler(code)(f)) + return f + + return decorator + + @setupmethod + def app_url_value_preprocessor( + self, f: T_url_value_preprocessor + ) -> T_url_value_preprocessor: + """Like :meth:`url_value_preprocessor`, but for every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.url_value_preprocessor`. + """ + self.record_once( + lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Like :meth:`url_defaults`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.url_defaults`. + """ + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/.venv/Lib/site-packages/flask/sansio/scaffold.py b/.venv/Lib/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..a43f6fd --- /dev/null +++ b/.venv/Lib/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,802 @@ +from __future__ import annotations + +import importlib.util +import os +import pathlib +import sys +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from jinja2 import FileSystemLoader +from werkzeug.exceptions import default_exceptions +from werkzeug.exceptions import HTTPException +from werkzeug.utils import cached_property + +from .. import typing as ft +from ..cli import AppGroup +from ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +# a singleton sentinel value for parameter defaults +_sentinel = object() + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) +T_route = t.TypeVar("T_route", bound=ft.RouteCallable) + + +def setupmethod(f: F) -> F: + f_name = f.__name__ + + def wrapper_func(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + self._check_setup_finished(f_name) + return f(self, *args, **kwargs) + + return t.cast(F, update_wrapper(wrapper_func, f)) + + +class Scaffold: + """Common behavior shared between :class:`~flask.Flask` and + :class:`~flask.blueprints.Blueprint`. + + :param import_name: The import name of the module where this object + is defined. Usually :attr:`__name__` should be used. + :param static_folder: Path to a folder of static files to serve. + If this is set, a static route will be added. + :param static_url_path: URL prefix for the static route. + :param template_folder: Path to a folder containing template files. + for rendering. If this is set, a Jinja loader will be added. + :param root_path: The path that static, template, and resource files + are relative to. Typically not set, it is discovered based on + the ``import_name``. + + .. versionadded:: 2.0 + """ + + name: str + _static_folder: str | None = None + _static_url_path: str | None = None + + def __init__( + self, + import_name: str, + static_folder: str | os.PathLike | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike | None = None, + root_path: str | None = None, + ): + #: The name of the package or module that this object belongs + #: to. Do not change this once it is set by the constructor. + self.import_name = import_name + + self.static_folder = static_folder # type: ignore + self.static_url_path = static_url_path + + #: The path to the templates folder, relative to + #: :attr:`root_path`, to add to the template loader. ``None`` if + #: templates should not be added. + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + #: Absolute path to the package on the filesystem. Used to look + #: up resources contained in the package. + self.root_path = root_path + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = AppGroup() + + #: A dictionary mapping endpoint names to view functions. + #: + #: To register a view function, use the :meth:`route` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.view_functions: dict[str, t.Callable] = {} + + #: A data structure of registered error handlers, in the format + #: ``{scope: {code: {class: handler}}}``. The ``scope`` key is + #: the name of a blueprint the handlers are active for, or + #: ``None`` for all requests. The ``code`` key is the HTTP + #: status code for ``HTTPException``, or ``None`` for + #: other exceptions. The innermost dictionary maps exception + #: classes to handler functions. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.error_handler_spec: dict[ + ft.AppOrBlueprintKey, + dict[int | None, dict[type[Exception], ft.ErrorHandlerCallable]], + ] = defaultdict(lambda: defaultdict(dict)) + + #: A data structure of functions to call at the beginning of + #: each request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`before_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.before_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.BeforeRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`after_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.after_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.AfterRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request even if an exception is raised, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`teardown_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.teardown_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.TeardownCallable] + ] = defaultdict(list) + + #: A data structure of functions to call to pass extra context + #: values when rendering templates, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`context_processor` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.template_context_processors: dict[ + ft.AppOrBlueprintKey, list[ft.TemplateContextProcessorCallable] + ] = defaultdict(list, {None: [_default_template_ctx_processor]}) + + #: A data structure of functions to call to modify the keyword + #: arguments passed to the view function, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the + #: :meth:`url_value_preprocessor` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_value_preprocessors: dict[ + ft.AppOrBlueprintKey, + list[ft.URLValuePreprocessorCallable], + ] = defaultdict(list) + + #: A data structure of functions to call to modify the keyword + #: arguments when generating URLs, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`url_defaults` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_default_functions: dict[ + ft.AppOrBlueprintKey, list[ft.URLDefaultCallable] + ] = defaultdict(list) + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.name!r}>" + + def _check_setup_finished(self, f_name: str) -> None: + raise NotImplementedError + + @property + def static_folder(self) -> str | None: + """The absolute path to the configured static folder. ``None`` + if no static folder is set. + """ + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + else: + return None + + @static_folder.setter + def static_folder(self, value: str | os.PathLike | None) -> None: + if value is not None: + value = os.fspath(value).rstrip(r"\/") + + self._static_folder = value + + @property + def has_static_folder(self) -> bool: + """``True`` if :attr:`static_folder` is set. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @property + def static_url_path(self) -> str | None: + """The URL prefix that the static route will be accessible from. + + If it was not configured during init, it is derived from + :attr:`static_folder`. + """ + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + basename = os.path.basename(self.static_folder) + return f"/{basename}".rstrip("/") + + return None + + @static_url_path.setter + def static_url_path(self, value: str | None) -> None: + if value is not None: + value = value.rstrip("/") + + self._static_url_path = value + + @cached_property + def jinja_loader(self) -> FileSystemLoader | None: + """The Jinja loader for this object's templates. By default this + is a class :class:`jinja2.loaders.FileSystemLoader` to + :attr:`template_folder` if it is set. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, self.template_folder)) + else: + return None + + def _method_route( + self, + method: str, + rule: str, + options: dict, + ) -> t.Callable[[T_route], T_route]: + if "methods" in options: + raise TypeError("Use the 'route' decorator to use the 'methods' argument.") + + return self.route(rule, methods=[method], **options) + + @setupmethod + def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["GET"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("GET", rule, options) + + @setupmethod + def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["POST"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("POST", rule, options) + + @setupmethod + def put(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PUT"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PUT", rule, options) + + @setupmethod + def delete(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["DELETE"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("DELETE", rule, options) + + @setupmethod + def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PATCH"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PATCH", rule, options) + + @setupmethod + def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Decorate a view function to register it with the given URL + rule and options. Calls :meth:`add_url_rule`, which has more + details about the implementation. + + .. code-block:: python + + @app.route("/") + def index(): + return "Hello, World!" + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` and + ``OPTIONS`` are added automatically. + + :param rule: The URL rule string. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + + def decorator(f: T_route) -> T_route: + endpoint = options.pop("endpoint", None) + self.add_url_rule(rule, endpoint, f, **options) + return f + + return decorator + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a rule for routing incoming requests and building + URLs. The :meth:`route` decorator is a shortcut to call this + with the ``view_func`` argument. These are equivalent: + + .. code-block:: python + + @app.route("/") + def index(): + ... + + .. code-block:: python + + def index(): + ... + + app.add_url_rule("/", view_func=index) + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. An error + will be raised if a function has already been registered for the + endpoint. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` is + always added automatically, and ``OPTIONS`` is added + automatically by default. + + ``view_func`` does not necessarily need to be passed, but if the + rule should participate in routing an endpoint name must be + associated with a view function at some point with the + :meth:`endpoint` decorator. + + .. code-block:: python + + app.add_url_rule("/", endpoint="index") + + @app.endpoint("index") + def index(): + ... + + If ``view_func`` has a ``required_methods`` attribute, those + methods are added to the passed and automatic methods. If it + has a ``provide_automatic_methods`` attribute, it is used as the + default if the parameter is not passed. + + :param rule: The URL rule string. + :param endpoint: The endpoint name to associate with the rule + and view function. Used when routing and building URLs. + Defaults to ``view_func.__name__``. + :param view_func: The view function to associate with the + endpoint name. + :param provide_automatic_options: Add the ``OPTIONS`` method and + respond to ``OPTIONS`` requests automatically. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + raise NotImplementedError + + @setupmethod + def endpoint(self, endpoint: str) -> t.Callable[[F], F]: + """Decorate a view function to register it for the given + endpoint. Used if a rule is added without a ``view_func`` with + :meth:`add_url_rule`. + + .. code-block:: python + + app.add_url_rule("/ex", endpoint="example") + + @app.endpoint("example") + def example(): + ... + + :param endpoint: The endpoint name to associate with the view + function. + """ + + def decorator(f: F) -> F: + self.view_functions[endpoint] = f + return f + + return decorator + + @setupmethod + def before_request(self, f: T_before_request) -> T_before_request: + """Register a function to run before each request. + + For example, this can be used to open a database connection, or + to load the logged in user from the session. + + .. code-block:: python + + @app.before_request + def load_user(): + if "user_id" in session: + g.user = db.session.get(session["user_id"]) + + The function will be called without any arguments. If it returns + a non-``None`` value, the value is handled as if it was the + return value from the view, and further request handling is + stopped. + + This is available on both app and blueprint objects. When used on an app, this + executes before every request. When used on a blueprint, this executes before + every request that the blueprint handles. To register with a blueprint and + execute before every request, use :meth:`.Blueprint.before_app_request`. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def after_request(self, f: T_after_request) -> T_after_request: + """Register a function to run after each request to this object. + + The function is called with the response object, and must return + a response object. This allows the functions to modify or + replace the response before it is sent. + + If a function raises an exception, any remaining + ``after_request`` functions will not be called. Therefore, this + should not be used for actions that must execute, such as to + close resources. Use :meth:`teardown_request` for that. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.after_app_request`. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f: T_teardown) -> T_teardown: + """Register a function to be called when the request context is + popped. Typically this happens at the end of each request, but + contexts may be pushed manually as well during testing. + + .. code-block:: python + + with app.test_request_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the request context is + made inactive. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.teardown_app_request`. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def context_processor( + self, + f: T_template_context_processor, + ) -> T_template_context_processor: + """Registers a template context processor function. These functions run before + rendering a template. The keys of the returned dict are added as variables + available in the template. + + This is available on both app and blueprint objects. When used on an app, this + is called for every rendered template. When used on a blueprint, this is called + for templates rendered from the blueprint's views. To register with a blueprint + and affect every template, use :meth:`.Blueprint.app_context_processor`. + """ + self.template_context_processors[None].append(f) + return f + + @setupmethod + def url_value_preprocessor( + self, + f: T_url_value_preprocessor, + ) -> T_url_value_preprocessor: + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_value_preprocessor`. + """ + self.url_value_preprocessors[None].append(f) + return f + + @setupmethod + def url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_defaults`. + """ + self.url_default_functions[None].append(f) + return f + + @setupmethod + def errorhandler( + self, code_or_exception: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + This is available on both app and blueprint objects. When used on an app, this + can handle errors from every request. When used on a blueprint, this can handle + errors from requests that the blueprint handles. To register with a blueprint + and affect every request, use :meth:`.Blueprint.app_errorhandler`. + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.register_error_handler(code_or_exception, f) + return f + + return decorator + + @setupmethod + def register_error_handler( + self, + code_or_exception: type[Exception] | int, + f: ft.ErrorHandlerCallable, + ) -> None: + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + exc_class, code = self._get_exc_class_and_code(code_or_exception) + self.error_handler_spec[None][code][exc_class] = f + + @staticmethod + def _get_exc_class_and_code( + exc_class_or_code: type[Exception] | int, + ) -> tuple[type[Exception], int | None]: + """Get the exception class being handled. For HTTP status codes + or ``HTTPException`` subclasses, return both the exception and + status code. + + :param exc_class_or_code: Any exception class, or an HTTP status + code as an integer. + """ + exc_class: type[Exception] + + if isinstance(exc_class_or_code, int): + try: + exc_class = default_exceptions[exc_class_or_code] + except KeyError: + raise ValueError( + f"'{exc_class_or_code}' is not a recognized HTTP" + " error code. Use a subclass of HTTPException with" + " that code instead." + ) from None + else: + exc_class = exc_class_or_code + + if isinstance(exc_class, Exception): + raise TypeError( + f"{exc_class!r} is an instance, not a class. Handlers" + " can only be registered for Exception classes or HTTP" + " error codes." + ) + + if not issubclass(exc_class, Exception): + raise ValueError( + f"'{exc_class.__name__}' is not a subclass of Exception." + " Handlers can only be registered for Exception classes" + " or HTTP error codes." + ) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + +def _endpoint_from_view_func(view_func: t.Callable) -> str: + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, "expected view func if endpoint is not provided." + return view_func.__name__ + + +def _path_is_relative_to(path: pathlib.PurePath, base: str) -> bool: + # Path.is_relative_to doesn't exist until Python 3.9 + try: + path.relative_to(base) + return True + except ValueError: + return False + + +def _find_package_path(import_name): + """Find the path that contains the package or module.""" + root_mod_name, _, _ = import_name.partition(".") + + try: + root_spec = importlib.util.find_spec(root_mod_name) + + if root_spec is None: + raise ValueError("not found") + except (ImportError, ValueError): + # ImportError: the machinery told us it does not exist + # ValueError: + # - the module name was invalid + # - the module name is __main__ + # - we raised `ValueError` due to `root_spec` being `None` + return os.getcwd() + + if root_spec.origin in {"namespace", None}: + # namespace package + package_spec = importlib.util.find_spec(import_name) + + if package_spec is not None and package_spec.submodule_search_locations: + # Pick the path in the namespace that contains the submodule. + package_path = pathlib.Path( + os.path.commonpath(package_spec.submodule_search_locations) + ) + search_location = next( + location + for location in root_spec.submodule_search_locations + if _path_is_relative_to(package_path, location) + ) + else: + # Pick the first path. + search_location = root_spec.submodule_search_locations[0] + + return os.path.dirname(search_location) + elif root_spec.submodule_search_locations: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) + + +def find_package(import_name: str): + """Find the prefix that a package is installed under, and the path + that it would be imported from. + + The prefix is the directory containing the standard directory + hierarchy (lib, bin, etc.). If the package is not installed to the + system (:attr:`sys.prefix`) or a virtualenv (``site-packages``), + ``None`` is returned. + + The path is the entry in :attr:`sys.path` that contains the package + for import. If the package is not installed, it's assumed that the + package was imported from the current working directory. + """ + package_path = _find_package_path(import_name) + py_prefix = os.path.abspath(sys.prefix) + + # installed to the system + if _path_is_relative_to(pathlib.PurePath(package_path), py_prefix): + return py_prefix, package_path + + site_parent, site_folder = os.path.split(package_path) + + # installed to a virtualenv + if site_folder.lower() == "site-packages": + parent, folder = os.path.split(site_parent) + + # Windows (prefix/lib/site-packages) + if folder.lower() == "lib": + return parent, package_path + + # Unix (prefix/lib/pythonX.Y/site-packages) + if os.path.basename(parent).lower() == "lib": + return os.path.dirname(parent), package_path + + # something else (prefix/site-packages) + return site_parent, package_path + + # not installed + return None, package_path diff --git a/.venv/Lib/site-packages/flask/sessions.py b/.venv/Lib/site-packages/flask/sessions.py new file mode 100644 index 0000000..e5650d6 --- /dev/null +++ b/.venv/Lib/site-packages/flask/sessions.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import hashlib +import typing as t +from collections.abc import MutableMapping +from datetime import datetime +from datetime import timezone + +from itsdangerous import BadSignature +from itsdangerous import URLSafeTimedSerializer +from werkzeug.datastructures import CallbackDict + +from .json.tag import TaggedJSONSerializer + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .wrappers import Request, Response + + +class SessionMixin(MutableMapping): + """Expands a basic dictionary with session attributes.""" + + @property + def permanent(self) -> bool: + """This reflects the ``'_permanent'`` key in the dict.""" + return self.get("_permanent", False) + + @permanent.setter + def permanent(self, value: bool) -> None: + self["_permanent"] = bool(value) + + #: Some implementations can detect whether a session is newly + #: created, but that is not guaranteed. Use with caution. The mixin + # default is hard-coded ``False``. + new = False + + #: Some implementations can detect changes to the session and set + #: this when that happens. The mixin default is hard coded to + #: ``True``. + modified = True + + #: Some implementations can detect when session data is read or + #: written and set this when that happens. The mixin default is hard + #: coded to ``True``. + accessed = True + + +class SecureCookieSession(CallbackDict, SessionMixin): + """Base class for sessions based on signed cookies. + + This session backend will set the :attr:`modified` and + :attr:`accessed` attributes. It cannot reliably track whether a + session is new (vs. empty), so :attr:`new` remains hard coded to + ``False``. + """ + + #: When data is changed, this is set to ``True``. Only the session + #: dictionary itself is tracked; if the session contains mutable + #: data (for example a nested dict) then this must be set to + #: ``True`` manually when modifying that data. The session cookie + #: will only be written to the response if this is ``True``. + modified = False + + #: When data is read or written, this is set to ``True``. Used by + # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie`` + #: header, which allows caching proxies to cache different pages for + #: different users. + accessed = False + + def __init__(self, initial: t.Any = None) -> None: + def on_update(self) -> None: + self.modified = True + self.accessed = True + + super().__init__(initial, on_update) + + def __getitem__(self, key: str) -> t.Any: + self.accessed = True + return super().__getitem__(key) + + def get(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().get(key, default) + + def setdefault(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().setdefault(key, default) + + +class NullSession(SecureCookieSession): + """Class used to generate nicer error messages if sessions are not + available. Will still allow read-only access to the empty session + but fail on setting. + """ + + def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + raise RuntimeError( + "The session is unavailable because no secret " + "key was set. Set the secret_key on the " + "application to something unique and secret." + ) + + __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # type: ignore # noqa: B950 + del _fail + + +class SessionInterface: + """The basic interface you have to implement in order to replace the + default session interface which uses werkzeug's securecookie + implementation. The only methods you have to implement are + :meth:`open_session` and :meth:`save_session`, the others have + useful defaults which you don't need to change. + + The session object returned by the :meth:`open_session` method has to + provide a dictionary like interface plus the properties and methods + from the :class:`SessionMixin`. We recommend just subclassing a dict + and adding that mixin:: + + class Session(dict, SessionMixin): + pass + + If :meth:`open_session` returns ``None`` Flask will call into + :meth:`make_null_session` to create a session that acts as replacement + if the session support cannot work because some requirement is not + fulfilled. The default :class:`NullSession` class that is created + will complain that the secret key was not set. + + To replace the session interface on an application all you have to do + is to assign :attr:`flask.Flask.session_interface`:: + + app = Flask(__name__) + app.session_interface = MySessionInterface() + + Multiple requests with the same session may be sent and handled + concurrently. When implementing a new session interface, consider + whether reads or writes to the backing store must be synchronized. + There is no guarantee on the order in which the session for each + request is opened or saved, it will occur in the order that requests + begin and end processing. + + .. versionadded:: 0.8 + """ + + #: :meth:`make_null_session` will look here for the class that should + #: be created when a null session is requested. Likewise the + #: :meth:`is_null_session` method will perform a typecheck against + #: this type. + null_session_class = NullSession + + #: A flag that indicates if the session interface is pickle based. + #: This can be used by Flask extensions to make a decision in regards + #: to how to deal with the session object. + #: + #: .. versionadded:: 0.10 + pickle_based = False + + def make_null_session(self, app: Flask) -> NullSession: + """Creates a null session which acts as a replacement object if the + real session support could not be loaded due to a configuration + error. This mainly aids the user experience because the job of the + null session is to still support lookup without complaining but + modifications are answered with a helpful error message of what + failed. + + This creates an instance of :attr:`null_session_class` by default. + """ + return self.null_session_class() + + def is_null_session(self, obj: object) -> bool: + """Checks if a given object is a null session. Null sessions are + not asked to be saved. + + This checks if the object is an instance of :attr:`null_session_class` + by default. + """ + return isinstance(obj, self.null_session_class) + + def get_cookie_name(self, app: Flask) -> str: + """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``.""" + return app.config["SESSION_COOKIE_NAME"] + + def get_cookie_domain(self, app: Flask) -> str | None: + """The value of the ``Domain`` parameter on the session cookie. If not set, + browsers will only send the cookie to the exact domain it was set from. + Otherwise, they will send it to any subdomain of the given value as well. + + Uses the :data:`SESSION_COOKIE_DOMAIN` config. + + .. versionchanged:: 2.3 + Not set by default, does not fall back to ``SERVER_NAME``. + """ + rv = app.config["SESSION_COOKIE_DOMAIN"] + return rv if rv else None + + def get_cookie_path(self, app: Flask) -> str: + """Returns the path for which the cookie should be valid. The + default implementation uses the value from the ``SESSION_COOKIE_PATH`` + config var if it's set, and falls back to ``APPLICATION_ROOT`` or + uses ``/`` if it's ``None``. + """ + return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"] + + def get_cookie_httponly(self, app: Flask) -> bool: + """Returns True if the session cookie should be httponly. This + currently just returns the value of the ``SESSION_COOKIE_HTTPONLY`` + config var. + """ + return app.config["SESSION_COOKIE_HTTPONLY"] + + def get_cookie_secure(self, app: Flask) -> bool: + """Returns True if the cookie should be secure. This currently + just returns the value of the ``SESSION_COOKIE_SECURE`` setting. + """ + return app.config["SESSION_COOKIE_SECURE"] + + def get_cookie_samesite(self, app: Flask) -> str: + """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the + ``SameSite`` attribute. This currently just returns the value of + the :data:`SESSION_COOKIE_SAMESITE` setting. + """ + return app.config["SESSION_COOKIE_SAMESITE"] + + def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None: + """A helper method that returns an expiration date for the session + or ``None`` if the session is linked to the browser session. The + default implementation returns now + the permanent session + lifetime configured on the application. + """ + if session.permanent: + return datetime.now(timezone.utc) + app.permanent_session_lifetime + return None + + def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool: + """Used by session backends to determine if a ``Set-Cookie`` header + should be set for this session cookie for this response. If the session + has been modified, the cookie is set. If the session is permanent and + the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is + always set. + + This check is usually skipped if the session was deleted. + + .. versionadded:: 0.11 + """ + + return session.modified or ( + session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"] + ) + + def open_session(self, app: Flask, request: Request) -> SessionMixin | None: + """This is called at the beginning of each request, after + pushing the request context, before matching the URL. + + This must return an object which implements a dictionary-like + interface as well as the :class:`SessionMixin` interface. + + This will return ``None`` to indicate that loading failed in + some way that is not immediately an error. The request + context will fall back to using :meth:`make_null_session` + in this case. + """ + raise NotImplementedError() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + """This is called at the end of each request, after generating + a response, before removing the request context. It is skipped + if :meth:`is_null_session` returns ``True``. + """ + raise NotImplementedError() + + +session_json_serializer = TaggedJSONSerializer() + + +class SecureCookieSessionInterface(SessionInterface): + """The default session interface that stores sessions in signed cookies + through the :mod:`itsdangerous` module. + """ + + #: the salt that should be applied on top of the secret key for the + #: signing of cookie based sessions. + salt = "cookie-session" + #: the hash function to use for the signature. The default is sha1 + digest_method = staticmethod(hashlib.sha1) + #: the name of the itsdangerous supported key derivation. The default + #: is hmac. + key_derivation = "hmac" + #: A python serializer for the payload. The default is a compact + #: JSON derived serializer with support for some extra Python types + #: such as datetime objects or tuples. + serializer = session_json_serializer + session_class = SecureCookieSession + + def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: + if not app.secret_key: + return None + signer_kwargs = dict( + key_derivation=self.key_derivation, digest_method=self.digest_method + ) + return URLSafeTimedSerializer( + app.secret_key, + salt=self.salt, + serializer=self.serializer, + signer_kwargs=signer_kwargs, + ) + + def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: + s = self.get_signing_serializer(app) + if s is None: + return None + val = request.cookies.get(self.get_cookie_name(app)) + if not val: + return self.session_class() + max_age = int(app.permanent_session_lifetime.total_seconds()) + try: + data = s.loads(val, max_age=max_age) + return self.session_class(data) + except BadSignature: + return self.session_class() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + name = self.get_cookie_name(app) + domain = self.get_cookie_domain(app) + path = self.get_cookie_path(app) + secure = self.get_cookie_secure(app) + samesite = self.get_cookie_samesite(app) + httponly = self.get_cookie_httponly(app) + + # Add a "Vary: Cookie" header if the session was accessed at all. + if session.accessed: + response.vary.add("Cookie") + + # If the session is modified to be empty, remove the cookie. + # If the session is empty, return without setting the cookie. + if not session: + if session.modified: + response.delete_cookie( + name, + domain=domain, + path=path, + secure=secure, + samesite=samesite, + httponly=httponly, + ) + response.vary.add("Cookie") + + return + + if not self.should_set_cookie(app, session): + return + + expires = self.get_expiration_time(app, session) + val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore + response.set_cookie( + name, + val, # type: ignore + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + samesite=samesite, + ) + response.vary.add("Cookie") diff --git a/.venv/Lib/site-packages/flask/signals.py b/.venv/Lib/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/.venv/Lib/site-packages/flask/signals.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from blinker import Namespace + +# This namespace is only for signals provided by Flask itself. +_signals = Namespace() + +template_rendered = _signals.signal("template-rendered") +before_render_template = _signals.signal("before-render-template") +request_started = _signals.signal("request-started") +request_finished = _signals.signal("request-finished") +request_tearing_down = _signals.signal("request-tearing-down") +got_request_exception = _signals.signal("got-request-exception") +appcontext_tearing_down = _signals.signal("appcontext-tearing-down") +appcontext_pushed = _signals.signal("appcontext-pushed") +appcontext_popped = _signals.signal("appcontext-popped") +message_flashed = _signals.signal("message-flashed") diff --git a/.venv/Lib/site-packages/flask/templating.py b/.venv/Lib/site-packages/flask/templating.py new file mode 100644 index 0000000..8dff8ba --- /dev/null +++ b/.venv/Lib/site-packages/flask/templating.py @@ -0,0 +1,221 @@ +from __future__ import annotations + +import typing as t + +from jinja2 import BaseLoader +from jinja2 import Environment as BaseEnvironment +from jinja2 import Template +from jinja2 import TemplateNotFound + +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .helpers import stream_with_context +from .signals import before_render_template +from .signals import template_rendered + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sansio.app import App + from .sansio.scaffold import Scaffold + + +def _default_template_ctx_processor() -> dict[str, t.Any]: + """Default template context processor. Injects `request`, + `session` and `g`. + """ + appctx = _cv_app.get(None) + reqctx = _cv_request.get(None) + rv: dict[str, t.Any] = {} + if appctx is not None: + rv["g"] = appctx.g + if reqctx is not None: + rv["request"] = reqctx.request + rv["session"] = reqctx.session + return rv + + +class Environment(BaseEnvironment): + """Works like a regular Jinja2 environment but has some additional + knowledge of how Flask's blueprint works so that it can prepend the + name of the blueprint to referenced templates if necessary. + """ + + def __init__(self, app: App, **options: t.Any) -> None: + if "loader" not in options: + options["loader"] = app.create_global_jinja_loader() + BaseEnvironment.__init__(self, **options) + self.app = app + + +class DispatchingJinjaLoader(BaseLoader): + """A loader that looks for templates in the application and all + the blueprint folders. + """ + + def __init__(self, app: App) -> None: + self.app = app + + def get_source( # type: ignore + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + if self.app.config["EXPLAIN_TEMPLATE_LOADING"]: + return self._get_source_explained(environment, template) + return self._get_source_fast(environment, template) + + def _get_source_explained( + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + attempts = [] + rv: tuple[str, str | None, t.Callable[[], bool] | None] | None + trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None + + for srcobj, loader in self._iter_loaders(template): + try: + rv = loader.get_source(environment, template) + if trv is None: + trv = rv + except TemplateNotFound: + rv = None + attempts.append((loader, srcobj, rv)) + + from .debughelpers import explain_template_loading_attempts + + explain_template_loading_attempts(self.app, template, attempts) + + if trv is not None: + return trv + raise TemplateNotFound(template) + + def _get_source_fast( + self, environment: Environment, template: str + ) -> tuple[str, str | None, t.Callable | None]: + for _srcobj, loader in self._iter_loaders(template): + try: + return loader.get_source(environment, template) + except TemplateNotFound: + continue + raise TemplateNotFound(template) + + def _iter_loaders( + self, template: str + ) -> t.Generator[tuple[Scaffold, BaseLoader], None, None]: + loader = self.app.jinja_loader + if loader is not None: + yield self.app, loader + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + yield blueprint, loader + + def list_templates(self) -> list[str]: + result = set() + loader = self.app.jinja_loader + if loader is not None: + result.update(loader.list_templates()) + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + for template in loader.list_templates(): + result.add(template) + + return list(result) + + +def _render(app: Flask, template: Template, context: dict[str, t.Any]) -> str: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + rv = template.render(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + return rv + + +def render_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> str: + """Render a template by name with the given context. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _render(app, template, context) + + +def render_template_string(source: str, **context: t.Any) -> str: + """Render a template from the given source string with the given + context. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _render(app, template, context) + + +def _stream( + app: Flask, template: Template, context: dict[str, t.Any] +) -> t.Iterator[str]: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + def generate() -> t.Iterator[str]: + yield from template.generate(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + rv = generate() + + # If a request context is active, keep it while generating. + if request: + rv = stream_with_context(rv) + + return rv + + +def stream_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> t.Iterator[str]: + """Render a template by name with the given context as a stream. + This returns an iterator of strings, which can be used as a + streaming response from a view. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _stream(app, template, context) + + +def stream_template_string(source: str, **context: t.Any) -> t.Iterator[str]: + """Render a template from the given source string with the given + context as a stream. This returns an iterator of strings, which can + be used as a streaming response from a view. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _stream(app, template, context) diff --git a/.venv/Lib/site-packages/flask/testing.py b/.venv/Lib/site-packages/flask/testing.py new file mode 100644 index 0000000..69aa785 --- /dev/null +++ b/.venv/Lib/site-packages/flask/testing.py @@ -0,0 +1,295 @@ +from __future__ import annotations + +import importlib.metadata +import typing as t +from contextlib import contextmanager +from contextlib import ExitStack +from copy import copy +from types import TracebackType +from urllib.parse import urlsplit + +import werkzeug.test +from click.testing import CliRunner +from werkzeug.test import Client +from werkzeug.wrappers import Request as BaseRequest + +from .cli import ScriptInfo +from .sessions import SessionMixin + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.test import TestResponse + + from .app import Flask + + +class EnvironBuilder(werkzeug.test.EnvironBuilder): + """An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the + application. + + :param app: The Flask application to configure the environment from. + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + + def __init__( + self, + app: Flask, + path: str = "/", + base_url: str | None = None, + subdomain: str | None = None, + url_scheme: str | None = None, + *args: t.Any, + **kwargs: t.Any, + ) -> None: + assert not (base_url or subdomain or url_scheme) or ( + base_url is not None + ) != bool( + subdomain or url_scheme + ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + + if base_url is None: + http_host = app.config.get("SERVER_NAME") or "localhost" + app_root = app.config["APPLICATION_ROOT"] + + if subdomain: + http_host = f"{subdomain}.{http_host}" + + if url_scheme is None: + url_scheme = app.config["PREFERRED_URL_SCHEME"] + + url = urlsplit(path) + base_url = ( + f"{url.scheme or url_scheme}://{url.netloc or http_host}" + f"/{app_root.lstrip('/')}" + ) + path = url.path + + if url.query: + sep = b"?" if isinstance(url.query, bytes) else "?" + path += sep + url.query + + self.app = app + super().__init__(path, base_url, *args, **kwargs) + + def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str: # type: ignore + """Serialize ``obj`` to a JSON-formatted string. + + The serialization will be configured according to the config associated + with this EnvironBuilder's ``app``. + """ + return self.app.json.dumps(obj, **kwargs) + + +_werkzeug_version = "" + + +def _get_werkzeug_version() -> str: + global _werkzeug_version + + if not _werkzeug_version: + _werkzeug_version = importlib.metadata.version("werkzeug") + + return _werkzeug_version + + +class FlaskClient(Client): + """Works like a regular Werkzeug test client but has knowledge about + Flask's contexts to defer the cleanup of the request context until + the end of a ``with`` block. For general information about how to + use this class refer to :class:`werkzeug.test.Client`. + + .. versionchanged:: 0.12 + `app.test_client()` includes preset default environment, which can be + set after instantiation of the `app.test_client()` object in + `client.environ_base`. + + Basic usage is outlined in the :doc:`/testing` chapter. + """ + + application: Flask + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + super().__init__(*args, **kwargs) + self.preserve_context = False + self._new_contexts: list[t.ContextManager[t.Any]] = [] + self._context_stack = ExitStack() + self.environ_base = { + "REMOTE_ADDR": "127.0.0.1", + "HTTP_USER_AGENT": f"Werkzeug/{_get_werkzeug_version()}", + } + + @contextmanager + def session_transaction( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Generator[SessionMixin, None, None]: + """When used in combination with a ``with`` statement this opens a + session transaction. This can be used to modify the session that + the test client uses. Once the ``with`` block is left the session is + stored back. + + :: + + with client.session_transaction() as session: + session['value'] = 42 + + Internally this is implemented by going through a temporary test + request context and since session handling could depend on + request variables this function accepts the same arguments as + :meth:`~flask.Flask.test_request_context` which are directly + passed through. + """ + if self._cookies is None: + raise TypeError( + "Cookies are disabled. Create a client with 'use_cookies=True'." + ) + + app = self.application + ctx = app.test_request_context(*args, **kwargs) + self._add_cookies_to_wsgi(ctx.request.environ) + + with ctx: + sess = app.session_interface.open_session(app, ctx.request) + + if sess is None: + raise RuntimeError("Session backend did not open a session.") + + yield sess + resp = app.response_class() + + if app.session_interface.is_null_session(sess): + return + + with ctx: + app.session_interface.save_session(app, sess, resp) + + self._update_cookies_from_response( + ctx.request.host.partition(":")[0], + ctx.request.path, + resp.headers.getlist("Set-Cookie"), + ) + + def _copy_environ(self, other): + out = {**self.environ_base, **other} + + if self.preserve_context: + out["werkzeug.debug.preserve_context"] = self._new_contexts.append + + return out + + def _request_from_builder_args(self, args, kwargs): + kwargs["environ_base"] = self._copy_environ(kwargs.get("environ_base", {})) + builder = EnvironBuilder(self.application, *args, **kwargs) + + try: + return builder.get_request() + finally: + builder.close() + + def open( + self, + *args: t.Any, + buffered: bool = False, + follow_redirects: bool = False, + **kwargs: t.Any, + ) -> TestResponse: + if args and isinstance( + args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest) + ): + if isinstance(args[0], werkzeug.test.EnvironBuilder): + builder = copy(args[0]) + builder.environ_base = self._copy_environ(builder.environ_base or {}) + request = builder.get_request() + elif isinstance(args[0], dict): + request = EnvironBuilder.from_environ( + args[0], app=self.application, environ_base=self._copy_environ({}) + ).get_request() + else: + # isinstance(args[0], BaseRequest) + request = copy(args[0]) + request.environ = self._copy_environ(request.environ) + else: + # request is None + request = self._request_from_builder_args(args, kwargs) + + # Pop any previously preserved contexts. This prevents contexts + # from being preserved across redirects or multiple requests + # within a single block. + self._context_stack.close() + + response = super().open( + request, + buffered=buffered, + follow_redirects=follow_redirects, + ) + response.json_module = self.application.json # type: ignore[assignment] + + # Re-push contexts that were preserved during the request. + while self._new_contexts: + cm = self._new_contexts.pop() + self._context_stack.enter_context(cm) + + return response + + def __enter__(self) -> FlaskClient: + if self.preserve_context: + raise RuntimeError("Cannot nest client invocations") + self.preserve_context = True + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.preserve_context = False + self._context_stack.close() + + +class FlaskCliRunner(CliRunner): + """A :class:`~click.testing.CliRunner` for testing a Flask app's + CLI commands. Typically created using + :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`. + """ + + def __init__(self, app: Flask, **kwargs: t.Any) -> None: + self.app = app + super().__init__(**kwargs) + + def invoke( # type: ignore + self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any + ) -> t.Any: + """Invokes a CLI command in an isolated environment. See + :meth:`CliRunner.invoke ` for + full method documentation. See :ref:`testing-cli` for examples. + + If the ``obj`` argument is not given, passes an instance of + :class:`~flask.cli.ScriptInfo` that knows how to load the Flask + app being tested. + + :param cli: Command object to invoke. Default is the app's + :attr:`~flask.app.Flask.cli` group. + :param args: List of strings to invoke the command with. + + :return: a :class:`~click.testing.Result` object. + """ + if cli is None: + cli = self.app.cli # type: ignore + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/.venv/Lib/site-packages/flask/typing.py b/.venv/Lib/site-packages/flask/typing.py new file mode 100644 index 0000000..a8c9ba0 --- /dev/null +++ b/.venv/Lib/site-packages/flask/typing.py @@ -0,0 +1,88 @@ +from __future__ import annotations + +import typing as t + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIApplication # noqa: F401 + from werkzeug.datastructures import Headers # noqa: F401 + from werkzeug.sansio.response import Response # noqa: F401 + +# The possible types that are directly convertible or are a Response object. +ResponseValue = t.Union[ + "Response", + str, + bytes, + t.List[t.Any], + # Only dict is actually accepted, but Mapping allows for TypedDict. + t.Mapping[str, t.Any], + t.Iterator[str], + t.Iterator[bytes], +] + +# the possible types for an individual HTTP header +# This should be a Union, but mypy doesn't pass unless it's a TypeVar. +HeaderValue = t.Union[str, t.List[str], t.Tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[t.Tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + t.Tuple[ResponseValue, HeadersValue], + t.Tuple[ResponseValue, int], + t.Tuple[ResponseValue, int, HeadersValue], + "WSGIApplication", +] + +# Allow any subclass of werkzeug.Response, such as the one from Flask, +# as a callback argument. Using werkzeug.Response directly makes a +# callback annotated with flask.Response fail type checking. +ResponseClass = t.TypeVar("ResponseClass", bound="Response") + +AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named +AfterRequestCallable = t.Union[ + t.Callable[[ResponseClass], ResponseClass], + t.Callable[[ResponseClass], t.Awaitable[ResponseClass]], +] +BeforeFirstRequestCallable = t.Union[ + t.Callable[[], None], t.Callable[[], t.Awaitable[None]] +] +BeforeRequestCallable = t.Union[ + t.Callable[[], t.Optional[ResponseReturnValue]], + t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]], +] +ShellContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]] +TeardownCallable = t.Union[ + t.Callable[[t.Optional[BaseException]], None], + t.Callable[[t.Optional[BaseException]], t.Awaitable[None]], +] +TemplateContextProcessorCallable = t.Union[ + t.Callable[[], t.Dict[str, t.Any]], + t.Callable[[], t.Awaitable[t.Dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, dict], None] +URLValuePreprocessorCallable = t.Callable[[t.Optional[str], t.Optional[dict]], None] + +# This should take Exception, but that either breaks typing the argument +# with a specific exception, or decorating multiple times with different +# exceptions (and using a union type on the argument). +# https://github.com/pallets/flask/issues/4095 +# https://github.com/pallets/flask/issues/4295 +# https://github.com/pallets/flask/issues/4297 +ErrorHandlerCallable = t.Union[ + t.Callable[[t.Any], ResponseReturnValue], + t.Callable[[t.Any], t.Awaitable[ResponseReturnValue]], +] + +RouteCallable = t.Union[ + t.Callable[..., ResponseReturnValue], + t.Callable[..., t.Awaitable[ResponseReturnValue]], +] diff --git a/.venv/Lib/site-packages/flask/views.py b/.venv/Lib/site-packages/flask/views.py new file mode 100644 index 0000000..c7a2b62 --- /dev/null +++ b/.venv/Lib/site-packages/flask/views.py @@ -0,0 +1,190 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + + +http_method_funcs = frozenset( + ["get", "post", "head", "options", "delete", "put", "trace", "patch"] +) + + +class View: + """Subclass this class and override :meth:`dispatch_request` to + create a generic class-based view. Call :meth:`as_view` to create a + view function that creates an instance of the class with the given + arguments and calls its ``dispatch_request`` method with any URL + variables. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class Hello(View): + init_every_request = False + + def dispatch_request(self, name): + return f"Hello, {name}!" + + app.add_url_rule( + "/hello/", view_func=Hello.as_view("hello") + ) + + Set :attr:`methods` on the class to change what methods the view + accepts. + + Set :attr:`decorators` on the class to apply a list of decorators to + the generated view function. Decorators applied to the class itself + will not be applied to the generated view function! + + Set :attr:`init_every_request` to ``False`` for efficiency, unless + you need to store request-global data on ``self``. + """ + + #: The methods this view is registered for. Uses the same default + #: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and + #: ``add_url_rule`` by default. + methods: t.ClassVar[t.Collection[str] | None] = None + + #: Control whether the ``OPTIONS`` method is handled automatically. + #: Uses the same default (``True``) as ``route`` and + #: ``add_url_rule`` by default. + provide_automatic_options: t.ClassVar[bool | None] = None + + #: A list of decorators to apply, in order, to the generated view + #: function. Remember that ``@decorator`` syntax is applied bottom + #: to top, so the first decorator in the list would be the bottom + #: decorator. + #: + #: .. versionadded:: 0.8 + decorators: t.ClassVar[list[t.Callable]] = [] + + #: Create a new instance of this view class for every request by + #: default. If a view subclass sets this to ``False``, the same + #: instance is used for every request. + #: + #: A single instance is more efficient, especially if complex setup + #: is done during init. However, storing data on ``self`` is no + #: longer safe across requests, and :data:`~flask.g` should be used + #: instead. + #: + #: .. versionadded:: 2.2 + init_every_request: t.ClassVar[bool] = True + + def dispatch_request(self) -> ft.ResponseReturnValue: + """The actual view function behavior. Subclasses must override + this and return a valid response. Any variables from the URL + rule are passed as keyword arguments. + """ + raise NotImplementedError() + + @classmethod + def as_view( + cls, name: str, *class_args: t.Any, **class_kwargs: t.Any + ) -> ft.RouteCallable: + """Convert the class into a view function that can be registered + for a route. + + By default, the generated view will create a new instance of the + view class for every request and call its + :meth:`dispatch_request` method. If the view class sets + :attr:`init_every_request` to ``False``, the same instance will + be used for every request. + + Except for ``name``, all other arguments passed to this method + are forwarded to the view class ``__init__`` method. + + .. versionchanged:: 2.2 + Added the ``init_every_request`` class attribute. + """ + if cls.init_every_request: + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + self = view.view_class( # type: ignore[attr-defined] + *class_args, **class_kwargs + ) + return current_app.ensure_sync(self.dispatch_request)(**kwargs) + + else: + self = cls(*class_args, **class_kwargs) + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) + + if cls.decorators: + view.__name__ = name + view.__module__ = cls.__module__ + for decorator in cls.decorators: + view = decorator(view) + + # We attach the view class to the view function for two reasons: + # first of all it allows us to easily figure out what class-based + # view this thing came from, secondly it's also used for instantiating + # the view class so you can actually replace it with something else + # for testing purposes and debugging. + view.view_class = cls # type: ignore + view.__name__ = name + view.__doc__ = cls.__doc__ + view.__module__ = cls.__module__ + view.methods = cls.methods # type: ignore + view.provide_automatic_options = cls.provide_automatic_options # type: ignore + return view + + +class MethodView(View): + """Dispatches request methods to the corresponding instance methods. + For example, if you implement a ``get`` method, it will be used to + handle ``GET`` requests. + + This can be useful for defining a REST API. + + :attr:`methods` is automatically set based on the methods defined on + the class. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class CounterAPI(MethodView): + def get(self): + return str(session.get("counter", 0)) + + def post(self): + session["counter"] = session.get("counter", 0) + 1 + return redirect(url_for("counter")) + + app.add_url_rule( + "/counter", view_func=CounterAPI.as_view("counter") + ) + """ + + def __init_subclass__(cls, **kwargs: t.Any) -> None: + super().__init_subclass__(**kwargs) + + if "methods" not in cls.__dict__: + methods = set() + + for base in cls.__bases__: + if getattr(base, "methods", None): + methods.update(base.methods) # type: ignore[attr-defined] + + for key in http_method_funcs: + if hasattr(cls, key): + methods.add(key.upper()) + + if methods: + cls.methods = methods + + def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue: + meth = getattr(self, request.method.lower(), None) + + # If the request method is HEAD and we don't have a handler for it + # retry with GET. + if meth is None and request.method == "HEAD": + meth = getattr(self, "get", None) + + assert meth is not None, f"Unimplemented method {request.method!r}" + return current_app.ensure_sync(meth)(**kwargs) diff --git a/.venv/Lib/site-packages/flask/wrappers.py b/.venv/Lib/site-packages/flask/wrappers.py new file mode 100644 index 0000000..ef7aa38 --- /dev/null +++ b/.venv/Lib/site-packages/flask/wrappers.py @@ -0,0 +1,173 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.wrappers import Request as RequestBase +from werkzeug.wrappers import Response as ResponseBase + +from . import json +from .globals import current_app +from .helpers import _split_blueprint_path + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.routing import Rule + + +class Request(RequestBase): + """The request object used by default in Flask. Remembers the + matched endpoint and view arguments. + + It is what ends up as :class:`~flask.request`. If you want to replace + the request object used you can subclass this and set + :attr:`~flask.Flask.request_class` to your subclass. + + The request object is a :class:`~werkzeug.wrappers.Request` subclass and + provides all of the attributes Werkzeug defines plus a few Flask + specific ones. + """ + + json_module: t.Any = json + + #: The internal URL rule that matched the request. This can be + #: useful to inspect which methods are allowed for the URL from + #: a before/after handler (``request.url_rule.methods``) etc. + #: Though if the request's method was invalid for the URL rule, + #: the valid list is available in ``routing_exception.valid_methods`` + #: instead (an attribute of the Werkzeug exception + #: :exc:`~werkzeug.exceptions.MethodNotAllowed`) + #: because the request was never internally bound. + #: + #: .. versionadded:: 0.6 + url_rule: Rule | None = None + + #: A dict of view arguments that matched the request. If an exception + #: happened when matching, this will be ``None``. + view_args: dict[str, t.Any] | None = None + + #: If matching the URL failed, this is the exception that will be + #: raised / was raised as part of the request handling. This is + #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or + #: something similar. + routing_exception: Exception | None = None + + @property + def max_content_length(self) -> int | None: # type: ignore + """Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" + if current_app: + return current_app.config["MAX_CONTENT_LENGTH"] + else: + return None + + @property + def endpoint(self) -> str | None: + """The endpoint that matched the request URL. + + This will be ``None`` if matching failed or has not been + performed yet. + + This in combination with :attr:`view_args` can be used to + reconstruct the same URL or a modified URL. + """ + if self.url_rule is not None: + return self.url_rule.endpoint + + return None + + @property + def blueprint(self) -> str | None: + """The registered name of the current blueprint. + + This will be ``None`` if the endpoint is not part of a + blueprint, or if URL matching failed or has not been performed + yet. + + This does not necessarily match the name the blueprint was + created with. It may have been nested, or registered with a + different name. + """ + endpoint = self.endpoint + + if endpoint is not None and "." in endpoint: + return endpoint.rpartition(".")[0] + + return None + + @property + def blueprints(self) -> list[str]: + """The registered names of the current blueprint upwards through + parent blueprints. + + This will be an empty list if there is no current blueprint, or + if URL matching failed. + + .. versionadded:: 2.0.1 + """ + name = self.blueprint + + if name is None: + return [] + + return _split_blueprint_path(name) + + def _load_form_data(self) -> None: + super()._load_form_data() + + # In debug mode we're replacing the files multidict with an ad-hoc + # subclass that raises a different error for key errors. + if ( + current_app + and current_app.debug + and self.mimetype != "multipart/form-data" + and not self.files + ): + from .debughelpers import attach_enctype_error_multidict + + attach_enctype_error_multidict(self) + + def on_json_loading_failed(self, e: ValueError | None) -> t.Any: + try: + return super().on_json_loading_failed(e) + except BadRequest as e: + if current_app and current_app.debug: + raise + + raise BadRequest() from e + + +class Response(ResponseBase): + """The response object that is used by default in Flask. Works like the + response object from Werkzeug but is set to have an HTML mimetype by + default. Quite often you don't have to create this object yourself because + :meth:`~flask.Flask.make_response` will take care of that for you. + + If you want to replace the response object used you can subclass this and + set :attr:`~flask.Flask.response_class` to your subclass. + + .. versionchanged:: 1.0 + JSON support is added to the response, like the request. This is useful + when testing to get the test client response data as JSON. + + .. versionchanged:: 1.0 + + Added :attr:`max_cookie_size`. + """ + + default_mimetype: str | None = "text/html" + + json_module = json + + autocorrect_location_header = False + + @property + def max_cookie_size(self) -> int: # type: ignore + """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. + + See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in + Werkzeug's docs. + """ + if current_app: + return current_app.config["MAX_COOKIE_SIZE"] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/.venv/Lib/site-packages/idna-3.4.dist-info/INSTALLER b/.venv/Lib/site-packages/idna-3.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/idna-3.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/idna-3.4.dist-info/LICENSE.md b/.venv/Lib/site-packages/idna-3.4.dist-info/LICENSE.md new file mode 100644 index 0000000..b6f8732 --- /dev/null +++ b/.venv/Lib/site-packages/idna-3.4.dist-info/LICENSE.md @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2013-2021, Kim Davies +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/idna-3.4.dist-info/METADATA b/.venv/Lib/site-packages/idna-3.4.dist-info/METADATA new file mode 100644 index 0000000..07f6193 --- /dev/null +++ b/.venv/Lib/site-packages/idna-3.4.dist-info/METADATA @@ -0,0 +1,242 @@ +Metadata-Version: 2.1 +Name: idna +Version: 3.4 +Summary: Internationalized Domain Names in Applications (IDNA) +Author-email: Kim Davies +Requires-Python: >=3.5 +Description-Content-Type: text/x-rst +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Utilities +Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.rst +Project-URL: Issue tracker, https://github.com/kjd/idna/issues +Project-URL: Source, https://github.com/kjd/idna + +Internationalized Domain Names in Applications (IDNA) +===================================================== + +Support for the Internationalized Domain Names in +Applications (IDNA) protocol as specified in `RFC 5891 +`_. This is the latest version of +the protocol and is sometimes referred to as “IDNA 2008”. + +This library also provides support for Unicode Technical +Standard 46, `Unicode IDNA Compatibility Processing +`_. + +This acts as a suitable replacement for the “encodings.idna” +module that comes with the Python standard library, but which +only supports the older superseded IDNA specification (`RFC 3490 +`_). + +Basic functions are simply executed: + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + + +Installation +------------ + +This package is available for installation from PyPI: + +.. code-block:: bash + + $ python3 -m pip install idna + + +Usage +----- + +For typical usage, the ``encode`` and ``decode`` functions will take a +domain name argument and perform a conversion to A-labels or U-labels +respectively. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('ドメイン.テスト') + b'xn--eckwd4c7c.xn--zckzah' + >>> print(idna.decode('xn--eckwd4c7c.xn--zckzah')) + ドメイン.テスト + +You may use the codec encoding and decoding methods using the +``idna.codec`` module: + +.. code-block:: pycon + + >>> import idna.codec + >>> print('домен.испытание'.encode('idna')) + b'xn--d1acufc.xn--80akhbyknj4f' + >>> print(b'xn--d1acufc.xn--80akhbyknj4f'.decode('idna')) + домен.испытание + +Conversions can be applied at a per-label basis using the ``ulabel`` or +``alabel`` functions if necessary: + +.. code-block:: pycon + + >>> idna.alabel('测试') + b'xn--0zwm56d' + +Compatibility Mapping (UTS #46) ++++++++++++++++++++++++++++++++ + +As described in `RFC 5895 `_, the +IDNA specification does not normalize input from different potential +ways a user may input a domain name. This functionality, known as +a “mapping”, is considered by the specification to be a local +user-interface issue distinct from IDNA conversion functionality. + +This library provides one such mapping, that was developed by the +Unicode Consortium. Known as `Unicode IDNA Compatibility Processing +`_, it provides for both a regular +mapping for typical applications, as well as a transitional mapping to +help migrate from older IDNA 2003 applications. + +For example, “Königsgäßchen” is not a permissible label as *LATIN +CAPITAL LETTER K* is not allowed (nor are capital letters in general). +UTS 46 will convert this into lower case prior to applying the IDNA +conversion. + +.. code-block:: pycon + + >>> import idna + >>> idna.encode('Königsgäßchen') + ... + idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed + >>> idna.encode('Königsgäßchen', uts46=True) + b'xn--knigsgchen-b4a3dun' + >>> print(idna.decode('xn--knigsgchen-b4a3dun')) + königsgäßchen + +Transitional processing provides conversions to help transition from +the older 2003 standard to the current standard. For example, in the +original IDNA specification, the *LATIN SMALL LETTER SHARP S* (ß) was +converted into two *LATIN SMALL LETTER S* (ss), whereas in the current +IDNA specification this conversion is not performed. + +.. code-block:: pycon + + >>> idna.encode('Königsgäßchen', uts46=True, transitional=True) + 'xn--knigsgsschen-lcb0w' + +Implementors should use transitional processing with caution, only in +rare cases where conversion from legacy labels to current labels must be +performed (i.e. IDNA implementations that pre-date 2008). For typical +applications that just need to convert labels, transitional processing +is unlikely to be beneficial and could produce unexpected incompatible +results. + +``encodings.idna`` Compatibility +++++++++++++++++++++++++++++++++ + +Function calls from the Python built-in ``encodings.idna`` module are +mapped to their IDNA 2008 equivalents using the ``idna.compat`` module. +Simply substitute the ``import`` clause in your code to refer to the new +module name. + +Exceptions +---------- + +All errors raised during the conversion following the specification +should raise an exception derived from the ``idna.IDNAError`` base +class. + +More specific exceptions that may be generated as ``idna.IDNABidiError`` +when the error reflects an illegal combination of left-to-right and +right-to-left characters in a label; ``idna.InvalidCodepoint`` when +a specific codepoint is an illegal character in an IDN label (i.e. +INVALID); and ``idna.InvalidCodepointContext`` when the codepoint is +illegal based on its positional context (i.e. it is CONTEXTO or CONTEXTJ +but the contextual requirements are not satisfied.) + +Building and Diagnostics +------------------------ + +The IDNA and UTS 46 functionality relies upon pre-calculated lookup +tables for performance. These tables are derived from computing against +eligibility criteria in the respective standards. These tables are +computed using the command-line script ``tools/idna-data``. + +This tool will fetch relevant codepoint data from the Unicode repository +and perform the required calculations to identify eligibility. There are +three main modes: + +* ``idna-data make-libdata``. Generates ``idnadata.py`` and + ``uts46data.py``, the pre-calculated lookup tables using for IDNA and + UTS 46 conversions. Implementors who wish to track this library against + a different Unicode version may use this tool to manually generate a + different version of the ``idnadata.py`` and ``uts46data.py`` files. + +* ``idna-data make-table``. Generate a table of the IDNA disposition + (e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix + B.1 of RFC 5892 and the pre-computed tables published by `IANA + `_. + +* ``idna-data U+0061``. Prints debugging output on the various + properties associated with an individual Unicode codepoint (in this + case, U+0061), that are used to assess the IDNA and UTS 46 status of a + codepoint. This is helpful in debugging or analysis. + +The tool accepts a number of arguments, described using ``idna-data +-h``. Most notably, the ``--version`` argument allows the specification +of the version of Unicode to use in computing the table data. For +example, ``idna-data --version 9.0.0 make-libdata`` will generate +library data against Unicode 9.0.0. + + +Additional Notes +---------------- + +* **Packages**. The latest tagged release version is published in the + `Python Package Index `_. + +* **Version support**. This library supports Python 3.5 and higher. + As this library serves as a low-level toolkit for a variety of + applications, many of which strive for broad compatibility with older + Python versions, there is no rush to remove older intepreter support. + Removing support for older versions should be well justified in that the + maintenance burden has become too high. + +* **Python 2**. Python 2 is supported by version 2.x of this library. + While active development of the version 2.x series has ended, notable + issues being corrected may be backported to 2.x. Use "idna<3" in your + requirements file if you need this library for a Python 2 application. + +* **Testing**. The library has a test suite based on each rule of the + IDNA specification, as well as tests that are provided as part of the + Unicode Technical Standard 46, `Unicode IDNA Compatibility Processing + `_. + +* **Emoji**. It is an occasional request to support emoji domains in + this library. Encoding of symbols like emoji is expressly prohibited by + the technical standard IDNA 2008 and emoji domains are broadly phased + out across the domain industry due to associated security risks. For + now, applications that wish need to support these non-compliant labels + may wish to consider trying the encode/decode operation in this library + first, and then falling back to using `encodings.idna`. See `the Github + project `_ for more discussion. + diff --git a/.venv/Lib/site-packages/idna-3.4.dist-info/RECORD b/.venv/Lib/site-packages/idna-3.4.dist-info/RECORD new file mode 100644 index 0000000..b94b726 --- /dev/null +++ b/.venv/Lib/site-packages/idna-3.4.dist-info/RECORD @@ -0,0 +1,22 @@ +idna-3.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +idna-3.4.dist-info/LICENSE.md,sha256=otbk2UC9JNvnuWRc3hmpeSzFHbeuDVrNMBrIYMqj6DY,1523 +idna-3.4.dist-info/METADATA,sha256=8aLSf9MFS7oB26pZh2hprg7eJp0UJSc-3rpf_evp4DA,9830 +idna-3.4.dist-info/RECORD,, +idna-3.4.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81 +idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849 +idna/__pycache__/__init__.cpython-310.pyc,, +idna/__pycache__/codec.cpython-310.pyc,, +idna/__pycache__/compat.cpython-310.pyc,, +idna/__pycache__/core.cpython-310.pyc,, +idna/__pycache__/idnadata.cpython-310.pyc,, +idna/__pycache__/intranges.cpython-310.pyc,, +idna/__pycache__/package_data.cpython-310.pyc,, +idna/__pycache__/uts46data.cpython-310.pyc,, +idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374 +idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321 +idna/core.py,sha256=1JxchwKzkxBSn7R_oCE12oBu3eVux0VzdxolmIad24M,12950 +idna/idnadata.py,sha256=xUjqKqiJV8Ho_XzBpAtv5JFoVPSupK-SUXvtjygUHqw,44375 +idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881 +idna/package_data.py,sha256=C_jHJzmX8PI4xq0jpzmcTMxpb5lDsq4o5VyxQzlVrZE,21 +idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +idna/uts46data.py,sha256=zvjZU24s58_uAS850Mcd0NnD0X7_gCMAMjzWNIeUJdc,206539 diff --git a/.venv/Lib/site-packages/idna-3.4.dist-info/WHEEL b/.venv/Lib/site-packages/idna-3.4.dist-info/WHEEL new file mode 100644 index 0000000..668ba4d --- /dev/null +++ b/.venv/Lib/site-packages/idna-3.4.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.7.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/idna/__init__.py b/.venv/Lib/site-packages/idna/__init__.py new file mode 100644 index 0000000..a40eeaf --- /dev/null +++ b/.venv/Lib/site-packages/idna/__init__.py @@ -0,0 +1,44 @@ +from .package_data import __version__ +from .core import ( + IDNABidiError, + IDNAError, + InvalidCodepoint, + InvalidCodepointContext, + alabel, + check_bidi, + check_hyphen_ok, + check_initial_combiner, + check_label, + check_nfc, + decode, + encode, + ulabel, + uts46_remap, + valid_contextj, + valid_contexto, + valid_label_length, + valid_string_length, +) +from .intranges import intranges_contain + +__all__ = [ + "IDNABidiError", + "IDNAError", + "InvalidCodepoint", + "InvalidCodepointContext", + "alabel", + "check_bidi", + "check_hyphen_ok", + "check_initial_combiner", + "check_label", + "check_nfc", + "decode", + "encode", + "intranges_contain", + "ulabel", + "uts46_remap", + "valid_contextj", + "valid_contexto", + "valid_label_length", + "valid_string_length", +] diff --git a/.venv/Lib/site-packages/idna/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/idna/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..84508f5b822912fa73e514c6c9949bcdc4afcaec GIT binary patch literal 825 zcmbu7&5qMB5P*~Zq)n6bf4hh`=z&Em&>j#%EQLcQv;wWTSdlC@HmzyKj-0g6C*VD} z@k+jO;uSdINmdB$feV)WWo8`Dk7sm}3_Q2|ub1L|+w*>)^7m>v<)zzY<-k4e=N|aP z_fc-;EohTAbVvufqzeHFphtSpCw&M>2m>;Jh(r*R7!s1ekPKl&MldF0n2-rf$rNT} z26Hm6{k8KmSdfM9Z9U%k=96>Yz4eyCPv3=J`Zl8UC`>7}qI5a6$@=xp^()Ec8)LMw zA*ziyUaKR^C0}VS3N2M-&+l7ST2NHk8m6|QtlcrGmNVm;>6s3qiwF=sL?00%u=6HD z#E1kjM4TZ;h%sVx!fsG56?b%jP&MIbbP;4jDM*LUke@3<8pGxZ-ZI4ox z=ahc;%tK5K@oT+$mVPMRq@<LDk3f%nGQIB8N4W6kr-@7eQa-ut~b{aUSTU}Ha@ zlg*l8JfX?nX5(ZId-6L9VF(r(J?68X>6<;vw|d;?J=?dLAxvRKj_>HV>$~{ok=HBv zrC!-DGef!?6=82Ozxt&i9N|7Tge#qu+PdY}5b;C_krERmr78OJ)h)f`I1d*z! zAyShy#OmwZuOl`l#t|FW*d$_;Vgj{OT~izp^~c;lDy&;ZWAZ7(?Kf=Y$hgxNQaM8A z?;r}6WTc#7{x02ESiE{2pbt;+2V=2eD*Kz^Ad<@aYLJHgIEaQ-RD9Qb^3$VdfBgFF z&&@j>`f_h8;babbaubC#d?pOv#PgWa5*BtYxwNIzHBT5_N7%x7Y@@$OZ|~}@UA-$j z)T4j!92I5H?BLc60zV~%|u`*ssWW(s!Kf=Y@Z z+hCcw$=2B;ma$}gZT!pt7e#}EgD>TD`_KzgFlk~%GTyQjPh`{u@*yDKj4cC>;p_Pq^Ost;6A4Kx ziTe*kYyQ^x3+Gz%Lja7}>ea!Z)x0m``>mVdQY#5l`Q9Mt+zpmx(h5Z!yidXGGzY8N z6ft_6gvZ7hH#wUyA6B*BntAwN>L3`$zeY!f37l-1YTucljv$azVUolY2|7V8j?;*= zTKNhNMwWBJEjE~TXQQONb~_GwvfWnYcDvUX!-&S!cKhBih;}p>D+*NhL+I@i!d&7aKQ_iJNQ<_p)YZ z9L{E3*e8r+RyZ^l_GKe3Wmcl`%LaWxnq^}ROU#;^@de|~(KRn~Hh5}h-a4+ujLe0( z4AbhOfnT_(LpY7^ofFQ6n>m{-vyU5VC9Sh_U4}Ethpkec51Jfs0#5)ZQ9S({n_^8( zf6&Fo(>b8|q9)qII3$j?ML$j2AeEgAqA*oXFc`>K0QpE0O7WF`7;lx~C?UIP0&n0{ zIl4$Cs+vL&Qs&Wel=aCl!dj4o4{>4rjbF~eHW8>`2@yn%wU>t7u7q};46h-Ue1Kw< zEoICY&b*!O=ow{^)@wOtRq_3B<{$-{``2Dp^nUyn-5p}vOmv@NP3xvMYi-(}(Ik5O@% zlpm3x*#S2bujjCD6EBO3f%U*t)mtgZp!Y3cafZb$>&3Vijwwujg3EkQ>*dkq3ECu|~scmkvmm7dK7j;A8GQ&R?*A zaO0Tboj&Y2PF|EW$>}PAYbcb7waZCY2UvV^QjznN+v)cPVI=bmq1~#J*L0DQ;$V@` x`#^oo9Rl#lPmbQ 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-310.pyc b/.venv/Lib/site-packages/idna/__pycache__/idnadata.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd1e1d9b725d28ead00a457b80c0c710fc0baed1 GIT binary patch literal 38361 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 rv#wuKi=%;2i~raEXaCf;%bMu<&gkgyIp6L zS`{J@d1kCA`ywl>8Ypd6#4wRcj4EO-@06A5kMev!f~XlLc`l04a9e3Q&C6mS^r$c$ z5NTN$m5waTeqbvthtfhFne%Ls;@@MI8!(G5+mM-WAmM?aL1+223e8h?t+hRA|_$8p%OnX z=jCAemWw-zx}8Jd!=6W89XvxO>hR^L%2gdwTH?B;l^yA#n<8VUgP;ZEY#r15iN&%p zJKz&OU=vUBiEp{}#{2-kr|g&2NiYtica=4~U8Zl3`8Zf&v=SfCdy8z>)3;yEf#(yi zIr$yXPQtPG&bPrhlsebbO(7(>_^FVR!%BOBw7jeCP{6+ z52?~9pme6^Fpo2__7Lnff*u6wL6{OSW!;W5_QHkNm@3jzDoIx`Sux1Z>g>2+#M+v; zcUO$b7D6maOR|;#HC<=z@Cf6Oz|^!vt-57OZI!G;mxtQVRZ+K+s)C7nHb#=*GH%X7 zXDMpw0IKzLqZm`6piW$vbtg|yHhVg=s^(cen~t^cajeB3O_ST(fy8lg8^}1-y*S%-icF(}lmsOJPCIG3I$s+j*>217qtNr@YDHZp1 zIdsuX!-=_qrQHsAz~}K>Fir;TX}aQ`!Dft?>k*3e zTZRJjo*xSE+&v;slM{XQgyFb)fk;vmn1)Qva7Wi%f7C_ zc#RD;v*ZWf#IyVz+IZ}}_a;8tlJ5rkw)LA9T}0a+@SZmb(4fH>CVaNb_2=V|8eIAt z49!Vxi$?&Q`;FeIPK$KV^7lzn2DoeZ>%*tYDm}~!)OBBMQMg;8j~Ca_ds>PT2gk2w zgFiiKTg`T>>*`t4ZC-vCg-ya++Zmo@TTeINI9Gk^lA-CpE1J^R@o_1sTdua_+OJAe z2PBA&$Ob#M=JBVAzHnA^c=T@-_cv@E==s@%;b* literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/idna/__pycache__/package_data.cpython-310.pyc b/.venv/Lib/site-packages/idna/__pycache__/package_data.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..00ac2b1f33b698a45c12f26c703291ddb64f2bdf GIT binary patch literal 189 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 A8RXOc&_nLP9en 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/idna/codec.py b/.venv/Lib/site-packages/idna/codec.py new file mode 100644 index 0000000..1ca9ba6 --- /dev/null +++ b/.venv/Lib/site-packages/idna/codec.py @@ -0,0 +1,112 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re +from typing import Tuple, Optional + +_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)) + + 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)) + + if not data: + 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)) + + if not data: + return "", 0 + + labels = _unicode_dots_re.split(data) + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result_str = '.'.join(result) + trailing_dot # type: ignore + size += len(trailing_dot) + return result_str, 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)) + + if not data: + return ('', 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = '' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result_str = '.'.join(result) + trailing_dot + size += len(trailing_dot) + return (result_str, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +def getregentry() -> codecs.CodecInfo: + # Compatibility as a search_function for codecs.register() + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, # type: ignore + decode=Codec().decode, # type: ignore + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/.venv/Lib/site-packages/idna/compat.py b/.venv/Lib/site-packages/idna/compat.py new file mode 100644 index 0000000..786e6bd --- /dev/null +++ b/.venv/Lib/site-packages/idna/compat.py @@ -0,0 +1,13 @@ +from .core import * +from .codec import * +from typing import Any, Union + +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') + diff --git a/.venv/Lib/site-packages/idna/core.py b/.venv/Lib/site-packages/idna/core.py new file mode 100644 index 0000000..4f30037 --- /dev/null +++ b/.venv/Lib/site-packages/idna/core.py @@ -0,0 +1,400 @@ +from . import idnadata +import bisect +import unicodedata +import re +from typing import Union, Optional +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile('[\u002e\u3002\uff0e\uff61]') + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp: int) -> int: + v = unicodedata.combining(chr(cp)) + if v == 0: + if not unicodedata.name(chr(cp)): + 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') + +def _unot(s: int) -> str: + return 'U+{:04X}'.format(s) + + +def valid_label_length(label: Union[bytes, str]) -> bool: + if len(label) > 63: + return False + return True + + +def valid_string_length(label: Union[bytes, str], trailing_dot: bool) -> bool: + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +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): + direction = unicodedata.bidirectional(cp) + 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']: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {} 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): + 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)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label: str) -> bool: + 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') + return True + + +def check_nfc(label: str) -> None: + 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 pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label: 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: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == '\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + return False + + +def check_label(label: Union[str, bytes, bytearray]) -> None: + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {} 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']): + if not valid_contexto(label, pos): + 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))) + + check_bidi(label) + + +def alabel(label: str) -> bytes: + try: + label_bytes = label.encode('ascii') + ulabel(label_bytes) + if not valid_label_length(label_bytes): + 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 + + if not valid_label_length(label_bytes): + raise IDNAError('Label too long') + + return label_bytes + + +def ulabel(label: Union[str, bytes, bytearray]) -> str: + if not isinstance(label, (bytes, bytearray)): + try: + label_bytes = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + else: + label_bytes = label + + label_bytes = label_bytes.lower() + if label_bytes.startswith(_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') + else: + check_label(label_bytes) + return label_bytes.decode('ascii') + + try: + label = label_bytes.decode('punycode') + except UnicodeError: + raise IDNAError('Invalid A-label') + check_label(label) + return label + + +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 = '' + + 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] + status = uts46row[1] + replacement = None # type: Optional[str] + 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)): + output += char + elif replacement is not None and (status == 'M' or + (status == '3' and not std3_rules) or + (status == 'D' and transitional)): + output += replacement + elif status != 'I': + raise IndexError() + except IndexError: + raise InvalidCodepoint( + 'Codepoint {} not allowed at position {} in {}'.format( + _unot(code_point), pos + 1, repr(domain))) + + 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)): + try: + s = s.decode('ascii') + except UnicodeDecodeError: + 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('.') + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s: 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') + except UnicodeDecodeError: + raise IDNAError('Invalid ASCII in A-label') + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split('.') + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append('') + return '.'.join(result) diff --git a/.venv/Lib/site-packages/idna/idnadata.py b/.venv/Lib/site-packages/idna/idnadata.py new file mode 100644 index 0000000..67db462 --- /dev/null +++ b/.venv/Lib/site-packages/idna/idnadata.py @@ -0,0 +1,2151 @@ +# This file is automatically generated by tools/idna-data + +__version__ = '15.0.0' +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x37f00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0xab650000ab66, + 0x101400001018f, + 0x101a0000101a1, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004dc0, + 0x4e000000a000, + 0xf9000000fa6e, + 0xfa700000fada, + 0x16fe200016fe4, + 0x16ff000016ff2, + 0x200000002a6e0, + 0x2a7000002b73a, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + 0x300000003134b, + 0x31350000323b0, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5ef000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b120, + 0x1b1320001b133, + 0x1b1500001b153, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 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, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x70f: 84, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 82, + 0x857: 82, + 0x858: 82, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 0x870: 82, + 0x871: 82, + 0x872: 82, + 0x873: 82, + 0x874: 82, + 0x875: 82, + 0x876: 82, + 0x877: 82, + 0x878: 82, + 0x879: 82, + 0x87a: 82, + 0x87b: 82, + 0x87c: 82, + 0x87d: 82, + 0x87e: 82, + 0x87f: 82, + 0x880: 82, + 0x881: 82, + 0x882: 82, + 0x883: 67, + 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, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1878: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x202f: 85, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, + 0x10ac0: 68, + 0x10ac1: 68, + 0x10ac2: 68, + 0x10ac3: 68, + 0x10ac4: 68, + 0x10ac5: 82, + 0x10ac6: 85, + 0x10ac7: 82, + 0x10ac8: 85, + 0x10ac9: 82, + 0x10aca: 82, + 0x10acb: 85, + 0x10acc: 85, + 0x10acd: 76, + 0x10ace: 82, + 0x10acf: 82, + 0x10ad0: 82, + 0x10ad1: 82, + 0x10ad2: 82, + 0x10ad3: 68, + 0x10ad4: 68, + 0x10ad5: 68, + 0x10ad6: 68, + 0x10ad7: 76, + 0x10ad8: 68, + 0x10ad9: 68, + 0x10ada: 68, + 0x10adb: 68, + 0x10adc: 68, + 0x10add: 82, + 0x10ade: 68, + 0x10adf: 68, + 0x10ae0: 68, + 0x10ae1: 82, + 0x10ae2: 85, + 0x10ae3: 85, + 0x10ae4: 82, + 0x10aeb: 68, + 0x10aec: 68, + 0x10aed: 68, + 0x10aee: 68, + 0x10aef: 82, + 0x10b80: 68, + 0x10b81: 82, + 0x10b82: 68, + 0x10b83: 82, + 0x10b84: 82, + 0x10b85: 82, + 0x10b86: 68, + 0x10b87: 68, + 0x10b88: 68, + 0x10b89: 82, + 0x10b8a: 68, + 0x10b8b: 68, + 0x10b8c: 82, + 0x10b8d: 68, + 0x10b8e: 82, + 0x10b8f: 82, + 0x10b90: 68, + 0x10b91: 82, + 0x10ba9: 82, + 0x10baa: 82, + 0x10bab: 82, + 0x10bac: 82, + 0x10bad: 68, + 0x10bae: 68, + 0x10baf: 85, + 0x10d00: 76, + 0x10d01: 68, + 0x10d02: 68, + 0x10d03: 68, + 0x10d04: 68, + 0x10d05: 68, + 0x10d06: 68, + 0x10d07: 68, + 0x10d08: 68, + 0x10d09: 68, + 0x10d0a: 68, + 0x10d0b: 68, + 0x10d0c: 68, + 0x10d0d: 68, + 0x10d0e: 68, + 0x10d0f: 68, + 0x10d10: 68, + 0x10d11: 68, + 0x10d12: 68, + 0x10d13: 68, + 0x10d14: 68, + 0x10d15: 68, + 0x10d16: 68, + 0x10d17: 68, + 0x10d18: 68, + 0x10d19: 68, + 0x10d1a: 68, + 0x10d1b: 68, + 0x10d1c: 68, + 0x10d1d: 68, + 0x10d1e: 68, + 0x10d1f: 68, + 0x10d20: 68, + 0x10d21: 68, + 0x10d22: 82, + 0x10d23: 68, + 0x10f30: 68, + 0x10f31: 68, + 0x10f32: 68, + 0x10f33: 82, + 0x10f34: 68, + 0x10f35: 68, + 0x10f36: 68, + 0x10f37: 68, + 0x10f38: 68, + 0x10f39: 68, + 0x10f3a: 68, + 0x10f3b: 68, + 0x10f3c: 68, + 0x10f3d: 68, + 0x10f3e: 68, + 0x10f3f: 68, + 0x10f40: 68, + 0x10f41: 68, + 0x10f42: 68, + 0x10f43: 68, + 0x10f44: 68, + 0x10f45: 85, + 0x10f51: 68, + 0x10f52: 68, + 0x10f53: 68, + 0x10f54: 82, + 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, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052a, + 0x52b0000052c, + 0x52d0000052e, + 0x52f00000530, + 0x5590000055a, + 0x56000000587, + 0x58800000589, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5ef000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x7fd000007fe, + 0x8000000082e, + 0x8400000085c, + 0x8600000086b, + 0x87000000888, + 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, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f6, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x16f1000016f9, + 0x170000001716, + 0x171f00001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001879, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191f, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1ab000001abe, + 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, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 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, + 0x1030000010320, + 0x1032d00010341, + 0x103420001034a, + 0x103500001037b, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x104d8000104fc, + 0x1050000010528, + 0x1053000010564, + 0x10597000105a2, + 0x105a3000105b2, + 0x105b3000105ba, + 0x105bb000105bd, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1078000010786, + 0x10787000107b1, + 0x107b2000107bb, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1086000010877, + 0x108800001089f, + 0x108e0000108f3, + 0x108f4000108f6, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a36, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10a8000010a9d, + 0x10ac000010ac8, + 0x10ac900010ae7, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10b8000010b92, + 0x10c0000010c49, + 0x10cc000010cf3, + 0x10d0000010d28, + 0x10d3000010d3a, + 0x10e8000010eaa, + 0x10eab00010ead, + 0x10eb000010eb2, + 0x10efd00010f1d, + 0x10f2700010f28, + 0x10f3000010f51, + 0x10f7000010f86, + 0x10fb000010fc5, + 0x10fe000010ff7, + 0x1100000011047, + 0x1106600011076, + 0x1107f000110bb, + 0x110c2000110c3, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1114400011148, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111c9000111cd, + 0x111ce000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e00011242, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133b00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x1145e00011462, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b9, + 0x116c0000116ca, + 0x117000001171b, + 0x1171d0001172c, + 0x117300001173a, + 0x1174000011747, + 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, + 0x1248000012544, + 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, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/.venv/Lib/site-packages/idna/intranges.py b/.venv/Lib/site-packages/idna/intranges.py new file mode 100644 index 0000000..6a43b04 --- /dev/null +++ b/.venv/Lib/site-packages/idna/intranges.py @@ -0,0 +1,54 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect +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 + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start: int, end: int) -> int: + return (start << 32) | end + +def _decode_range(r: int) -> Tuple[int, int]: + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_: int, ranges: Tuple[int, ...]) -> bool: + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/.venv/Lib/site-packages/idna/package_data.py b/.venv/Lib/site-packages/idna/package_data.py new file mode 100644 index 0000000..8501893 --- /dev/null +++ b/.venv/Lib/site-packages/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '3.4' + diff --git a/.venv/Lib/site-packages/idna/py.typed b/.venv/Lib/site-packages/idna/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/idna/uts46data.py b/.venv/Lib/site-packages/idna/uts46data.py new file mode 100644 index 0000000..186796c --- /dev/null +++ b/.venv/Lib/site-packages/idna/uts46data.py @@ -0,0 +1,8600 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +from typing import List, Tuple, Union + + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = '15.0.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'), + ] + +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', 'ç'), + ] + +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'), + ] + +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', 'ɠ'), + ] + +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', 'ȍ'), + ] + +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'), + ] + +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', 'ђ'), + ] + +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'), + ] + +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', 'ԃ'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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', 'в'), + ] + +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', 'ɔ'), + ] + +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'), + ] + +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'), + ] + +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', 'ự'), + ] + +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', 'ἇι'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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', 'ⱘ'), + ] + +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', 'ⳃ'), + ] + +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', '匚'), + ] + +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', '网'), + ] + +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', '十'), + ] + +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', 'ᅗ'), + ] + +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', '文'), + ] + +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'), + ] + +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', 'キログラム'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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', 'ꝼ'), + ] + +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'), + ] + +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', 'Ꮪ'), + ] + +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', '聾'), + ] + +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', '囹'), + ] + +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', '嗀'), + ] + +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', '喝'), + ] + +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'), + ] + +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', 'ۋ'), + ] + +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', 'يح'), + ] + +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', 'عج'), + ] + +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', 'جي'), + ] + +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', 'جحى'), + ] + +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', '〔'), + ] + +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', ':'), + ] + +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', 'セ'), + ] + +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', '←'), + ] + +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', '𐓝'), + ] + +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', 'ꭦ'), + ] + +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'), + ] + +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'), + ] + +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', '𑣆'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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'), + ] + +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', 'γ'), + ] + +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', 'υ'), + ] + +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', 'ζ'), + ] + +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', 'в'), + ] + +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', '𞤫'), + ] + +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'), + ] + +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', 'ش'), + ] + +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'), + ] + +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'), + ] + +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', '呈'), + ] + +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', '慈'), + ] + +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', '㴳'), + ] + +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', '䌴'), + ] + +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', '賁'), + ] + +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'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() + + _seg_78() + + _seg_79() + + _seg_80() + + _seg_81() +) # type: Tuple[Union[Tuple[int, str], Tuple[int, str, str]], ...] diff --git a/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2011 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/METADATA b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/METADATA new file mode 100644 index 0000000..1d935ed --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/METADATA @@ -0,0 +1,97 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 2.1.2 +Summary: Safely pass data to untrusted environments and back. +Home-page: https://palletsprojects.com/p/itsdangerous/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://itsdangerous.palletsprojects.com/ +Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/itsdangerous/ +Project-URL: Issue Tracker, https://github.com/pallets/itsdangerous/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +ItsDangerous +============ + +... so better sign this + +Various helpers to pass data to untrusted environments and to get it +back safe and sound. Data is cryptographically signed to ensure that a +token has not been tampered with. + +It's possible to customize how data is serialized. Data is compressed as +needed. A timestamp can be added and verified automatically while +loading a token. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U itsdangerous + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +Here's how you could generate a token for transmitting a user's id and +name between web requests. + +.. code-block:: python + + from itsdangerous import URLSafeSerializer + auth_s = URLSafeSerializer("secret key", "auth") + token = auth_s.dumps({"id": 5, "name": "itsdangerous"}) + + print(token) + # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg + + data = auth_s.loads(token) + print(data["name"]) + # itsdangerous + + +Donate +------ + +The Pallets organization develops and supports ItsDangerous and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://itsdangerous.palletsprojects.com/ +- Changes: https://itsdangerous.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/ItsDangerous/ +- Source Code: https://github.com/pallets/itsdangerous/ +- Issue Tracker: https://github.com/pallets/itsdangerous/issues/ +- Website: https://palletsprojects.com/p/itsdangerous/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/RECORD b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/RECORD new file mode 100644 index 0000000..d3a279a --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/RECORD @@ -0,0 +1,23 @@ +itsdangerous-2.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +itsdangerous-2.1.2.dist-info/LICENSE.rst,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475 +itsdangerous-2.1.2.dist-info/METADATA,sha256=ThrHIJQ_6XlfbDMCAVe_hawT7IXiIxnTBIDrwxxtucQ,2928 +itsdangerous-2.1.2.dist-info/RECORD,, +itsdangerous-2.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +itsdangerous-2.1.2.dist-info/top_level.txt,sha256=gKN1OKLk81i7fbWWildJA88EQ9NhnGMSvZqhfz9ICjk,13 +itsdangerous/__init__.py,sha256=n4mkyjlIVn23pgsgCIw0MJKPdcHIetyeRpe5Fwsn8qg,876 +itsdangerous/__pycache__/__init__.cpython-310.pyc,, +itsdangerous/__pycache__/_json.cpython-310.pyc,, +itsdangerous/__pycache__/encoding.cpython-310.pyc,, +itsdangerous/__pycache__/exc.cpython-310.pyc,, +itsdangerous/__pycache__/serializer.cpython-310.pyc,, +itsdangerous/__pycache__/signer.cpython-310.pyc,, +itsdangerous/__pycache__/timed.cpython-310.pyc,, +itsdangerous/__pycache__/url_safe.cpython-310.pyc,, +itsdangerous/_json.py,sha256=wIhs_7-_XZolmyr-JvKNiy_LgAcfevYR0qhCVdlIhg8,450 +itsdangerous/encoding.py,sha256=pgh86snHC76dPLNCnPlrjR5SaYL_M8H-gWRiiLNbhCU,1419 +itsdangerous/exc.py,sha256=VFxmP2lMoSJFqxNMzWonqs35ROII4-fvCBfG0v1Tkbs,3206 +itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous/serializer.py,sha256=zgZ1-U705jHDpt62x_pmLJdryEKDNAbt5UkJtnkcCSw,11144 +itsdangerous/signer.py,sha256=QUH0iX0in-OTptMAXKU5zWMwmOCXn1fsDsubXiGdFN4,9367 +itsdangerous/timed.py,sha256=5CBWLds4Nm8-3bFVC8RxNzFjx6PSwjch8wuZ5cwcHFI,8174 +itsdangerous/url_safe.py,sha256=5bC4jSKOjWNRkWrFseifWVXUnHnPgwOLROjiOwb-eeo,2402 diff --git a/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/WHEEL b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..e163955 --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +itsdangerous diff --git a/.venv/Lib/site-packages/itsdangerous/__init__.py b/.venv/Lib/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..fdb2dfd --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/__init__.py @@ -0,0 +1,19 @@ +from .encoding import base64_decode as base64_decode +from .encoding import base64_encode as base64_encode +from .encoding import want_bytes as want_bytes +from .exc import BadData as BadData +from .exc import BadHeader as BadHeader +from .exc import BadPayload as BadPayload +from .exc import BadSignature as BadSignature +from .exc import BadTimeSignature as BadTimeSignature +from .exc import SignatureExpired as SignatureExpired +from .serializer import Serializer as Serializer +from .signer import HMACAlgorithm as HMACAlgorithm +from .signer import NoneAlgorithm as NoneAlgorithm +from .signer import Signer as Signer +from .timed import TimedSerializer as TimedSerializer +from .timed import TimestampSigner as TimestampSigner +from .url_safe import URLSafeSerializer as URLSafeSerializer +from .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer + +__version__ = "2.1.2" diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bfc20c52cc875c85969e3088f052d80a71ac152 GIT binary patch literal 860 zcmaKq&5qMB6or$vNz*jx?@WgWVABOfGoV=@geV1R7Q+ZAv#}ysZf%N%^CLU$wDU&1 z536hu3toX0_gbT>Wr3p{edpM|v7?*Eap=JKwLKTA?l?cu9F7{8*YKJjAl%`ua#EML zE^-aHMrxMpz;#l$+)$0wBc5ds*eAYaAGk@HmYcu<2`mS|Ez+{w0uD)NIaKX5B9Y~` ziqj71SdM_Zq-!|_?vbA5j_RiaGO*kQ9+IKuo;pcS$*JW&@Q93n2jq+o=g#=#w+mMr zyH&hkMqECpTr6`g4g!%q1mPXaO1jvU!oYO%4dZWF$pBk`SAub&!GvHwu${^o2N!{x z%T>n8wZ@`7@SkNWjjyK zy4WtYht@}Fq68={6l}68H2W**HUz{s_RKoMB{50|W3R*u=q?6541%>*)WBhNAF}~S z)uwbKw2^s6>32t;;RMQ`kFyuaEquu&Cd==5GMhiUJWpn8t>NgqX;CDTjmS31wOk}d zmf}glmfzS)m_(L_vuq`FzBW%Om6yNsG9nls`{$B-rDLDpdX)h^fyY#cQn?CgRuu}?}Jc8 z(K#8@?#ssf6;Vv_E28)%8wZLWkSzEKd1O?eT&Erwd%*TR2;J2fGeyT-2a4%%7U`aj zC+r^70&8Ous6d5R!6hB{AtOSc>UEOq-Xv17+UTO2st;W^eIkbSqLGDreeiB{{^Wy^ zO`}aJP2E;1o!Pod7qx2VI(5g=rPi6UvFX`y>9mF4^uYHTxt!Nh`N(M3nyP?x{2|nF z6+>W)8*}8EUXUAvOh*~>p}-zK#0oZ}29v)MgRpN$!`=MQYGZR-)n_Un9z1=vlMh>C zbX6?(ngqIqTOQ>W26_Yooye)SdFiZ@)l>rt`?%{cXqF~|qA{>#Ao}cldma0r zo51t>Xy&7nGij#wFC_R+0Q?3EJOFV)ui>nU-7vb+xe8EsbjB{ogqGm_LO&zYaO4wR z+16+wZBdplec$Rv8tH0dGj>ZK-qPKSqt_`tk?q`>5L)<9wTlKa%m!En_t$M^B@l|a z10n&o2rgj>-KPKG>Pn2V#K%HZa-oIreIZsy1w9esV=L#sBRwHhU7*`K>B?fE-Eplv z6V8W+RSB2k@C1B#w1oS6zF)1j+KsU`8lKN|^WoYMip3#g5>Uoc%6Li*MzYWcc>fjJ f$Ss?)nwq;1>B9f3=;P>R`ttrrZ1%t0&w| literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2c3d4be605c4b3c8d343e47376471c4ecf90728 GIT binary patch literal 1864 zcma)6-ESi`5VyUXO|nhWHvPDM2^JkfM9@M-DF|^VxWWU{spx16XfGw&#BOfOb`#m& zwuxGV=)EESf)i5u$iL)Q#6zEXy9bULZ>vi|NO)y?c08Vs-;AeMt@;GUAE)c$=K>+W z$6p0P`I4m_|;w;PV}V-=@LM`=eG2dsg1v?Cgh^x(QI z;!=X;HzKRBJ%65d&8UBH_@#12gW~%Qr&6~v``aZLZM;bsZf{6Ng#6+(ryPqx*14g zur|;IATZDidJe%tnBB7oG){!c3OjDJtiHxD`GF2EHI0{cR|nSPmCAO=@0aT zo{&aq_~kWxTwq}Ud=UDoMdN?q7{tngWUP?q+@9#HrrjH%^)z-OA*xLdHVK3wcCu%6Hq=7r1PyEzr@@z5J;dFS#kFSK-<} z1F4M5u7iNWnyFEF7dBJ0?rHfiSD+c^MTG^3uAn0vn#Kj?&LXxAcl!$afedg#@2zK6 zANmGnO+g-JN<*E$jxyLb#_GH>F8V&4S;uCneADWZn0<+EG*)bC^GsnU%%Br`deDcr z8M2l(jyUbubeh6m8uwC(-NO{D{;<;0Ex40oWvj)$BAYljK||HbSGJX z`{7jU`XNS1|4GyqU~|XX4lVwh8>kjtaj~<>*U+Zhi4@3Xsb#%^EC+zFSlhV9K(KJw x7hn4LsK>KJ+(#7EyReiEie*@_=$b$d? literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1173416d39a3d54d69e4d505a06243fcaeb134a5 GIT binary patch literal 3403 zcmai0&2t+y6yGne*Bd(t{RmC@T3~uG(;5neg9n(Fv;z#Cz>sqBnAs?noNQU|8fl#m zPj2nd8yEfodhCTiXs-+h&b`sX@OxUX?Iv!kv1C1IB|W|0@4ctA(eMqFzYed8U+RYO zCkgY#fp8sF{fdSg+>DKmiGM4$23E&14PoB3QJr<8Q_+1Fz3P_+x4CoQ;Er(b*&PpZ zg}abl;X$rJu5u5uCu)#=$TjXm_Jt353Gx!JL$2%jI^+glhP&kKC{U@)f&-=kk@V70k_jnzE4Z^4sQ|xh zPhf=-et^*+!xpx zS0@&4l`7?~6xm27Jrkdlh5A%CP?d}3*tm;J$qKqnv$%yRJxFqC+JNLnUJXN)$uK+% zL6NOobG$M;Q_lf-SR`Qs5r(-RhJ%!kV(Qn!@aGYWCo|ZJr#%eYSf#Hbm+6Sc#9loS z$1v$kff{BdX(0(9(oRw18IF0zU32v4DH_w2s64)m<{27Sxh)*HS*7o2GLxG%o}q6Y z7u$+<69xl{@ueAuS)j_{fTuzQNty)%mi6{po7#GLb;yq5l<^*^S{CY;_3E3iWw9iWehKD8u}i2rI1=Vo z)iRx@mSz2C+19_Fv-VWdH>Ws20p~g`B+kuqfLlP;&R3_9-Z~sc$O2-;Ttx^nvzZ%!BeCB42?>p0mCB4n6ZE6aBt!s zpV5T~3(xRONh7E3O>RnMA@{-l+8p~4gM{1nH1{dZH#$|#eGeA$^BSQ3N-$h_{KrYt zfbe^Iii|R0JN}Vg2Z9pkV3JeQBtFu1*<-_@KnA6xii8xwJ;umOMMm9Y`vPX0?5LCM zF2%WnDBGi)taq3q@`7CZ;k8o^r8$aBSb>*U3<7CN&?AkWU6YSXC!%Zyl5wGic$eVmHf7nA2bTkIsaP!q9m0Y^ zq;y`?yX=VUK!`-|KBFAA(%VisNID5@Rj_0B+S7YzE~dR6y_m3UB%@?EAl>L6N2)BP zi8KlDq-?V+lkM$ttAc3obiLCHo`#cnPyFfGXv#wUvPuf^r&G1&+ZsE@pqEljt#_GqfjZtht=K+0hV2lSI2B@V|jxZr?!K z*Qud)t9)k{C(+Gyde`w?2Rltkz2V&ZU>YHF@6+P#_c?fIC{ohHGqrB{=BmBAvbwx_ JVbwi%@qZYE;u8P> literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94546ebfb6e81a9724838f614677ab4b9dd7f174 GIT binary patch literal 9687 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 Y%L2P0az*5XR?Vutw6rvLb!EBq|DUyYmH+?% literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da9ae6db51694054e62d5a8e57ce0d3792f00c20 GIT binary patch literal 6469 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc b/.venv/Lib/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6cf85f349200543fb6d33c4299710adff1baeb1 GIT binary patch literal 2688 zcmbVO-H#MS5bvJvo7>&vOTPT-1Q9NQMIs@J#()9H4aT#)0^^FPfyIgDz*6Nku++d( z1HrmxxYK(#>;1{c7DMz(Mw7qR(?az}XF75-Yl zJ&-e~9U|N}mH=ftyhGa5gA=REhY>5 zJiV3XgFoOQI7@T3k?K{JFez4gSt6NwniNYlIJ1l;T8mCsGhMJjmNr8MR|}w%LMf(K z1yfq4`3m|w$-2Pz)M_EMkSuMpT(n?bBKvjr>2|YI+QA4lxPgqN^+(k zgRIY*f_1Z`HClJVAho&)gVhTs3orfds7R%g$Q31#v!%DbfrHYMLic3evc}~=G6Znr zq&c|NuOK+xbcggV(DWXab3@8)PQJ4akxeMkraSO79nvkj>D?gtUWaI_f1Hv{pzpxf zHg|_U_rAA={(~AU-5^6(UIMRk*ByHIrr*3c^`^hmo7&qVYyQw%p+oy;dX=PP z==?%|KtczLmmcE!>k_lMHuzwn=w+Pcg=S-9M_e|@jxhlcTS-p|RVci)9o2vRGV7rjQc)6hgFk8)ms^1(w_LD0hbL0Rp-UoN^a0jo2h{H_UtT6?l{t-s^O?Ya#cd zDcB}MX=fsr*!p4i0eHwaP#gpiRZ|sj&l9{1Cwk9aMNp?ua-d^=SfGzaT&&Or{KK|^-3In)l0Im$B$!PwBlGIq|qKO z+DR|d@l-Eyn|&=*X~nvm#M#dsAh^@d!~Jjq}2N{4#6yG(*@F^a9S1c?!-1Xym55n&yh6-|q0OB3G%>xXYn^ zVC(O7VXKZ`-Vm|{M<{EpCK8TSu#YC0FiF;3O`1ZpM6nIP37^Z$$Kqql%O_Ad35tmW zdL8s}XTR^rBap6q3&l|sZ=;w%JR#0Wa9o7@A-0)-1XQBsg)qt!;04&WPsnG^@4@do zVfW0W{{zru4J9#$*UJNF!XVNw381V)nmgk44md8O^Arjk&F?Nf-S0wq<#Du`eeTBC zSj`4019MWNA2Bw2zO>;8F`azWm3?qTuEsw@63L=SN6!h20g) QSAmAQ{o7^ld4IqEACe@+$N&HU literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/itsdangerous/_json.py b/.venv/Lib/site-packages/itsdangerous/_json.py new file mode 100644 index 0000000..c70d37a --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/_json.py @@ -0,0 +1,16 @@ +import json as _json +import typing as _t + + +class _CompactJSON: + """Wrapper around json module that strips whitespace.""" + + @staticmethod + def loads(payload: _t.Union[str, bytes]) -> _t.Any: + return _json.loads(payload) + + @staticmethod + def dumps(obj: _t.Any, **kwargs: _t.Any) -> str: + kwargs.setdefault("ensure_ascii", False) + kwargs.setdefault("separators", (",", ":")) + return _json.dumps(obj, **kwargs) diff --git a/.venv/Lib/site-packages/itsdangerous/encoding.py b/.venv/Lib/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..edb04d1 --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/encoding.py @@ -0,0 +1,54 @@ +import base64 +import string +import struct +import typing as _t + +from .exc import BadData + +_t_str_bytes = _t.Union[str, bytes] + + +def want_bytes( + s: _t_str_bytes, encoding: str = "utf-8", errors: str = "strict" +) -> bytes: + if isinstance(s, str): + s = s.encode(encoding, errors) + + return s + + +def base64_encode(string: _t_str_bytes) -> bytes: + """Base64 encode a string of bytes or text. The resulting bytes are + safe to use in URLs. + """ + string = want_bytes(string) + return base64.urlsafe_b64encode(string).rstrip(b"=") + + +def base64_decode(string: _t_str_bytes) -> bytes: + """Base64 decode a URL-safe string of bytes or text. The result is + bytes. + """ + string = want_bytes(string, encoding="ascii", errors="ignore") + string += b"=" * (-len(string) % 4) + + try: + return base64.urlsafe_b64decode(string) + except (TypeError, ValueError) as e: + raise BadData("Invalid base64-encoded data") from e + + +# The alphabet used by base64.urlsafe_* +_base64_alphabet = f"{string.ascii_letters}{string.digits}-_=".encode("ascii") + +_int64_struct = struct.Struct(">Q") +_int_to_bytes = _int64_struct.pack +_bytes_to_int = _t.cast("_t.Callable[[bytes], _t.Tuple[int]]", _int64_struct.unpack) + + +def int_to_bytes(num: int) -> bytes: + return _int_to_bytes(num).lstrip(b"\x00") + + +def bytes_to_int(bytestr: bytes) -> int: + return _bytes_to_int(bytestr.rjust(8, b"\x00"))[0] diff --git a/.venv/Lib/site-packages/itsdangerous/exc.py b/.venv/Lib/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..c38a6af --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/exc.py @@ -0,0 +1,107 @@ +import typing as _t +from datetime import datetime + +_t_opt_any = _t.Optional[_t.Any] +_t_opt_exc = _t.Optional[Exception] + + +class BadData(Exception): + """Raised if bad data of any sort was encountered. This is the base + for all exceptions that ItsDangerous defines. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str): + super().__init__(message) + self.message = message + + def __str__(self) -> str: + return self.message + + +class BadSignature(BadData): + """Raised if a signature does not match.""" + + def __init__(self, message: str, payload: _t_opt_any = None): + super().__init__(message) + + #: The payload that failed the signature test. In some + #: situations you might still want to inspect this, even if + #: you know it was tampered with. + #: + #: .. versionadded:: 0.14 + self.payload: _t_opt_any = payload + + +class BadTimeSignature(BadSignature): + """Raised if a time-based signature is invalid. This is a subclass + of :class:`BadSignature`. + """ + + def __init__( + self, + message: str, + payload: _t_opt_any = None, + date_signed: _t.Optional[datetime] = None, + ): + super().__init__(message, payload) + + #: If the signature expired this exposes the date of when the + #: signature was created. This can be helpful in order to + #: tell the user how long a link has been gone stale. + #: + #: .. versionchanged:: 2.0 + #: The datetime value is timezone-aware rather than naive. + #: + #: .. versionadded:: 0.14 + self.date_signed = date_signed + + +class SignatureExpired(BadTimeSignature): + """Raised if a signature timestamp is older than ``max_age``. This + is a subclass of :exc:`BadTimeSignature`. + """ + + +class BadHeader(BadSignature): + """Raised if a signed header is invalid in some form. This only + happens for serializers that have a header that goes with the + signature. + + .. versionadded:: 0.24 + """ + + def __init__( + self, + message: str, + payload: _t_opt_any = None, + header: _t_opt_any = None, + original_error: _t_opt_exc = None, + ): + super().__init__(message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header: _t_opt_any = header + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: _t_opt_exc = original_error + + +class BadPayload(BadData): + """Raised if a payload is invalid. This could happen if the payload + is loaded despite an invalid signature, or if there is a mismatch + between the serializer and deserializer. The original exception + that occurred during loading is stored on as :attr:`original_error`. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str, original_error: _t_opt_exc = None): + super().__init__(message) + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: _t_opt_exc = original_error diff --git a/.venv/Lib/site-packages/itsdangerous/py.typed b/.venv/Lib/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/itsdangerous/serializer.py b/.venv/Lib/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..9f4a84a --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/serializer.py @@ -0,0 +1,295 @@ +import json +import typing as _t + +from .encoding import want_bytes +from .exc import BadPayload +from .exc import BadSignature +from .signer import _make_keys_list +from .signer import Signer + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_kwargs = _t.Dict[str, _t.Any] +_t_opt_kwargs = _t.Optional[_t_kwargs] +_t_signer = _t.Type[Signer] +_t_fallbacks = _t.List[_t.Union[_t_kwargs, _t.Tuple[_t_signer, _t_kwargs], _t_signer]] +_t_load_unsafe = _t.Tuple[bool, _t.Any] +_t_secret_key = _t.Union[_t.Iterable[_t_str_bytes], _t_str_bytes] + + +def is_text_serializer(serializer: _t.Any) -> bool: + """Checks whether a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), str) + + +class Serializer: + """A serializer wraps a :class:`~itsdangerous.signer.Signer` to + enable serializing and securely signing data other than bytes. It + can unsign to verify that the data hasn't been changed. + + The serializer provides :meth:`dumps` and :meth:`loads`, similar to + :mod:`json`, and by default uses :mod:`json` internally to serialize + the data to bytes. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param serializer: An object that provides ``dumps`` and ``loads`` + methods for serializing data to a string. Defaults to + :attr:`default_serializer`, which defaults to :mod:`json`. + :param serializer_kwargs: Keyword arguments to pass when calling + ``serializer.dumps``. + :param signer: A ``Signer`` class to instantiate when signing data. + Defaults to :attr:`default_signer`, which defaults to + :class:`~itsdangerous.signer.Signer`. + :param signer_kwargs: Keyword arguments to pass when instantiating + the ``Signer`` class. + :param fallback_signers: List of signer parameters to try when + unsigning with the default signer fails. Each item can be a dict + of ``signer_kwargs``, a ``Signer`` class, or a tuple of + ``(signer, signer_kwargs)``. Defaults to + :attr:`default_fallback_signers`. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 2.0 + Removed the default SHA-512 fallback signer from + ``default_fallback_signers``. + + .. versionchanged:: 1.1 + Added support for ``fallback_signers`` and configured a default + SHA-512 fallback. This fallback is for users who used the yanked + 1.0.0 release which defaulted to SHA-512. + + .. versionchanged:: 0.14 + The ``signer`` and ``signer_kwargs`` parameters were added to + the constructor. + """ + + #: The default serialization module to use to serialize data to a + #: string internally. The default is :mod:`json`, but can be changed + #: to any object that provides ``dumps`` and ``loads`` methods. + default_serializer: _t.Any = json + + #: The default ``Signer`` class to instantiate when signing data. + #: The default is :class:`itsdangerous.signer.Signer`. + default_signer: _t_signer = Signer + + #: The default fallback signers to try when unsigning fails. + default_fallback_signers: _t_fallbacks = [] + + def __init__( + self, + secret_key: _t_secret_key, + salt: _t_opt_str_bytes = b"itsdangerous", + serializer: _t.Any = None, + serializer_kwargs: _t_opt_kwargs = None, + signer: _t.Optional[_t_signer] = None, + signer_kwargs: _t_opt_kwargs = None, + fallback_signers: _t.Optional[_t_fallbacks] = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key) + + if salt is not None: + salt = want_bytes(salt) + # if salt is None then the signer's default is used + + self.salt = salt + + if serializer is None: + serializer = self.default_serializer + + self.serializer: _t.Any = serializer + self.is_text_serializer: bool = is_text_serializer(serializer) + + if signer is None: + signer = self.default_signer + + self.signer: _t_signer = signer + self.signer_kwargs: _t_kwargs = signer_kwargs or {} + + if fallback_signers is None: + fallback_signers = list(self.default_fallback_signers or ()) + + self.fallback_signers: _t_fallbacks = fallback_signers + self.serializer_kwargs: _t_kwargs = serializer_kwargs or {} + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def load_payload( + self, payload: bytes, serializer: _t.Optional[_t.Any] = None + ) -> _t.Any: + """Loads the encoded object. This function raises + :class:`.BadPayload` if the payload is not valid. The + ``serializer`` parameter can be used to override the serializer + stored on the class. The encoded ``payload`` should always be + bytes. + """ + if serializer is None: + serializer = self.serializer + is_text = self.is_text_serializer + else: + is_text = is_text_serializer(serializer) + + try: + if is_text: + return serializer.loads(payload.decode("utf-8")) + + return serializer.loads(payload) + except Exception as e: + raise BadPayload( + "Could not load the payload because an exception" + " occurred on unserializing the data.", + original_error=e, + ) from e + + def dump_payload(self, obj: _t.Any) -> bytes: + """Dumps the encoded object. The return value is always bytes. + If the internal serializer returns text, the value will be + encoded as UTF-8. + """ + return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) + + def make_signer(self, salt: _t_opt_str_bytes = None) -> Signer: + """Creates a new instance of the signer to be used. The default + implementation uses the :class:`.Signer` base class. + """ + if salt is None: + salt = self.salt + + return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs) + + def iter_unsigners(self, salt: _t_opt_str_bytes = None) -> _t.Iterator[Signer]: + """Iterates over all signers to be tried for unsigning. Starts + with the configured signer, then constructs each signer + specified in ``fallback_signers``. + """ + if salt is None: + salt = self.salt + + yield self.make_signer(salt) + + for fallback in self.fallback_signers: + if isinstance(fallback, dict): + kwargs = fallback + fallback = self.signer + elif isinstance(fallback, tuple): + fallback, kwargs = fallback + else: + kwargs = self.signer_kwargs + + for secret_key in self.secret_keys: + yield fallback(secret_key, salt=salt, **kwargs) + + def dumps(self, obj: _t.Any, salt: _t_opt_str_bytes = None) -> _t_str_bytes: + """Returns a signed string serialized with the internal + serializer. The return value can be either a byte or unicode + string depending on the format of the internal serializer. + """ + payload = want_bytes(self.dump_payload(obj)) + rv = self.make_signer(salt).sign(payload) + + if self.is_text_serializer: + return rv.decode("utf-8") + + return rv + + def dump(self, obj: _t.Any, f: _t.IO, salt: _t_opt_str_bytes = None) -> None: + """Like :meth:`dumps` but dumps into a file. The file handle has + to be compatible with what the internal serializer expects. + """ + f.write(self.dumps(obj, salt)) + + def loads( + self, s: _t_str_bytes, salt: _t_opt_str_bytes = None, **kwargs: _t.Any + ) -> _t.Any: + """Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the + signature validation fails. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + return self.load_payload(signer.unsign(s)) + except BadSignature as err: + last_exception = err + + raise _t.cast(BadSignature, last_exception) + + def load(self, f: _t.IO, salt: _t_opt_str_bytes = None) -> _t.Any: + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe( + self, s: _t_str_bytes, salt: _t_opt_str_bytes = None + ) -> _t_load_unsafe: + """Like :meth:`loads` but without verifying the signature. This + is potentially very dangerous to use depending on how your + serializer works. The return value is ``(signature_valid, + payload)`` instead of just the payload. The first item will be a + boolean that indicates if the signature is valid. This function + never fails. + + Use it for debugging only and if you know that your serializer + module is not exploitable (for example, do not use it with a + pickle serializer). + + .. versionadded:: 0.15 + """ + return self._loads_unsafe_impl(s, salt) + + def _loads_unsafe_impl( + self, + s: _t_str_bytes, + salt: _t_opt_str_bytes, + load_kwargs: _t_opt_kwargs = None, + load_payload_kwargs: _t_opt_kwargs = None, + ) -> _t_load_unsafe: + """Low level helper function to implement :meth:`loads_unsafe` + in serializer subclasses. + """ + if load_kwargs is None: + load_kwargs = {} + + try: + return True, self.loads(s, salt=salt, **load_kwargs) + except BadSignature as e: + if e.payload is None: + return False, None + + if load_payload_kwargs is None: + load_payload_kwargs = {} + + try: + return ( + False, + self.load_payload(e.payload, **load_payload_kwargs), + ) + except BadPayload: + return False, None + + def load_unsafe(self, f: _t.IO, salt: _t_opt_str_bytes = None) -> _t_load_unsafe: + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), salt=salt) diff --git a/.venv/Lib/site-packages/itsdangerous/signer.py b/.venv/Lib/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..aa12005 --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/signer.py @@ -0,0 +1,257 @@ +import hashlib +import hmac +import typing as _t + +from .encoding import _base64_alphabet +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import want_bytes +from .exc import BadSignature + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_secret_key = _t.Union[_t.Iterable[_t_str_bytes], _t_str_bytes] + + +class SigningAlgorithm: + """Subclasses must implement :meth:`get_signature` to provide + signature generation functionality. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + """Returns the signature for the given key and value.""" + raise NotImplementedError() + + def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool: + """Verifies the given signature matches the expected + signature. + """ + return hmac.compare_digest(sig, self.get_signature(key, value)) + + +class NoneAlgorithm(SigningAlgorithm): + """Provides an algorithm that does not perform any signing and + returns an empty signature. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + return b"" + + +class HMACAlgorithm(SigningAlgorithm): + """Provides signature generation using HMACs.""" + + #: The digest method to use with the MAC algorithm. This defaults to + #: SHA1, but can be changed to any other function in the hashlib + #: module. + default_digest_method: _t.Any = staticmethod(hashlib.sha1) + + def __init__(self, digest_method: _t.Any = None): + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: _t.Any = digest_method + + def get_signature(self, key: bytes, value: bytes) -> bytes: + mac = hmac.new(key, msg=value, digestmod=self.digest_method) + return mac.digest() + + +def _make_keys_list(secret_key: _t_secret_key) -> _t.List[bytes]: + if isinstance(secret_key, (str, bytes)): + return [want_bytes(secret_key)] + + return [want_bytes(s) for s in secret_key] + + +class Signer: + """A signer securely signs bytes, then unsigns them to verify that + the value hasn't been changed. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param sep: Separator between the signature and value. + :param key_derivation: How to derive the signing key from the secret + key and salt. Possible values are ``concat``, ``django-concat``, + or ``hmac``. Defaults to :attr:`default_key_derivation`, which + defaults to ``django-concat``. + :param digest_method: Hash function to use when generating the HMAC + signature. Defaults to :attr:`default_digest_method`, which + defaults to :func:`hashlib.sha1`. Note that the security of the + hash alone doesn't apply when used intermediately in HMAC. + :param algorithm: A :class:`SigningAlgorithm` instance to use + instead of building a default :class:`HMACAlgorithm` with the + ``digest_method``. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 0.18 + ``algorithm`` was added as an argument to the class constructor. + + .. versionchanged:: 0.14 + ``key_derivation`` and ``digest_method`` were added as arguments + to the class constructor. + """ + + #: The default digest method to use for the signer. The default is + #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or + #: compatible object. Note that the security of the hash alone + #: doesn't apply when used intermediately in HMAC. + #: + #: .. versionadded:: 0.14 + default_digest_method: _t.Any = staticmethod(hashlib.sha1) + + #: The default scheme to use to derive the signing key from the + #: secret key and salt. The default is ``django-concat``. Possible + #: values are ``concat``, ``django-concat``, and ``hmac``. + #: + #: .. versionadded:: 0.14 + default_key_derivation: str = "django-concat" + + def __init__( + self, + secret_key: _t_secret_key, + salt: _t_opt_str_bytes = b"itsdangerous.Signer", + sep: _t_str_bytes = b".", + key_derivation: _t.Optional[str] = None, + digest_method: _t.Optional[_t.Any] = None, + algorithm: _t.Optional[SigningAlgorithm] = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: _t.List[bytes] = _make_keys_list(secret_key) + self.sep: bytes = want_bytes(sep) + + if self.sep in _base64_alphabet: + raise ValueError( + "The given separator cannot be used because it may be" + " contained in the signature itself. ASCII letters," + " digits, and '-_=' must not be used." + ) + + if salt is not None: + salt = want_bytes(salt) + else: + salt = b"itsdangerous.Signer" + + self.salt = salt + + if key_derivation is None: + key_derivation = self.default_key_derivation + + self.key_derivation: str = key_derivation + + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: _t.Any = digest_method + + if algorithm is None: + algorithm = HMACAlgorithm(self.digest_method) + + self.algorithm: SigningAlgorithm = algorithm + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def derive_key(self, secret_key: _t_opt_str_bytes = None) -> bytes: + """This method is called to derive the key. The default key + derivation choices can be overridden here. Key derivation is not + intended to be used as a security method to make a complex key + out of a short password. Instead you should use large random + secret keys. + + :param secret_key: A specific secret key to derive from. + Defaults to the last item in :attr:`secret_keys`. + + .. versionchanged:: 2.0 + Added the ``secret_key`` parameter. + """ + if secret_key is None: + secret_key = self.secret_keys[-1] + else: + secret_key = want_bytes(secret_key) + + if self.key_derivation == "concat": + return _t.cast(bytes, self.digest_method(self.salt + secret_key).digest()) + elif self.key_derivation == "django-concat": + return _t.cast( + bytes, self.digest_method(self.salt + b"signer" + secret_key).digest() + ) + elif self.key_derivation == "hmac": + mac = hmac.new(secret_key, digestmod=self.digest_method) + mac.update(self.salt) + return mac.digest() + elif self.key_derivation == "none": + return secret_key + else: + raise TypeError("Unknown key derivation method") + + def get_signature(self, value: _t_str_bytes) -> bytes: + """Returns the signature for the given value.""" + value = want_bytes(value) + key = self.derive_key() + sig = self.algorithm.get_signature(key, value) + return base64_encode(sig) + + def sign(self, value: _t_str_bytes) -> bytes: + """Signs the given string.""" + value = want_bytes(value) + return value + self.sep + self.get_signature(value) + + def verify_signature(self, value: _t_str_bytes, sig: _t_str_bytes) -> bool: + """Verifies the signature for the given value.""" + try: + sig = base64_decode(sig) + except Exception: + return False + + value = want_bytes(value) + + for secret_key in reversed(self.secret_keys): + key = self.derive_key(secret_key) + + if self.algorithm.verify_signature(key, value, sig): + return True + + return False + + def unsign(self, signed_value: _t_str_bytes) -> bytes: + """Unsigns the given string.""" + signed_value = want_bytes(signed_value) + + if self.sep not in signed_value: + raise BadSignature(f"No {self.sep!r} found in value") + + value, sig = signed_value.rsplit(self.sep, 1) + + if self.verify_signature(value, sig): + return value + + raise BadSignature(f"Signature {sig!r} does not match", payload=value) + + def validate(self, signed_value: _t_str_bytes) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid. + """ + try: + self.unsign(signed_value) + return True + except BadSignature: + return False diff --git a/.venv/Lib/site-packages/itsdangerous/timed.py b/.venv/Lib/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..cad8da3 --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/timed.py @@ -0,0 +1,234 @@ +import time +import typing +import typing as _t +from datetime import datetime +from datetime import timezone + +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import bytes_to_int +from .encoding import int_to_bytes +from .encoding import want_bytes +from .exc import BadSignature +from .exc import BadTimeSignature +from .exc import SignatureExpired +from .serializer import Serializer +from .signer import Signer + +_t_str_bytes = _t.Union[str, bytes] +_t_opt_str_bytes = _t.Optional[_t_str_bytes] +_t_opt_int = _t.Optional[int] + +if _t.TYPE_CHECKING: + import typing_extensions as _te + + +class TimestampSigner(Signer): + """Works like the regular :class:`.Signer` but also records the time + of the signing and can be used to expire signatures. The + :meth:`unsign` method can raise :exc:`.SignatureExpired` if the + unsigning failed because the signature is expired. + """ + + def get_timestamp(self) -> int: + """Returns the current timestamp. The function must return an + integer. + """ + return int(time.time()) + + def timestamp_to_datetime(self, ts: int) -> datetime: + """Convert the timestamp from :meth:`get_timestamp` into an + aware :class`datetime.datetime` in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + return datetime.fromtimestamp(ts, tz=timezone.utc) + + def sign(self, value: _t_str_bytes) -> bytes: + """Signs the given string and also attaches time information.""" + value = want_bytes(value) + timestamp = base64_encode(int_to_bytes(self.get_timestamp())) + sep = want_bytes(self.sep) + value = value + sep + timestamp + return value + sep + self.get_signature(value) + + # Ignore overlapping signatures check, return_timestamp is the only + # parameter that affects the return type. + + @typing.overload + def unsign( # type: ignore + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: "_te.Literal[False]" = False, + ) -> bytes: + ... + + @typing.overload + def unsign( + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: "_te.Literal[True]" = True, + ) -> _t.Tuple[bytes, datetime]: + ... + + def unsign( + self, + signed_value: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: bool = False, + ) -> _t.Union[_t.Tuple[bytes, datetime], bytes]: + """Works like the regular :meth:`.Signer.unsign` but can also + validate the time. See the base docstring of the class for + the general behavior. If ``return_timestamp`` is ``True`` the + timestamp of the signature will be returned as an aware + :class:`datetime.datetime` object in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + try: + result = super().unsign(signed_value) + sig_error = None + except BadSignature as e: + sig_error = e + result = e.payload or b"" + + sep = want_bytes(self.sep) + + # If there is no timestamp in the result there is something + # seriously wrong. In case there was a signature error, we raise + # that one directly, otherwise we have a weird situation in + # which we shouldn't have come except someone uses a time-based + # serializer on non-timestamp data, so catch that. + if sep not in result: + if sig_error: + raise sig_error + + raise BadTimeSignature("timestamp missing", payload=result) + + value, ts_bytes = result.rsplit(sep, 1) + ts_int: _t_opt_int = None + ts_dt: _t.Optional[datetime] = None + + try: + ts_int = bytes_to_int(base64_decode(ts_bytes)) + except Exception: + pass + + # Signature is *not* okay. Raise a proper error now that we have + # split the value and the timestamp. + if sig_error is not None: + if ts_int is not None: + try: + ts_dt = self.timestamp_to_datetime(ts_int) + except (ValueError, OSError, OverflowError) as exc: + # Windows raises OSError + # 32-bit raises OverflowError + raise BadTimeSignature( + "Malformed timestamp", payload=value + ) from exc + + raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt) + + # Signature was okay but the timestamp is actually not there or + # malformed. Should not happen, but we handle it anyway. + if ts_int is None: + raise BadTimeSignature("Malformed timestamp", payload=value) + + # Check timestamp is not older than max_age + if max_age is not None: + age = self.get_timestamp() - ts_int + + if age > max_age: + raise SignatureExpired( + f"Signature age {age} > {max_age} seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if age < 0: + raise SignatureExpired( + f"Signature age {age} < 0 seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if return_timestamp: + return value, self.timestamp_to_datetime(ts_int) + + return value + + def validate(self, signed_value: _t_str_bytes, max_age: _t_opt_int = None) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid.""" + try: + self.unsign(signed_value, max_age=max_age) + return True + except BadSignature: + return False + + +class TimedSerializer(Serializer): + """Uses :class:`TimestampSigner` instead of the default + :class:`.Signer`. + """ + + default_signer: _t.Type[TimestampSigner] = TimestampSigner + + def iter_unsigners( + self, salt: _t_opt_str_bytes = None + ) -> _t.Iterator[TimestampSigner]: + return _t.cast("_t.Iterator[TimestampSigner]", super().iter_unsigners(salt)) + + # TODO: Signature is incompatible because parameters were added + # before salt. + + def loads( # type: ignore + self, + s: _t_str_bytes, + max_age: _t_opt_int = None, + return_timestamp: bool = False, + salt: _t_opt_str_bytes = None, + ) -> _t.Any: + """Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the + signature validation fails. If a ``max_age`` is provided it will + ensure the signature is not older than that time in seconds. In + case the signature is outdated, :exc:`.SignatureExpired` is + raised. All arguments are forwarded to the signer's + :meth:`~TimestampSigner.unsign` method. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + base64d, timestamp = signer.unsign( + s, max_age=max_age, return_timestamp=True + ) + payload = self.load_payload(base64d) + + if return_timestamp: + return payload, timestamp + + return payload + except SignatureExpired: + # The signature was unsigned successfully but was + # expired. Do not try the next signer. + raise + except BadSignature as err: + last_exception = err + + raise _t.cast(BadSignature, last_exception) + + def loads_unsafe( # type: ignore + self, + s: _t_str_bytes, + max_age: _t_opt_int = None, + salt: _t_opt_str_bytes = None, + ) -> _t.Tuple[bool, _t.Any]: + return self._loads_unsafe_impl(s, salt, load_kwargs={"max_age": max_age}) diff --git a/.venv/Lib/site-packages/itsdangerous/url_safe.py b/.venv/Lib/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..d5a9b0c --- /dev/null +++ b/.venv/Lib/site-packages/itsdangerous/url_safe.py @@ -0,0 +1,80 @@ +import typing as _t +import zlib + +from ._json import _CompactJSON +from .encoding import base64_decode +from .encoding import base64_encode +from .exc import BadPayload +from .serializer import Serializer +from .timed import TimedSerializer + + +class URLSafeSerializerMixin(Serializer): + """Mixed in with a regular serializer it will attempt to zlib + compress the string to make it shorter if necessary. It will also + base64 encode the string so that it can safely be placed in a URL. + """ + + default_serializer = _CompactJSON + + def load_payload( + self, + payload: bytes, + *args: _t.Any, + serializer: _t.Optional[_t.Any] = None, + **kwargs: _t.Any, + ) -> _t.Any: + decompress = False + + if payload.startswith(b"."): + payload = payload[1:] + decompress = True + + try: + json = base64_decode(payload) + except Exception as e: + raise BadPayload( + "Could not base64 decode the payload because of an exception", + original_error=e, + ) from e + + if decompress: + try: + json = zlib.decompress(json) + except Exception as e: + raise BadPayload( + "Could not zlib decompress the payload before decoding the payload", + original_error=e, + ) from e + + return super().load_payload(json, *args, **kwargs) + + def dump_payload(self, obj: _t.Any) -> bytes: + json = super().dump_payload(obj) + is_compressed = False + compressed = zlib.compress(json) + + if len(compressed) < (len(json) - 1): + json = compressed + is_compressed = True + + base64d = base64_encode(json) + + if is_compressed: + base64d = b"." + base64d + + return base64d + + +class URLSafeSerializer(URLSafeSerializerMixin, Serializer): + """Works like :class:`.Serializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + + +class URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer): + """Works like :class:`.TimedSerializer` but dumps and loads into a + URL safe string consisting of the upper and lowercase character of + the alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ diff --git a/.venv/Lib/site-packages/jinja2/__init__.py b/.venv/Lib/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..e323926 --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/__init__.py @@ -0,0 +1,37 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.2" diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18e00419552b8c1ef88f3e1bf919948a7d0b971e GIT binary patch literal 1596 zcmbW1-EP}96vt)9j%``~cAW1-N&10Y)J0lg7sD{DaT{P;QUvn~41@temN=WOL<%J3 z+P&J{USY4WSMu$E0egjA?Hp#ZyCGL-LS1qNvqu3!XpcSM=ACW&MGT%_k3y zZ{V+f$yrut5i87v`6w6XNj`_X1-wPJ3>Sb4q+qxh72|EPZFn2FL`sHBQ8})Vis3S_ zO>Dyz;3}yawt*eu7_I`>NX@VVTqkwIHQ)wm7_LXnxJ6oq8^CSSHrxd6kdEONaF=uq zw}E%aj^Pe)kMs<8fp^KS;T_;TvS+v#?Z*e?!0;~cAvrX>2Yf`14DSOUlVigNz$fIy z@L_ZsyTmno1bjx$3?BoZlXJr-z!&7g@G0;k^2o3Y{FpojJ|j=U^PzQl@#(kk7=Q1( zOu4?RX`Dp9rY_|Z#;N;JGOa0h8F!OZQultLr-Jw0Z?&69F=HWxQ8pL+*-v-3u3B*I z&s{zBwX4!35mGA{8sSWIo=B<`6C6hH5dN-6G&KFlR$z?9oQAOMj7h;`%5~rV3+ltV z%q?rz3rzzN(t#gLDHyvqETY4Of^0wU>fO;ez_9T1p6Z+R+%QM^$A7m9+{^ftQdDA6 zZ=@6wm(F@JqnR0Rg}xCf4+g6-e};n!GsnL6 z6}=UHNHGy-FcmCVx9!&~(5v3&`ao7*{U+rB?q%gTcOp!q^&GW(KltEJ)`oL0A&2>D zKzlIt8TZE#U1bNU)L+waI@xr3vHyX3k(fZuOguQ0hn+xdW2hx0x*1&AY&bzged(Du zrf{1~{b#(B_)2+!;F``g^fyg=qe{SQJ$N%e+6ZhZ8qq*|eyRmkfuGP%#h3l7{)@Ml zPnRXn3q|00q%;o9(h~0^xrI^ySynezkVUk&(YEP4pr&Y*gqzKhWt0jEUU{;L;-J(( zmZiwNJtgaCHBg!;EtED&2c?U$142sjp@3u$tzDEolzo%~kYzE|EK>3ijU$v}loOOw z6c=P!^}HFC_^El`@0NUu9VmZ)KlpO=4k}!Y6c-=E(O~%Ui>uKfm6Gyc@hVA1{Tb|h zbj!vg#Wa1EJQRo;y~iu!#dFVNoN3SNCyQnItJsv&*Z7sHYmkEF6r9}u|CRIq09Kp3 AeE^m}0pmPy{+*Te3tz4(CvtJe1SEsM? z>{abm@21FZ&Tne$rg780>D*ZC#`#+Ny2t*p|4oa1(|cpHH{P2$=|x6*ne;ORgY+gs zn{*Swp^Gx3i!(Bg85tL37>pVzYD^IVYAhHv52>jkl&D#!ra`SFqgIMq0ku$VE7ZEikkR-# zjf*rsfvVAXKx2<4eVX`;CR4h?d${_7rhS?sF}U@>DSf!d!y_IsZQZ84X%T`{0HC(R7I$MpGx01zfCHGb?-^!<=?259_M0qYw ztKzgK&U)gkFLYVx8KLKeZZM&@MO_m0q^QGaq=lg)^o6k$jTRFPM>MlcG>=6~VxpB2 zEsu$|B-%~UF`4L$gqafNfiP8J&X_Rg!s-cYz=Y)sYb>mZuol8v3Ogxmn+e+$_E6X( z;bLdk5^h(x&bnJ&Pb9XU9Ihuig1er0>xsXEa10_ zAqCPP0}i6ZA(%uWvfw$p30h&nZy@Qn!@@iRF)xIgBryy!fL}{yz!E}6M(#yo8fr@9 zQIJvEk?=z;od)oxy->?U)eNc`4HwKGP%hxc;TcLIkJ#df$GZ26U z5~>2SAP4eMLIovI2L@`p`X$@sD#={ zWGN$YYD1i&uk#ATxgBbH)TxfMMlV$B?1ShuohvYl1P)-LJ5$5NJPS2zAHph!S})qJ zHv-Xiy=ABkjvxkYU`7HZzYpO@0z3FPu|EgVdmiFN4zcbiT5j|Oz@3aVa2zFY{8`k; zY!nu4bYHanu-J`67nwPlDb5#Rad8N-I10}O6;KT;=_bQq0w)p!fKya(OO;GI5_w=n z!U-$SWQb=i9-|t7qNc{@|UvukY+8UcdG5@h3Z5k05p)Jb9AX-8N&p z-^G9H|Av3RfB$Fk-|QuJ_u_lok3ZXt-~ZspKY1^H|LN{-V*BCezuMV}zx!!o`_uTZ zw|*br+j^2A@cpd-0FAwm*LGqaXfmYcsL^Wa|%GiQRX1K7W1h=bt>@eEKNy Viw$hCcMrq8*mv&U*|_(g{{rpk^(X)U literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33a1e384c79de129ddfb75755fb16c1efd0c09c1 GIT binary patch literal 2708 zcma)7-EI>{6rPz~+v~slI3Z1-RT2He6x^vN@+_)ElNU=OwelMnS?d=u9+Dp zByuDoQYBnasV`6^QZLFY^tO-CySc4YiC5qPdd_ST+aT1gJ+o(K&YV5xo9~>7i^Uv) z=bs1X#qU`{{>DN719Rj{XzCB>IN`KOYRQ|{7>rrdX}L9*;+z9=s+I!T<*8=6m8oT{ zoCeved6WpYm*ts#TFY^dXSYc$FAAb4hQzQK5u>6c#yEXM?|QXyo)fHb4B78?)E1U%BDW&dpu@w)(@B>iir`r`BZ9R?jGC!N~Kk2TIM#6_7{UAo^l8X!`Xy z(&B+ObfJ!lhYth6IcRDGgdMU>Ipu8I+oWCmyi*<6kOG}Fv@vMvSLig^qr1*NMRiU( zx>A~Ko zL?VFCtCv4tys3m#iz3-CnG$ifDE5TDY{RLM_gd?bC2R#lp@dSH8H(U%`Vs4dFG7m3Vz^(|L$%EsejH8x_v~^4l;~K`DbfYMt$CJ<$ zdOS|cj>-9cE9RZ1@O>bt9|bLx3ci286Eu?%QWw}7u0(=cTV*CEV86+9+C0#L*I{t< zAZJ}@??O|bLAOi01dg5o4GMUEocsidw+W@ zq)Fdfvz(zzW!K~qyq7ys-9~0cBO&-;R^_8uwjj%_l0^f7Fd59uwveaLOGMFgTvnhi z8=^yO$@d!+ghs({ts4 zJ5Ioav`}P^=!ry9sF|Z4&9MnKo^mrKkP38yx_OVLnM*fL{uelh96?L+J?t#*2zBzs z;(!H2U*SOm{HNvnAea=?#g348PrQ~OsQD)}^%ZnmP|%QFnyx|~Xtw8YU>l~1cK1>s zQF+47LgmKggRJiirWi!%4y^3^|ml2DA27|9Qkb- zwn81Q3f0R!lL;f$7Ikg%p$ZPS1KuBi$t3I^=W;$n`0$fVDe*_ zfa0ZvL?@n~(UqG~7)Q6kGpuG;4;H|?vnO?>Z+Pcw4d@IYhh)PrFN2_}AZ#&2 z4z5Nfr!?JT+#)nhHnJBiO1B7J8w-Sz`-K^p0n|_nGIXDPP41+QR^P?7vRgG--v{`F z^!<$iZxTE=iUS@)<;mO)6wyQ2vVyZGRyN~d*DNAaTJ<2xAdmE#1 xufaC!dS9fy4Dv1}chx04R)s-$#G?iL*(~y$$+M>%mS>c`WGwe0kvul^;$PJGckTcH literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd80fd62edce40766c97b2b21de607865d862e01 GIT binary patch literal 13950 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 +bY9cajXh1gaNIZ)4|Dw9@!TgUhByC7Li?N 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7ce1843d89e629e76c7c4dc222e922033a77620f GIT binary patch literal 54553 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/debug.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/debug.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cd49d9ec9eff34283947fc7b7afa002053fd84c GIT binary patch literal 3988 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 M)r~d&v;EP30V_9eVgLXD literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb5912a81ddaada35a21d52c86e53d424285a53e GIT binary patch literal 1332 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 m}=a=J?ebEuaGI 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/ext.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/ext.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc4af1f5dfaf53490d0e9c94b63d342dc34d3555 GIT binary patch literal 25695 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 NzGuBnhsCt<{{W{(tXBX4 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/filters.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/filters.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc51e9dab765a76cec3f8c3ee6976e92d833701c GIT binary patch literal 51185 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..650576cbb11fbc87d9a223a6d684871db7864dd1 GIT binary patch literal 11083 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ea94e5f0ec2d45048dcf4f06781d39e8f4ea224 GIT binary patch literal 20435 zcmcJ1d2n3!ec!%gPwXxZf&h3)D~b}iJfO?6WSSHOf)E7>1SkL$tre)nVt)_d0*hVn z_Z~>%`N5F{+0NKaDv#aNt-}_~(bQ?CO=sHFJrgH0?M%{6I`ycnU+gwl?JDi0iLcm* zEcWyL{@&XIfZG1k#k}8rAK&|jdM1;K;PhLkVH5p;?>l0MI ztadJU6}q&DWh{2fGu&!VVGnAgs=dp53wx2%B|0{=LLW->;~Nm^d3|5R+9xt+B9^wf zUu5rUg##SwMCc%gx-4z+&|ST7AIG{8yB}Zfd<1C^a9U4W+F>gx_Mn#s;rGHn0)H?3 zhv4_Ye;9s0{G;#(;2(p(4}Kp0e)z}XAAo-X{z3RB;U9v33jTfY2jSlj{}K2(_>aPW z0RCg}55s>P{)6zJfPV!3hu}X1|4H}{!~Zb+qwt@Ce+>T9@bmCL0{=Mt)9_Eg|0w*E z@Xx?M1^+DkLHN(We+2$H_>aPW7XD-Khu}XB|2+IB;19$95c~`9pM*aG|HJT~gZ~u# zi}0U@|2+JUz#oNw8vYCLKMMav_-Ejc!9NTC68vZ2kHbF)e**rq@Grw3g8vfy^YAC( z55u3TM8pN_!Ov@A#QG@Q=d7b}FIvapK5sn%chq_u?hDq3;l5~{fjedm!o6fY4R_pn z1nz|O5xAGFQ*d9ho`O4R<>5|QAA&n=o%pE$E=5}C#{FA)8fj{CVx>Y zOpBMr)wd$n^yZbjkqZ%w>1FGxHNBz1eR)G$(%;tX&%6*3AKTF0)c7Qgi&r*3CJN$J z)Oy957Bk}7TM_ZvPw7jmqqHEvB};-F zE!lReV&_(EOXQq-PSkUDec8&bNNYvb%a(0dY72w8Q71QFsXCUlbM;jxSE=1BRVyM_ zU$JD#sUx*oS+Y_N+McU8_VvoV(~@_~LbJ7_POem~)^DM5&ap7)l4IH2vTd!D(2QlL z!gLH=Sh-S7u2wL#QnhGdScpf3bz{{+AXcd% zqxPtp94+`! zUN%2nu}!v^;8bOW9(As(Ya&AbFV&n>alD26S)VmwzZO6<6N&{RiW$F?QKO~eeBdnuA$V7$R9^f!YWsmceaB9kGAILTuauur98Xt zd+Z%Mcjkea!F-Mys#`W~z3r5wle<-MuH%#rs!}uJL@|FHE*GpU;N+alt<oYTWtWh_Aj%wFe=!}=Dxp`SC2SFSvr%}gx^~B7nYv-Evs1{CBy@uV* zHHtQuwY3i_D{-VM5|?DR9@Ol8qa;Kjh8tB`sQJ-yy;^5)dAZ~pqH+^X-SKtnhM$

hBePu;qXJ7ce)M?Z?ulpH@!mu10{zF8|R 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbfac2699b8b37387cb680d3de5bd5456dea51a5 GIT binary patch literal 20522 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 OpMG)rE7LE{IsXSEJ1U<5 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/meta.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/meta.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d63e89fbe14049e75c79d279854a6d59e7d6e4b6 GIT binary patch literal 3812 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 DnBsw% literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c9be31e2b573fc835e3e3fc08704d1cae98dc09 GIT binary patch literal 1952 zcmY*Z-)|d55Z=9Cwl8)9C2gTauy4pxF)BqoAcR`1P%5f`NGjCBaN69ilXK6vW_K@+ zqw7;D@dSTEi+Jf1|IfW5A@yIVRA6QuC(T(q-rL=q{l1xRM)i6zf#;v2n^H%F{EaWK zKd?q_!!QDjAPEsvcm+*7;ftW~r$G`>0`ss4r%@77BE3mVUx$^bXiqyy2XraSSm(huzbcMG=`WyT&O33bkWNK#fX?`p(Q-8e7Vtl*hsM!_1lEVs-Ys0zN^lWfe5 zMc0bSLta$e%0V1|DKlOfxpKjTf_qD4@nXxtAukHIX)-m-%YBxYW2L9u0tN>G?v67x zo#h4iKHv`YI0tMFfU4{bHkT~pB{~)A%-<?@^#C7;d;d4m;7%~(}x zRTOwNVkZ9uaR$K|OD!RKh+YmD2HB{ha_E;wAuya7 z33LTB3*dYN!Iv_2@Qqa(Tw{D!{B>1GGl*Y+I>`15NF3?YCM=bZ1|}QZFxl0-G#DkR zVQFovJj}H!r+}jg@L;nh&zE!vE}BS7Tj?_M(Cz8t!#}EV2*bP!#*&(z(8r#oPd)2T zg4%l;*5ny|hAN`RKO;L#n>@1YAP3eEbxb_u7dR+3lNwP$+8Aic=GjVcE(tM%XOH7q zNG(!c`P$D9WjW|aP3PN{KpP5NG7ywTludxNoA59kHcTW*C{(v6x*`-2)TZyMHWY0cObY8Qs-IfG}XkQEY}D#d8)WAXoX2Q#P*o1kF}bnRcUnvElwnD zZc-30sPhW&a-Ng;-gKs*b?z0iALvWC?qs@&v&&$f)25TAS;37-)AM-iw_)!+80H$7 zYkoKIXhb(@0KfLD_0Xe%=e-L2xPTpQ!&1<1qH%)g$C$*DPi2}mahgIGho%Da zZkqm5@nX57QPPgA?&1u^()f4Eg+tWzPO)aPC{}o}z%vmvF0jonZ(Cm9v|J99)+m{#xBKwBt#tVH*6^Eq+jp1Tu!k*C jV&yF>!+|+BOYMHX2V1?nGnk!O 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 jgsi{`4;ES>u5Gl!`AVs7l>n!zfxLp7T9`3-| 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/sandbox.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/sandbox.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b0a69cfa8779ef58f430001507a79fc64bff76c GIT binary patch literal 11966 zcmdT~%X1vZd7szLKCoDTAPK&yAt_2&K9-_nQ8pthf*?Ys%K{w&w5$!C!CWcv`yl{lx^mP?fLQhZ8PZuv8ENzFA?sW_)ps!~a0N6hc*o>}aIph`Jr z$!YZC>z?lK{e3;*M>OChL>3UO>H4ub^IJ zrS?>3x;`!I6YT??nfi>Zm)i$Bhw6u9eG>J<^~1Wxt&Le$L3xBtp*-3&j%jTAeWQMi z9jG7YCw8>@N%WuMr;lm;DK_)6Ci|R`zJo7o><~M=Zq(1PS#|_}&$6TJ82+B)g^j2A z`Ig3xf28l|O#|&`Wc$Rh{j6-COxs1-I;C1ot3HSKRMY1I{$8Yg$URO`i5;EB+n>V7 z5k`BuB*!gwhMj%Ss$XX3cn$qmnihMSok!1e>=}LxJ;%`VESp2mRYvO{Wf%Bq^grLU z*+q5<{VzP$f0@rGUMYON7=h1$izlioVv|nIfK>G`P0_~U3 zevw^6`x<|VPwrUtFEV3UtG?8KZ{CT#fUSiOoVK^cg%huPvBQI?CwS!ag2-!fC+u?J z#eNt>PQwd=Fm~3sgT7`cI-J!?cOu^GwVnIxJivVJ#JtmOdog$XIO6T5(+E3QtSQ2d z;{{kW7QHCu%!$IDXz*I;*Tk<&RXsUQD|&Ivh1>Lbo4JA4;cnDz`!PmMZ>@npImX}V zaa4+n88jMGH=>5u<)dBpo1VDW>;78D>VTNI5p4P*3_3iZ)h3sDqbK}$>xK}aKu3Nd z3}XI(#)@|W#+!b?S)wo2(2-jUdja!5{DH0|$L}mH&oAC^7w;@BtlYe{TGT=1a5-Cmag$w{91IJ#ho*$umiEqEu~tJC4J@Eh*qQ*1T0niEHX z8*u_flE-WxluJqxk8ygh*N(+$LYV%4@f&NvDf@B4`jv zvmex&X5m@D6F~!Nu{O|ReZ#k(T&`;4k$ggF?xKUFGDRt z9E_!^k=Tj{lal)DcD!yipOpLvM~*$O@{VuouQA8XXm zC=9)r%Mf3p4OyOOMGe%3zYMc)peLF`L74rq2HfcbsM6TDXNj5E zWT^d2W5x&Oj{b)j0Vd7kyQo&MR6tVdQ(yh@OIbBtk$c?q?WVaa$ieW1BOEwNz#d!)4@przRh8l-fc zP&kleu$tp#D!EpY$f(tzTN%GB&wbtLZUHJ#LxjLrmHw8X)P_{!Y4e!R5kpq54@YRU z>qU|5Sb@TuQd8Yb@~XO+$4>X+z*b;g3`Hb^cG1!Wol9Ip0hWqm(V(+tKdR^O$g}?= zDw(iC5GNs!=B6gf3@jAX(-8|Jr`1Sw0)KOWI3*!&N(d6+3j=sG_Y6^${a;RJ=Ai%z zc#2IEFfY+qI#NRWb*wdkwHD-@b8$I__k;d#q%f0I2TTPpcO=XK2}Ap7r7%-e2h22J zS_CuDKRm#44@m@U@9#k96&}To-;`#Nkm0ZO!2c~D;_UdKGD;X75qRyCdd?84<~Xos zk|O+p2a8IgfjL9IP`WU3R#!xiuR4%-`I=P%kXB@McQHtpTuHHr1Kk4^5#bdpv?Tub zlnqa}3T2a-%9Quy?CZpb*H^!@tXu}pMoenWk6bAc!vn0+y0Aq;_>A!&<=IzWc}2Mb zN_EvT+4VbJ*b+=}GmN;ymE_B5;=ZGE(5jc5vmFthtx8D3$LE^TgIN>lq(!eCsaY$D ziM5i+g;0b&D0MDX{LFl`6*S&ZDl8PT&v4!9jJN_e7SEwb%8RMY(x{lC{;O1wYDlb@ zEJa}f0xKs^t_ZKe*PzK|v$#mEfEpQp%Zb#fc;m*>job4pw{DO675Q~9B0PyjdPfGj zaO?K1J1aMrZj68mQsc>)bg}v6x0e>&eU~i3&WSi8?F?f@f-GLAf=tzj{yV%cF}49D zt#G+q&@J6~R5qsN-;$x)voJYjJ*#IhHW?+;(o4En!3twKgA~iqz$-KKy7sN9yT-P$ zZNe0312Xal2KoTn!_ai-(RUEjkT&)Hjbw04Y8vaDYy=n`!Z+kF2YS|X)|3@@Qtu-b z6Uj<*Z9j@HIm~aMgoi|0SvjIqBd@m+!dyq)5Po9Na^_!KfPo8pZ3e3b4{QrYOfG~M zlTszWdB~#@!sn5D59U9}oS(UGZ-cF+-?txQf7YaXd@Fj4uStNOFzNTdg*PdW?f>v9 zIm?Hu{9x=|@>n;sW2RP~{Qd~?1{sIvuk_C)XLVJI-Kta-N}qim#GGx0;aTi>fB9Vm z*IpoACBdv(yBu6EkO-1@q-@k4hMwIYIUiw_h|F~PUINciy>2q2Zt>iPjVF(%fTxJ3gl7UznVCP&*C%;pV~S6sJb-70o|Zu+MVT_v zJjg7>zPXJYZ}L6%SZj*s*e5WyB{E-T4$ zf|Z;054EPwCRydZa{UA%a~hrI(@gG;P4JV=0-Iq65s#iqN2$-EI2?Va*(@UCBY>xO z&#+@^T`HR;cAT96j5CBeIWk&cr`TzXo=I1I3S(y_UL+>)W@=*{eokV>W)3?8_@`5N z!0rQcjy(;S^J6gQ5NV%h&!GRAVwpY1p2bYU!n3qGo1@hwJ`{%4+p8Fx!*c**6MPzH zxxg;Im#bIVC7k!NoH>R`>H$=ZUBP=U{1B?Fei6FqYI0~lGwM;eI^xqpSVoL74ED_! zYK1(+wttU20(jHB)q}4)3I|Q5v`x(0?I=}Govz;|e>mKA#8cyomyjQc)#n-W$?1fK z+H#`aTB8lG5W#!uK1c^-WIs;F+saJ5+Klp4>6LK%>FsKZ2>SgFM~c8x`x+`pE z4ICl_05a!*U3!fMkKp!a`h?CpOfA5b!nTG`aHArM=SdAS4pn}gKWJQE9gFcv$;h>Y z=SNU8j`Nl9J_WQ6On>NvSRY7y(BNH_>yT$_U{Qx5Q2?E;kPUq&TTv(%qfV*Ng#%Me zJ5t#bg#qAkbV)j1!|S!yV-?M;RP&$c7eCQ2C;Ej?^ecVi3Z4t7o=*;@F}S!J0GU@&-EYcx)vLVq7nJMOwqLUVeTRRx;E=c(5EIIb z`i|M1kabx79aD0I)&JK8aywJ6bDV@wv{{s0b6(pTQZVb>CEgwaN&5GKHk2eLfrOwI zQ-n=%s-pANRD}}qq%SPhoxqG%;P*+3LWRA)fwT%(FboiysZOi?aB1lF1hv)X*$DrcJv9N5g~cD zU_I)e|4b@nbCNvHKzZDxpz_wCNGwV*BIDyj@ir*^ko~AW6lsdmpur&4$FzYtK%fsZ zt@r;EQMlr3rB{)53OoU`2Yu$n7^62w&RiNCk7`?~$)Z&il@e~Gz-KH?GRz;qY7yBe zyU0Cw#wu5kMIzZtvPd0?v>~FAgh$lQ$mCG2+KGEqfR<}~-P`oBGc49Xn%487HqzZ@ z_LO#m^bxFIMCKj=I=g<|dA@dSxI9um92h~8SQ4y@x_E~QK}AHx9{QCC6Uyw&X3{lX z>_4?H-F9J-;1;dNG%d-O)U*{;cFD3sah=}(kG(|ceO{VK3;6$+Bu!ugG0h&5^!A}f zQDT^mdnO}BCEq{&WMU9#QUEP_bVbr2xyXJbCluaDf_#KZKSu`dnD!P7o(0tx<6>>= zrjFoS`UXZ!skArxc5K2d>f7d9T2KU>wRKj(ysZW2?`!>hOzQx4+e#tqtrvz6hwg*$ zALi*z1M8tFes^Hm+S_;|dJEM1&`@oxrW5Q&k$Rc_K1r_8pIh#&MGfTKV8n)oQ(i+w zSprM>y&tPIM`F=^Q?-;7DGehNz{$kd!Vs58vY|3PFXH$~@kZt+ih$ac`7F7oAUo7K zohDJq#;V(-;;@>Dl{8!T0j+W@``Ip1os74Dx@iK zpJ4pVV7LIIYnlzJn;+yLM98l*>wOEtk?UW*Ew9o@GKNf!~$+t40+FD|KAK22)75m>u9t~GPa^EUu0Dc*6a2jwL zE)l=el{@cnT9@5JW1a>X2y*d6rH#sovS*rcMq;4ZYmlvJlYVhNM=c#zO8ON1c<1dhH6Ra zQbK%kbXQA_-{Fhz)9}o2crm;0SIqM=twti5(+}=<{l`A_Xu8uyZhc6 zE{1yTB#-Y`IP*7?0`7@JK{b4OaUX*rQ;7^6Uq-x+n*t$yg#w{ee!gJN2V2RM>&lO4 z)E71MRX{h45;Nc}mF+0PL+K-jgpW7=fL@G?A!;w9?V>Fc8;P|RhHYhqB$~-N6J)H# zCe6v+3E zzJc1`wVIbDthMcxdXhaoRpqG$tT6kLXG591`fIPft%6 zxGOduRp>$c=_5xE7*p17pw~aGn8yE9EaSJOobemOE`4I0qFxKV7J4o8TK3E*g7(tD zGxj6RM8D`7iYy7QQtJ)#ci`ZQrxH`HCu!f6p~XnJLw(Jek|4h zhqq(~HdA(wWnx$No3%Nr z0tUe!aH?Etm2Rf+iY;jHELWLk0rtPv*qd6}n?Sh){5=+wk&!eByAFz2+aY}eXM;>v zRH7?4m`mv?szlh*B8Y7fx}=%<7ydYP@y>irW#wqMLF^)R)H@2Q4g^hpIj##==!F?7Ig zqd^YXj*cr{3)YRe4E9PnNP`?Me-C3Mzg-yQ#VI(v#)sy>9uyuL+x9zCvTcpD?Sa)q zd?EfA%fdcUULh$W26APFSNsjyN6^6t zo4CD&+>5`U!M~;Ai40C0^k=lQSyT$zN!_qWJ0qSTr`Xwc>?_gAYO=07VPdB+#7gy2M}GcE9*Q8nBJu<>F>-q)2(d|N_sU0lEA_lkw^c$KRkEQ; zo)QAz@Pzm|EhN>+B-Or5gC?13x+_UcGSX7d{DMX)UJ>N1iQl7w_!?ggsxKP}@*#Cp z(vFmX$R{`PrU{grmG<5wB9;0u{fcg1)1W7uC{GN);x_ zDzQDnvqQopg_o6Q^a>F=T18=N1>_S7h)UCcaCyu0;NNk>G7sS&An*^CS+~JKu+!7v kq))9Jl}0Y>o%@&L7iTInQ%5I{p2s!xcc*VpPtMN#F9;>BK>z>% literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/tests.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/tests.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..773ad183a1b83293b0a39c05e59b591d22315972 GIT binary patch literal 6686 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 rK3ez|Lw4DMjTUUQFp8(W%kL$4CD!i0|UU literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc b/.venv/Lib/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..777ee86df3fcb244e17394a6e7d035dcf53819ce GIT binary patch literal 3971 zcma)9U2ogg873)GqG>ygvm$kZra0RQB-)3EcEx}V-4Mg;x@?6S#9oGJ?kJk)$fiS) z$~ly6X*4jv+wK0qFd!Lr)BTj~AMkd-fZpwTH|_Jjv@FR=fDzy;@|?r>yr0i=l&`M` z7OwxCy{G=WZdw1Pm-)-Z%R}6z3n8tpC2i@XcGr;&>86c=+jVVAIme!Un`fHc*2k9g zWb==fY^v6=f6?f!V5B8|jQAH$H^AG94Dc4H0JE#o*|plMlc(E{ABldhMWLe;rA?9@ zisDF#?cF_*@vvEEcCaKaQ%49H5MI@4}(773^xJdGBEBFF- zTb(a#$hKX%9cYSaX#Vo?@({QA4urD0HXL=Nts2r%?y)BuEM1a)pPh5NP1%CkezpEI zF-fr#rD=4Ks>&r(D>u@IrfNPrt$(#DMmmcfXrEpbSF-6-+=gDHwQGHDcRsh;Zsi)4 z_O*vm-6YW>L3v{FzhCV9X#ZCRA=)=tek%8OcEA6F_x5*2TB|G`Zx4t2TPG?z+5aRt z*oSTEyTd4c79A?Hf1G5;(fi*!A(L~xH5^xd7{;(Y4A-FEkcF;2xxL`i)^tgy-J}>iqd*UH=w1mi>k4mjWvpD&i2|1+DntutGL;F-+I^Pk=N(u z0BdKt>2hwU2>b43Mm)-vY^mlkij8H1Br->jf@eLSdsTx5iN)PySa!&Z%>bZmSk{# z+^gN=@2?^tPV-SJS4ohbe7(|J_*Y@zk3$*8w?aGOnt!YTo)g#vS|SMD7PYd}Fv zFaZ*>TD?JT@98KrfZ&1B(Z6sK_&-PnY0OWJ0P80GB#sDa452coL#;p+BO}thj)BPWp*~IEO;X%9Qwt^3 z6i0Io&TL`YnVMJ=tsv$F^NP7aCGYGab@l7kr`vz*mjMuEKRGJ%lyHRu znp%CKpQ*%Xn)~^mc)054-|ai+?zsmp@CxU`(c6dCd9(D;=?~6Z7;O~|jDCQgcgxoG zo@2#tP> z+dP1{X$Q7z`;eQE4t@j3HT%Zp$eO+8IDf#o_};a~0w>KK6c$pvz(s_62rJUO6jlnn zOQ|;CrbFT)7Z_nre!q=wn?VG+es(gX2pXJ1gvoI%BC10MVn6J^g zDg)l2bt6F bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return t.cast("V", value) + + +async def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + async for item in t.cast("t.AsyncIterable[V]", iterable): + yield item + else: + for item in t.cast("t.Iterable[V]", iterable): + yield item + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/.venv/Lib/site-packages/jinja2/bccache.py b/.venv/Lib/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..d0ddf56 --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/bccache.py @@ -0,0 +1,406 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: + ... + + def set(self, key: str, value: bytes, timeout: t.Optional[int] = None) -> None: + ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/.venv/Lib/site-packages/jinja2/compiler.py b/.venv/Lib/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..3458095 --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/compiler.py @@ -0,0 +1,1957 @@ +"""Compiles nodes from the parser into Python code.""" +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed + and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "Frame": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "Frame": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in (self.filters, visitor.filters, "filters"), ( + self.tests, + visitor.tests, + "tests", + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(vars): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, public_names)) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import exported, async_exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline( + "async for event in parent_template.root_render_func(context):" + ) + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline( + f"{self.choose_async()}for event in" + f" context.blocks[{node.name!r}][0]({context}):", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + skip_event_yield = False + if node.with_context: + self.writeline( + f"{self.choose_async()}for event in template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)})):" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + else: + self.writeline("yield from template._get_default_module()._body_stream") + skip_event_yield = True + + if not skip_event_yield: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + message = ( + "the template {included_template.__name__!r}" + f" (imported on {self.position(node)})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/.venv/Lib/site-packages/jinja2/constants.py b/.venv/Lib/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/.venv/Lib/site-packages/jinja2/debug.py b/.venv/Lib/site-packages/jinja2/debug.py new file mode 100644 index 0000000..7ed7e92 --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: "t.Optional[Context]" = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/.venv/Lib/site-packages/jinja2/defaults.py b/.venv/Lib/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/.venv/Lib/site-packages/jinja2/environment.py b/.venv/Lib/site-packages/jinja2/environment.py new file mode 100644 index 0000000..ea04e8b --- /dev/null +++ b/.venv/Lib/site-packages/jinja2/environment.py @@ -0,0 +1,1667 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping], +) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: "Environment") -> "Environment": + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = False, + ) -> "Environment": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``,, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) # type: ignore + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") # type: ignore + + @typing.overload + def compile( # type: ignore + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: + ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: + ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "