From 232a87499c89f94d098f514184bdff39e60cd0c5 Mon Sep 17 00:00:00 2001 From: sascha Date: Tue, 12 Mar 2024 06:19:48 +0000 Subject: [PATCH] flask --- .vscode/launch.json | 15 + website/.venv/bin/Activate.ps1 | 247 + website/.venv/bin/activate | 69 + website/.venv/bin/activate.csh | 26 + website/.venv/bin/activate.fish | 69 + website/.venv/bin/flask | 8 + website/.venv/bin/pip | 8 + website/.venv/bin/pip3 | 8 + website/.venv/bin/pip3.10 | 8 + website/.venv/bin/python | 1 + website/.venv/bin/python3 | 1 + website/.venv/bin/python3.10 | 1 + .../Jinja2-3.1.3.dist-info/INSTALLER | 1 + .../Jinja2-3.1.3.dist-info/LICENSE.rst | 28 + .../Jinja2-3.1.3.dist-info/METADATA | 105 + .../Jinja2-3.1.3.dist-info/RECORD | 58 + .../Jinja2-3.1.3.dist-info/WHEEL | 5 + .../Jinja2-3.1.3.dist-info/entry_points.txt | 2 + .../Jinja2-3.1.3.dist-info/top_level.txt | 1 + .../MarkupSafe-2.1.5.dist-info/INSTALLER | 1 + .../MarkupSafe-2.1.5.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.5.dist-info/METADATA | 93 + .../MarkupSafe-2.1.5.dist-info/RECORD | 14 + .../MarkupSafe-2.1.5.dist-info/WHEEL | 6 + .../MarkupSafe-2.1.5.dist-info/top_level.txt | 1 + .../site-packages/_distutils_hack/__init__.py | 132 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5107 bytes .../__pycache__/override.cpython-310.pyc | Bin 0 -> 232 bytes .../site-packages/_distutils_hack/override.py | 1 + .../blinker-1.7.0.dist-info/INSTALLER | 1 + .../blinker-1.7.0.dist-info/LICENSE.rst | 20 + .../blinker-1.7.0.dist-info/METADATA | 62 + .../blinker-1.7.0.dist-info/RECORD | 14 + .../blinker-1.7.0.dist-info/WHEEL | 4 + .../site-packages/blinker/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 496 bytes .../__pycache__/_saferef.cpython-310.pyc | Bin 0 -> 7183 bytes .../__pycache__/_utilities.cpython-310.pyc | Bin 0 -> 3522 bytes .../blinker/__pycache__/base.cpython-310.pyc | Bin 0 -> 17496 bytes .../site-packages/blinker/_saferef.py | 230 + .../site-packages/blinker/_utilities.py | 105 + .../python3.10/site-packages/blinker/base.py | 558 ++ .../python3.10/site-packages/blinker/py.typed | 0 .../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 + .../site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2615 bytes .../click/__pycache__/_compat.cpython-310.pyc | Bin 0 -> 15673 bytes .../__pycache__/_termui_impl.cpython-310.pyc | Bin 0 -> 16313 bytes .../__pycache__/_textwrap.cpython-310.pyc | Bin 0 -> 1549 bytes .../__pycache__/_winconsole.cpython-310.pyc | Bin 0 -> 7665 bytes .../click/__pycache__/core.cpython-310.pyc | Bin 0 -> 91143 bytes .../__pycache__/decorators.cpython-310.pyc | Bin 0 -> 17213 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10257 bytes .../__pycache__/formatting.cpython-310.pyc | Bin 0 -> 9462 bytes .../click/__pycache__/globals.cpython-310.pyc | Bin 0 -> 2434 bytes .../click/__pycache__/parser.cpython-310.pyc | Bin 0 -> 13675 bytes .../shell_completion.cpython-310.pyc | Bin 0 -> 16850 bytes .../click/__pycache__/termui.cpython-310.pyc | Bin 0 -> 26135 bytes .../click/__pycache__/testing.cpython-310.pyc | Bin 0 -> 15208 bytes .../click/__pycache__/types.cpython-310.pyc | Bin 0 -> 33692 bytes .../click/__pycache__/utils.cpython-310.pyc | Bin 0 -> 18848 bytes .../python3.10/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 739 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../python3.10/site-packages/click/core.py | 3042 ++++++ .../site-packages/click/decorators.py | 561 ++ .../site-packages/click/exceptions.py | 288 + .../site-packages/click/formatting.py | 301 + .../python3.10/site-packages/click/globals.py | 68 + .../python3.10/site-packages/click/parser.py | 529 + .../python3.10/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .../python3.10/site-packages/click/termui.py | 784 ++ .../python3.10/site-packages/click/testing.py | 479 + .../python3.10/site-packages/click/types.py | 1089 +++ .../python3.10/site-packages/click/utils.py | 624 ++ .../site-packages/distutils-precedence.pth | 1 + .../flask-3.0.2.dist-info/INSTALLER | 1 + .../flask-3.0.2.dist-info/LICENSE.rst | 28 + .../flask-3.0.2.dist-info/METADATA | 116 + .../flask-3.0.2.dist-info/RECORD | 58 + .../flask-3.0.2.dist-info/REQUESTED | 0 .../site-packages/flask-3.0.2.dist-info/WHEEL | 4 + .../flask-3.0.2.dist-info/entry_points.txt | 3 + .../site-packages/flask/__init__.py | 60 + .../site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2286 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 211 bytes .../flask/__pycache__/app.cpython-310.pyc | Bin 0 -> 49881 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 3422 bytes .../flask/__pycache__/cli.cpython-310.pyc | Bin 0 -> 29085 bytes .../flask/__pycache__/config.cpython-310.pyc | Bin 0 -> 13420 bytes .../flask/__pycache__/ctx.cpython-310.pyc | Bin 0 -> 14852 bytes .../__pycache__/debughelpers.cpython-310.pyc | Bin 0 -> 6590 bytes .../flask/__pycache__/globals.cpython-310.pyc | Bin 0 -> 1579 bytes .../flask/__pycache__/helpers.cpython-310.pyc | Bin 0 -> 21606 bytes .../flask/__pycache__/logging.cpython-310.pyc | Bin 0 -> 2546 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 13288 bytes .../flask/__pycache__/signals.cpython-310.pyc | Bin 0 -> 809 bytes .../__pycache__/templating.cpython-310.pyc | Bin 0 -> 7083 bytes .../flask/__pycache__/testing.cpython-310.pyc | Bin 0 -> 9846 bytes .../flask/__pycache__/typing.cpython-310.pyc | Bin 0 -> 1833 bytes .../flask/__pycache__/views.cpython-310.pyc | Bin 0 -> 5543 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 5237 bytes .../lib/python3.10/site-packages/flask/app.py | 1488 +++ .../site-packages/flask/blueprints.py | 91 + .../lib/python3.10/site-packages/flask/cli.py | 1111 +++ .../python3.10/site-packages/flask/config.py | 372 + .../lib/python3.10/site-packages/flask/ctx.py | 449 + .../site-packages/flask/debughelpers.py | 178 + .../python3.10/site-packages/flask/globals.py | 51 + .../python3.10/site-packages/flask/helpers.py | 621 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5993 bytes .../json/__pycache__/provider.cpython-310.pyc | Bin 0 -> 7685 bytes .../json/__pycache__/tag.cpython-310.pyc | Bin 0 -> 11643 bytes .../site-packages/flask/json/provider.py | 215 + .../site-packages/flask/json/tag.py | 326 + .../python3.10/site-packages/flask/logging.py | 79 + .../python3.10/site-packages/flask/py.typed | 0 .../site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-310.pyc | Bin 0 -> 28610 bytes .../__pycache__/blueprints.cpython-310.pyc | Bin 0 -> 22932 bytes .../__pycache__/scaffold.cpython-310.pyc | Bin 0 -> 24084 bytes .../site-packages/flask/sansio/app.py | 968 ++ .../site-packages/flask/sansio/blueprints.py | 632 ++ .../site-packages/flask/sansio/scaffold.py | 805 ++ .../site-packages/flask/sessions.py | 371 + .../python3.10/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 219 + .../python3.10/site-packages/flask/testing.py | 298 + .../python3.10/site-packages/flask/typing.py | 90 + .../python3.10/site-packages/flask/views.py | 191 + .../site-packages/flask/wrappers.py | 174 + .../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 -> 864 bytes .../__pycache__/_json.cpython-310.pyc | Bin 0 -> 919 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1868 bytes .../__pycache__/exc.cpython-310.pyc | Bin 0 -> 3407 bytes .../__pycache__/serializer.cpython-310.pyc | Bin 0 -> 9691 bytes .../__pycache__/signer.cpython-310.pyc | Bin 0 -> 8459 bytes .../__pycache__/timed.cpython-310.pyc | Bin 0 -> 6473 bytes .../__pycache__/url_safe.cpython-310.pyc | Bin 0 -> 2692 bytes .../site-packages/itsdangerous/_json.py | 16 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 107 + .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 295 + .../site-packages/itsdangerous/signer.py | 257 + .../site-packages/itsdangerous/timed.py | 234 + .../site-packages/itsdangerous/url_safe.py | 80 + .../site-packages/jinja2/__init__.py | 37 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1600 bytes .../__pycache__/_identifier.cpython-310.pyc | Bin 0 -> 2075 bytes .../__pycache__/async_utils.cpython-310.pyc | Bin 0 -> 2689 bytes .../__pycache__/bccache.cpython-310.pyc | Bin 0 -> 13946 bytes .../__pycache__/compiler.cpython-310.pyc | Bin 0 -> 54549 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 1536 bytes .../jinja2/__pycache__/debug.cpython-310.pyc | Bin 0 -> 3992 bytes .../__pycache__/defaults.cpython-310.pyc | Bin 0 -> 1336 bytes .../__pycache__/environment.cpython-310.pyc | Bin 0 -> 53386 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5535 bytes .../jinja2/__pycache__/ext.cpython-310.pyc | Bin 0 -> 25841 bytes .../__pycache__/filters.cpython-310.pyc | Bin 0 -> 51370 bytes .../__pycache__/idtracking.cpython-310.pyc | Bin 0 -> 11087 bytes .../jinja2/__pycache__/lexer.cpython-310.pyc | Bin 0 -> 20437 bytes .../__pycache__/loaders.cpython-310.pyc | Bin 0 -> 20493 bytes .../jinja2/__pycache__/meta.cpython-310.pyc | Bin 0 -> 3816 bytes .../__pycache__/nativetypes.cpython-310.pyc | Bin 0 -> 5011 bytes .../jinja2/__pycache__/nodes.cpython-310.pyc | Bin 0 -> 40302 bytes .../__pycache__/optimizer.cpython-310.pyc | Bin 0 -> 1956 bytes .../jinja2/__pycache__/parser.cpython-310.pyc | Bin 0 -> 27730 bytes .../__pycache__/runtime.cpython-310.pyc | Bin 0 -> 32145 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 11968 bytes .../jinja2/__pycache__/tests.cpython-310.pyc | Bin 0 -> 6690 bytes .../jinja2/__pycache__/utils.cpython-310.pyc | Bin 0 -> 24509 bytes .../__pycache__/visitor.cpython-310.pyc | Bin 0 -> 3975 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../site-packages/jinja2/bccache.py | 406 + .../site-packages/jinja2/compiler.py | 1956 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.10/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1667 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../python3.10/site-packages/jinja2/ext.py | 869 ++ .../site-packages/jinja2/filters.py | 1854 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.10/site-packages/jinja2/lexer.py | 866 ++ .../site-packages/jinja2/loaders.py | 661 ++ .../python3.10/site-packages/jinja2/meta.py | 111 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.10/site-packages/jinja2/nodes.py | 1204 +++ .../site-packages/jinja2/optimizer.py | 47 + .../python3.10/site-packages/jinja2/parser.py | 1034 ++ .../python3.10/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1051 ++ .../site-packages/jinja2/sandbox.py | 428 + .../python3.10/site-packages/jinja2/tests.py | 255 + .../python3.10/site-packages/jinja2/utils.py | 755 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 332 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 11345 bytes .../__pycache__/_native.cpython-310.pyc | Bin 0 -> 2000 bytes .../site-packages/markupsafe/_native.py | 63 + .../site-packages/markupsafe/_speedups.c | 320 + .../_speedups.cpython-310-x86_64-linux-gnu.so | Bin 0 -> 44240 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../site-packages/markupsafe/py.typed | 0 .../pip-22.0.2.dist-info/INSTALLER | 1 + .../pip-22.0.2.dist-info/LICENSE.txt | 20 + .../pip-22.0.2.dist-info/METADATA | 92 + .../site-packages/pip-22.0.2.dist-info/RECORD | 1037 ++ .../pip-22.0.2.dist-info/REQUESTED | 0 .../site-packages/pip-22.0.2.dist-info/WHEEL | 5 + .../pip-22.0.2.dist-info/entry_points.txt | 5 + .../pip-22.0.2.dist-info/top_level.txt | 1 + .../python3.10/site-packages/pip/__init__.py | 13 + .../python3.10/site-packages/pip/__main__.py | 31 + .../pip/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 625 bytes .../pip/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 587 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 746 bytes .../__pycache__/build_env.cpython-310.pyc | Bin 0 -> 9590 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 8373 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 11119 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 23116 bytes .../__pycache__/main.cpython-310.pyc | Bin 0 -> 611 bytes .../__pycache__/pyproject.cpython-310.pyc | Bin 0 -> 3530 bytes .../self_outdated_check.cpython-310.pyc | Bin 0 -> 4570 bytes .../__pycache__/wheel_builder.cpython-310.pyc | Bin 0 -> 9132 bytes .../site-packages/pip/_internal/build_env.py | 296 + .../site-packages/pip/_internal/cache.py | 264 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 266 bytes .../autocompletion.cpython-310.pyc | Bin 0 -> 5299 bytes .../__pycache__/base_command.cpython-310.pyc | Bin 0 -> 6242 bytes .../__pycache__/cmdoptions.cpython-310.pyc | Bin 0 -> 22541 bytes .../command_context.cpython-310.pyc | Bin 0 -> 1300 bytes .../cli/__pycache__/main.cpython-310.pyc | Bin 0 -> 1364 bytes .../__pycache__/main_parser.cpython-310.pyc | Bin 0 -> 2150 bytes .../cli/__pycache__/parser.cpython-310.pyc | Bin 0 -> 9937 bytes .../__pycache__/progress_bars.cpython-310.pyc | Bin 0 -> 9226 bytes .../__pycache__/req_command.cpython-310.pyc | Bin 0 -> 13527 bytes .../cli/__pycache__/spinners.cpython-310.pyc | Bin 0 -> 4940 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 345 bytes .../pip/_internal/cli/autocompletion.py | 171 + .../pip/_internal/cli/base_command.py | 220 + .../pip/_internal/cli/cmdoptions.py | 1018 ++ .../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 | 292 + .../pip/_internal/cli/progress_bars.py | 321 + .../pip/_internal/cli/req_command.py | 506 + .../pip/_internal/cli/spinners.py | 157 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 127 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3129 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 6170 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 1563 bytes .../__pycache__/completion.cpython-310.pyc | Bin 0 -> 3130 bytes .../__pycache__/configuration.cpython-310.pyc | Bin 0 -> 8312 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 6667 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 3977 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 2643 bytes .../commands/__pycache__/hash.cpython-310.pyc | Bin 0 -> 2142 bytes .../commands/__pycache__/help.cpython-310.pyc | Bin 0 -> 1303 bytes .../__pycache__/index.cpython-310.pyc | Bin 0 -> 4626 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 17785 bytes .../commands/__pycache__/list.cpython-310.pyc | Bin 0 -> 10352 bytes .../__pycache__/search.cpython-310.pyc | Bin 0 -> 5356 bytes .../commands/__pycache__/show.cpython-310.pyc | Bin 0 -> 6109 bytes .../__pycache__/uninstall.cpython-310.pyc | Bin 0 -> 3100 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4832 bytes .../pip/_internal/commands/cache.py | 223 + .../pip/_internal/commands/check.py | 53 + .../pip/_internal/commands/completion.py | 96 + .../pip/_internal/commands/configuration.py | 266 + .../pip/_internal/commands/debug.py | 202 + .../pip/_internal/commands/download.py | 140 + .../pip/_internal/commands/freeze.py | 97 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 139 + .../pip/_internal/commands/install.py | 771 ++ .../pip/_internal/commands/list.py | 363 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 178 + .../pip/_internal/commands/uninstall.py | 105 + .../pip/_internal/commands/wheel.py | 178 + .../pip/_internal/configuration.py | 366 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 793 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1850 bytes .../__pycache__/installed.cpython-310.pyc | Bin 0 -> 1227 bytes .../__pycache__/sdist.cpython-310.pyc | Bin 0 -> 4439 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1594 bytes .../pip/_internal/distributions/base.py | 36 + .../pip/_internal/distributions/installed.py | 20 + .../pip/_internal/distributions/sdist.py | 127 + .../pip/_internal/distributions/wheel.py | 31 + .../site-packages/pip/_internal/exceptions.py | 658 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 220 bytes .../__pycache__/collector.cpython-310.pyc | Bin 0 -> 19299 bytes .../package_finder.cpython-310.pyc | Bin 0 -> 28108 bytes .../index/__pycache__/sources.cpython-310.pyc | Bin 0 -> 7113 bytes .../pip/_internal/index/collector.py | 648 ++ .../pip/_internal/index/package_finder.py | 1004 ++ .../pip/_internal/index/sources.py | 224 + .../pip/_internal/locations/__init__.py | 520 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 12380 bytes .../__pycache__/_distutils.cpython-310.pyc | Bin 0 -> 4648 bytes .../__pycache__/_sysconfig.cpython-310.pyc | Bin 0 -> 6231 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1530 bytes .../pip/_internal/locations/_distutils.py | 169 + .../pip/_internal/locations/_sysconfig.py | 219 + .../pip/_internal/locations/base.py | 52 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 62 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2286 bytes .../metadata/__pycache__/base.cpython-310.pyc | Bin 0 -> 20840 bytes .../__pycache__/pkg_resources.cpython-310.pyc | Bin 0 -> 9856 bytes .../pip/_internal/metadata/base.py | 546 ++ .../pip/_internal/metadata/pkg_resources.py | 256 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 254 bytes .../__pycache__/candidate.cpython-310.pyc | Bin 0 -> 1406 bytes .../__pycache__/direct_url.cpython-310.pyc | Bin 0 -> 7279 bytes .../format_control.cpython-310.pyc | Bin 0 -> 2731 bytes .../models/__pycache__/index.cpython-310.pyc | Bin 0 -> 1223 bytes .../models/__pycache__/link.cpython-310.pyc | Bin 0 -> 10155 bytes .../models/__pycache__/scheme.cpython-310.pyc | Bin 0 -> 1022 bytes .../__pycache__/search_scope.cpython-310.pyc | Bin 0 -> 3477 bytes .../selection_prefs.cpython-310.pyc | Bin 0 -> 1684 bytes .../__pycache__/target_python.cpython-310.pyc | Bin 0 -> 3435 bytes .../models/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4351 bytes .../pip/_internal/models/candidate.py | 34 + .../pip/_internal/models/direct_url.py | 220 + .../pip/_internal/models/format_control.py | 80 + .../pip/_internal/models/index.py | 28 + .../pip/_internal/models/link.py | 288 + .../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 | 89 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 242 bytes .../network/__pycache__/auth.cpython-310.pyc | Bin 0 -> 7510 bytes .../network/__pycache__/cache.cpython-310.pyc | Bin 0 -> 2923 bytes .../__pycache__/download.cpython-310.pyc | Bin 0 -> 5489 bytes .../__pycache__/lazy_wheel.cpython-310.pyc | Bin 0 -> 8397 bytes .../__pycache__/session.cpython-310.pyc | Bin 0 -> 10718 bytes .../network/__pycache__/utils.cpython-310.pyc | Bin 0 -> 1438 bytes .../__pycache__/xmlrpc.cpython-310.pyc | Bin 0 -> 2055 bytes .../pip/_internal/network/auth.py | 323 + .../pip/_internal/network/cache.py | 69 + .../pip/_internal/network/download.py | 185 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 454 + .../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 -> 190 bytes .../__pycache__/check.cpython-310.pyc | Bin 0 -> 4003 bytes .../__pycache__/freeze.cpython-310.pyc | Bin 0 -> 6188 bytes .../__pycache__/prepare.cpython-310.pyc | Bin 0 -> 14886 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 196 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 1423 bytes .../metadata_editable.cpython-310.pyc | Bin 0 -> 1457 bytes .../metadata_legacy.cpython-310.pyc | Bin 0 -> 2368 bytes .../build/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 1213 bytes .../wheel_editable.cpython-310.pyc | Bin 0 -> 1437 bytes .../__pycache__/wheel_legacy.cpython-310.pyc | Bin 0 -> 2753 bytes .../_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 -> 254 bytes .../editable_legacy.cpython-310.pyc | Bin 0 -> 1541 bytes .../__pycache__/legacy.cpython-310.pyc | Bin 0 -> 3325 bytes .../install/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 21083 bytes .../operations/install/editable_legacy.py | 47 + .../_internal/operations/install/legacy.py | 120 + .../pip/_internal/operations/install/wheel.py | 738 ++ .../pip/_internal/operations/prepare.py | 642 ++ .../site-packages/pip/_internal/pyproject.py | 168 + .../pip/_internal/req/__init__.py | 94 + .../req/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2590 bytes .../__pycache__/constructors.cpython-310.pyc | Bin 0 -> 12153 bytes .../req/__pycache__/req_file.cpython-310.pyc | Bin 0 -> 13481 bytes .../__pycache__/req_install.cpython-310.pyc | Bin 0 -> 22170 bytes .../req/__pycache__/req_set.cpython-310.pyc | Bin 0 -> 5830 bytes .../__pycache__/req_tracker.cpython-310.pyc | Bin 0 -> 4298 bytes .../__pycache__/req_uninstall.cpython-310.pyc | Bin 0 -> 18936 bytes .../pip/_internal/req/constructors.py | 490 + .../pip/_internal/req/req_file.py | 536 ++ .../pip/_internal/req/req_install.py | 858 ++ .../pip/_internal/req/req_set.py | 189 + .../pip/_internal/req/req_tracker.py | 124 + .../pip/_internal/req/req_uninstall.py | 633 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 190 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 1042 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 197 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 12284 bytes .../_internal/resolution/legacy/resolver.py | 467 + .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 201 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 6444 bytes .../__pycache__/candidates.cpython-310.pyc | Bin 0 -> 18351 bytes .../__pycache__/factory.cpython-310.pyc | Bin 0 -> 19209 bytes .../found_candidates.cpython-310.pyc | Bin 0 -> 4861 bytes .../__pycache__/provider.cpython-310.pyc | Bin 0 -> 7703 bytes .../__pycache__/reporter.cpython-310.pyc | Bin 0 -> 3170 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 7459 bytes .../__pycache__/resolver.cpython-310.pyc | Bin 0 -> 8096 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 547 ++ .../resolution/resolvelib/factory.py | 739 ++ .../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 | 292 + .../pip/_internal/self_outdated_check.py | 189 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 185 bytes .../utils/__pycache__/_log.cpython-310.pyc | Bin 0 -> 1513 bytes .../utils/__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 1611 bytes .../utils/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1501 bytes .../compatibility_tags.cpython-310.pyc | Bin 0 -> 4070 bytes .../__pycache__/datetime.cpython-310.pyc | Bin 0 -> 508 bytes .../__pycache__/deprecation.cpython-310.pyc | Bin 0 -> 3306 bytes .../direct_url_helpers.cpython-310.pyc | Bin 0 -> 2076 bytes .../distutils_args.cpython-310.pyc | Bin 0 -> 1092 bytes .../__pycache__/egg_link.cpython-310.pyc | Bin 0 -> 2141 bytes .../__pycache__/encoding.cpython-310.pyc | Bin 0 -> 1298 bytes .../__pycache__/entrypoints.cpython-310.pyc | Bin 0 -> 1295 bytes .../__pycache__/filesystem.cpython-310.pyc | Bin 0 -> 5153 bytes .../__pycache__/filetypes.cpython-310.pyc | Bin 0 -> 935 bytes .../utils/__pycache__/glibc.cpython-310.pyc | Bin 0 -> 1664 bytes .../utils/__pycache__/hashes.cpython-310.pyc | Bin 0 -> 5187 bytes .../inject_securetransport.cpython-310.pyc | Bin 0 -> 980 bytes .../utils/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9624 bytes .../utils/__pycache__/misc.cpython-310.pyc | Bin 0 -> 19390 bytes .../utils/__pycache__/models.cpython-310.pyc | Bin 0 -> 1981 bytes .../__pycache__/packaging.cpython-310.pyc | Bin 0 -> 2073 bytes .../setuptools_build.cpython-310.pyc | Bin 0 -> 4588 bytes .../__pycache__/subprocess.cpython-310.pyc | Bin 0 -> 5767 bytes .../__pycache__/temp_dir.cpython-310.pyc | Bin 0 -> 7290 bytes .../__pycache__/unpacking.cpython-310.pyc | Bin 0 -> 6645 bytes .../utils/__pycache__/urls.cpython-310.pyc | Bin 0 -> 1578 bytes .../__pycache__/virtualenv.cpython-310.pyc | Bin 0 -> 3281 bytes .../utils/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 4406 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 | 42 + .../pip/_internal/utils/egg_link.py | 75 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 27 + .../pip/_internal/utils/filesystem.py | 182 + .../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 | 343 + .../site-packages/pip/_internal/utils/misc.py | 653 ++ .../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 | 258 + .../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 -> 508 bytes .../vcs/__pycache__/bazaar.cpython-310.pyc | Bin 0 -> 3335 bytes .../vcs/__pycache__/git.cpython-310.pyc | Bin 0 -> 12538 bytes .../vcs/__pycache__/mercurial.cpython-310.pyc | Bin 0 -> 5054 bytes .../__pycache__/subversion.cpython-310.pyc | Bin 0 -> 8442 bytes .../versioncontrol.cpython-310.pyc | Bin 0 -> 21137 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 | 377 + .../site-packages/pip/_vendor/__init__.py | 111 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2908 bytes .../__pycache__/distro.cpython-310.pyc | Bin 0 -> 38226 bytes .../_vendor/__pycache__/six.cpython-310.pyc | Bin 0 -> 27575 bytes .../typing_extensions.cpython-310.pyc | Bin 0 -> 66571 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 636 bytes .../__pycache__/_cmd.cpython-310.pyc | Bin 0 -> 1574 bytes .../__pycache__/adapter.cpython-310.pyc | Bin 0 -> 3150 bytes .../__pycache__/cache.cpython-310.pyc | Bin 0 -> 1840 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 750 bytes .../__pycache__/controller.cpython-310.pyc | Bin 0 -> 8204 bytes .../__pycache__/filewrapper.cpython-310.pyc | Bin 0 -> 2786 bytes .../__pycache__/heuristics.cpython-310.pyc | Bin 0 -> 4710 bytes .../__pycache__/serialize.cpython-310.pyc | Bin 0 -> 4245 bytes .../__pycache__/wrapper.cpython-310.pyc | Bin 0 -> 681 bytes .../pip/_vendor/cachecontrol/_cmd.py | 61 + .../pip/_vendor/cachecontrol/adapter.py | 137 + .../pip/_vendor/cachecontrol/cache.py | 43 + .../_vendor/cachecontrol/caches/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 287 bytes .../__pycache__/file_cache.cpython-310.pyc | Bin 0 -> 3361 bytes .../__pycache__/redis_cache.cpython-310.pyc | Bin 0 -> 1567 bytes .../_vendor/cachecontrol/caches/file_cache.py | 150 + .../cachecontrol/caches/redis_cache.py | 37 + .../pip/_vendor/cachecontrol/compat.py | 32 + .../pip/_vendor/cachecontrol/controller.py | 415 + .../pip/_vendor/cachecontrol/filewrapper.py | 111 + .../pip/_vendor/cachecontrol/heuristics.py | 139 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 33 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 269 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 448 bytes .../certifi/__pycache__/core.cpython-310.pyc | Bin 0 -> 1507 bytes .../pip/_vendor/certifi/cacert.pem | 4362 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 76 + .../pip/_vendor/chardet/__init__.py | 83 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1893 bytes .../__pycache__/big5freq.cpython-310.pyc | Bin 0 -> 27172 bytes .../__pycache__/big5prober.cpython-310.pyc | Bin 0 -> 1123 bytes .../chardistribution.cpython-310.pyc | Bin 0 -> 5733 bytes .../charsetgroupprober.cpython-310.pyc | Bin 0 -> 2222 bytes .../__pycache__/charsetprober.cpython-310.pyc | Bin 0 -> 3476 bytes .../codingstatemachine.cpython-310.pyc | Bin 0 -> 2895 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 394 bytes .../__pycache__/cp949prober.cpython-310.pyc | Bin 0 -> 1130 bytes .../chardet/__pycache__/enums.cpython-310.pyc | Bin 0 -> 2577 bytes .../__pycache__/escprober.cpython-310.pyc | Bin 0 -> 2624 bytes .../chardet/__pycache__/escsm.cpython-310.pyc | Bin 0 -> 8371 bytes .../__pycache__/eucjpprober.cpython-310.pyc | Bin 0 -> 2426 bytes .../__pycache__/euckrfreq.cpython-310.pyc | Bin 0 -> 12056 bytes .../__pycache__/euckrprober.cpython-310.pyc | Bin 0 -> 1131 bytes .../__pycache__/euctwfreq.cpython-310.pyc | Bin 0 -> 27176 bytes .../__pycache__/euctwprober.cpython-310.pyc | Bin 0 -> 1131 bytes .../__pycache__/gb2312freq.cpython-310.pyc | Bin 0 -> 19100 bytes .../__pycache__/gb2312prober.cpython-310.pyc | Bin 0 -> 1139 bytes .../__pycache__/hebrewprober.cpython-310.pyc | Bin 0 -> 3012 bytes .../__pycache__/jisfreq.cpython-310.pyc | Bin 0 -> 22128 bytes .../__pycache__/jpcntx.cpython-310.pyc | Bin 0 -> 37635 bytes .../langbulgarianmodel.cpython-310.pyc | Bin 0 -> 47916 bytes .../langgreekmodel.cpython-310.pyc | Bin 0 -> 46106 bytes .../langhebrewmodel.cpython-310.pyc | Bin 0 -> 44555 bytes .../langhungarianmodel.cpython-310.pyc | Bin 0 -> 47876 bytes .../langrussianmodel.cpython-310.pyc | Bin 0 -> 61009 bytes .../__pycache__/langthaimodel.cpython-310.pyc | Bin 0 -> 44731 bytes .../langturkishmodel.cpython-310.pyc | Bin 0 -> 44572 bytes .../__pycache__/latin1prober.cpython-310.pyc | Bin 0 -> 4422 bytes .../mbcharsetprober.cpython-310.pyc | Bin 0 -> 2241 bytes .../mbcsgroupprober.cpython-310.pyc | Bin 0 -> 1126 bytes .../__pycache__/mbcssm.cpython-310.pyc | Bin 0 -> 18753 bytes .../sbcharsetprober.cpython-310.pyc | Bin 0 -> 3072 bytes .../sbcsgroupprober.cpython-310.pyc | Bin 0 -> 1695 bytes .../__pycache__/sjisprober.cpython-310.pyc | Bin 0 -> 2464 bytes .../universaldetector.cpython-310.pyc | Bin 0 -> 5818 bytes .../__pycache__/utf8prober.cpython-310.pyc | Bin 0 -> 1975 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 432 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 107 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 189 bytes .../__pycache__/chardetect.cpython-310.pyc | Bin 0 -> 2688 bytes .../pip/_vendor/chardet/cli/chardetect.py | 84 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 36 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4398 +++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5718 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 194 bytes .../__pycache__/languages.cpython-310.pyc | Bin 0 -> 7956 bytes .../pip/_vendor/chardet/metadata/languages.py | 310 + .../pip/_vendor/chardet/sbcharsetprober.py | 145 + .../pip/_vendor/chardet/sbcsgroupprober.py | 83 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 437 bytes .../colorama/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 2998 bytes .../__pycache__/ansitowin32.cpython-310.pyc | Bin 0 -> 7896 bytes .../__pycache__/initialise.cpython-310.pyc | Bin 0 -> 1684 bytes .../__pycache__/win32.cpython-310.pyc | Bin 0 -> 3944 bytes .../__pycache__/winterm.cpython-310.pyc | Bin 0 -> 4561 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 258 + .../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 -> 1056 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 31402 bytes .../__pycache__/database.cpython-310.pyc | Bin 0 -> 42857 bytes .../distlib/__pycache__/index.cpython-310.pyc | Bin 0 -> 17311 bytes .../__pycache__/locators.cpython-310.pyc | Bin 0 -> 38370 bytes .../__pycache__/manifest.cpython-310.pyc | Bin 0 -> 10224 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 5028 bytes .../__pycache__/metadata.cpython-310.pyc | Bin 0 -> 26556 bytes .../__pycache__/resources.cpython-310.pyc | Bin 0 -> 11030 bytes .../__pycache__/scripts.cpython-310.pyc | Bin 0 -> 11246 bytes .../distlib/__pycache__/util.cpython-310.pyc | Bin 0 -> 51689 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 20143 bytes .../distlib/__pycache__/wheel.cpython-310.pyc | Bin 0 -> 27303 bytes .../pip/_vendor/distlib/compat.py | 1116 +++ .../pip/_vendor/distlib/database.py | 1345 +++ .../pip/_vendor/distlib/index.py | 509 + .../pip/_vendor/distlib/locators.py | 1300 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 152 + .../pip/_vendor/distlib/metadata.py | 1058 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 429 + .../site-packages/pip/_vendor/distlib/util.py | 1932 ++++ .../pip/_vendor/distlib/version.py | 739 ++ .../pip/_vendor/distlib/wheel.py | 1053 ++ .../site-packages/pip/_vendor/distro.py | 1386 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1296 bytes .../__pycache__/_ihatexml.cpython-310.pyc | Bin 0 -> 13851 bytes .../__pycache__/_inputstream.cpython-310.pyc | Bin 0 -> 21668 bytes .../__pycache__/_tokenizer.cpython-310.pyc | Bin 0 -> 37314 bytes .../__pycache__/_utils.cpython-310.pyc | Bin 0 -> 4790 bytes .../__pycache__/constants.cpython-310.pyc | Bin 0 -> 161255 bytes .../__pycache__/html5parser.cpython-310.pyc | Bin 0 -> 88465 bytes .../__pycache__/serializer.cpython-310.pyc | Bin 0 -> 10731 bytes .../pip/_vendor/html5lib/_ihatexml.py | 289 + .../pip/_vendor/html5lib/_inputstream.py | 918 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1735 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 5 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 346 bytes .../_trie/__pycache__/_base.cpython-310.pyc | Bin 0 -> 1598 bytes .../_trie/__pycache__/py.cpython-310.pyc | Bin 0 -> 2261 bytes .../pip/_vendor/html5lib/_trie/_base.py | 40 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 159 + .../pip/_vendor/html5lib/constants.py | 2946 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 194 bytes .../alphabeticalattributes.cpython-310.pyc | Bin 0 -> 1324 bytes .../filters/__pycache__/base.cpython-310.pyc | Bin 0 -> 864 bytes .../inject_meta_charset.cpython-310.pyc | Bin 0 -> 1862 bytes .../filters/__pycache__/lint.cpython-310.pyc | Bin 0 -> 2570 bytes .../__pycache__/optionaltags.cpython-310.pyc | Bin 0 -> 2721 bytes .../__pycache__/sanitizer.cpython-310.pyc | Bin 0 -> 20018 bytes .../__pycache__/whitespace.cpython-310.pyc | Bin 0 -> 1368 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 916 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2795 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 935 bytes .../__pycache__/genshi.cpython-310.pyc | Bin 0 -> 1547 bytes .../__pycache__/sax.cpython-310.pyc | Bin 0 -> 1454 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3326 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 11317 bytes .../__pycache__/dom.cpython-310.pyc | Bin 0 -> 9404 bytes .../__pycache__/etree.cpython-310.pyc | Bin 0 -> 11706 bytes .../__pycache__/etree_lxml.cpython-310.pyc | Bin 0 -> 13021 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 239 + .../_vendor/html5lib/treebuilders/etree.py | 343 + .../html5lib/treebuilders/etree_lxml.py | 392 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 3976 bytes .../__pycache__/base.cpython-310.pyc | Bin 0 -> 6937 bytes .../__pycache__/dom.cpython-310.pyc | Bin 0 -> 1708 bytes .../__pycache__/etree.cpython-310.pyc | Bin 0 -> 3466 bytes .../__pycache__/etree_lxml.cpython-310.pyc | Bin 0 -> 6553 bytes .../__pycache__/genshi.cpython-310.pyc | Bin 0 -> 1914 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 131 + .../html5lib/treewalkers/etree_lxml.py | 215 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 841 bytes .../idna/__pycache__/codec.cpython-310.pyc | Bin 0 -> 2812 bytes .../idna/__pycache__/compat.cpython-310.pyc | Bin 0 -> 741 bytes .../idna/__pycache__/core.cpython-310.pyc | Bin 0 -> 9556 bytes .../idna/__pycache__/idnadata.cpython-310.pyc | Bin 0 -> 38219 bytes .../__pycache__/intranges.cpython-310.pyc | Bin 0 -> 1978 bytes .../__pycache__/package_data.cpython-310.pyc | Bin 0 -> 205 bytes .../__pycache__/uts46data.cpython-310.pyc | Bin 0 -> 150940 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 | 54 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1421 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 212 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 1802 bytes .../msgpack/__pycache__/ext.cpython-310.pyc | Bin 0 -> 6310 bytes .../__pycache__/fallback.cpython-310.pyc | Bin 0 -> 25439 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1012 ++ .../pip/_vendor/packaging/__about__.py | 26 + .../pip/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 584 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 440 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7294 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4606 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2699 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9281 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3969 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 21521 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12184 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3569 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12919 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 -> 307 bytes .../pep517/__pycache__/build.cpython-310.pyc | Bin 0 -> 3590 bytes .../pep517/__pycache__/check.cpython-310.pyc | Bin 0 -> 4554 bytes .../__pycache__/colorlog.cpython-310.pyc | Bin 0 -> 2958 bytes .../pep517/__pycache__/compat.cpython-310.pyc | Bin 0 -> 1531 bytes .../__pycache__/dirtools.cpython-310.pyc | Bin 0 -> 1349 bytes .../__pycache__/envbuild.cpython-310.pyc | Bin 0 -> 4372 bytes .../pep517/__pycache__/meta.cpython-310.pyc | Bin 0 -> 2954 bytes .../__pycache__/wrappers.cpython-310.pyc | Bin 0 -> 12300 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 -> 915 bytes .../__pycache__/_in_process.cpython-310.pyc | Bin 0 -> 10062 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 -> 99870 bytes .../__pycache__/py31compat.cpython-310.pyc | Bin 0 -> 654 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/platformdirs/__init__.py | 331 + .../pip/_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 10470 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 1230 bytes .../__pycache__/android.cpython-310.pyc | Bin 0 -> 4262 bytes .../__pycache__/api.cpython-310.pyc | Bin 0 -> 5196 bytes .../__pycache__/macos.cpython-310.pyc | Bin 0 -> 3184 bytes .../__pycache__/unix.cpython-310.pyc | Bin 0 -> 6885 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 289 bytes .../__pycache__/windows.cpython-310.pyc | Bin 0 -> 6428 bytes .../pip/_vendor/platformdirs/android.py | 119 + .../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/progress/__init__.py | 189 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5724 bytes .../progress/__pycache__/bar.cpython-310.pyc | Bin 0 -> 2689 bytes .../__pycache__/colors.cpython-310.pyc | Bin 0 -> 1482 bytes .../__pycache__/counter.cpython-310.pyc | Bin 0 -> 1553 bytes .../__pycache__/spinner.cpython-310.pyc | Bin 0 -> 1383 bytes .../site-packages/pip/_vendor/progress/bar.py | 93 + .../pip/_vendor/progress/colors.py | 79 + .../pip/_vendor/progress/counter.py | 47 + .../pip/_vendor/progress/spinner.py | 45 + .../pip/_vendor/pygments/__init__.py | 83 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2986 bytes .../__pycache__/__main__.cpython-310.pyc | Bin 0 -> 582 bytes .../__pycache__/cmdline.cpython-310.pyc | Bin 0 -> 15445 bytes .../__pycache__/console.cpython-310.pyc | Bin 0 -> 1877 bytes .../__pycache__/filter.cpython-310.pyc | Bin 0 -> 2648 bytes .../__pycache__/formatter.cpython-310.pyc | Bin 0 -> 3004 bytes .../__pycache__/lexer.cpython-310.pyc | Bin 0 -> 24358 bytes .../__pycache__/modeline.cpython-310.pyc | Bin 0 -> 1186 bytes .../__pycache__/plugin.cpython-310.pyc | Bin 0 -> 2038 bytes .../__pycache__/regexopt.cpython-310.pyc | Bin 0 -> 2950 bytes .../__pycache__/scanner.cpython-310.pyc | Bin 0 -> 3551 bytes .../__pycache__/sphinxext.cpython-310.pyc | Bin 0 -> 4536 bytes .../__pycache__/style.cpython-310.pyc | Bin 0 -> 4573 bytes .../__pycache__/token.cpython-310.pyc | Bin 0 -> 4645 bytes .../__pycache__/unistring.cpython-310.pyc | Bin 0 -> 31199 bytes .../pygments/__pycache__/util.cpython-310.pyc | Bin 0 -> 9156 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 -> 4662 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 5529 bytes .../__pycache__/bbcode.cpython-310.pyc | Bin 0 -> 3079 bytes .../__pycache__/groff.cpython-310.pyc | Bin 0 -> 4352 bytes .../__pycache__/html.cpython-310.pyc | Bin 0 -> 29063 bytes .../__pycache__/img.cpython-310.pyc | Bin 0 -> 17491 bytes .../__pycache__/irc.cpython-310.pyc | Bin 0 -> 4582 bytes .../__pycache__/latex.cpython-310.pyc | Bin 0 -> 13488 bytes .../__pycache__/other.cpython-310.pyc | Bin 0 -> 4798 bytes .../__pycache__/pangomarkup.cpython-310.pyc | Bin 0 -> 2098 bytes .../__pycache__/rtf.cpython-310.pyc | Bin 0 -> 4128 bytes .../__pycache__/svg.cpython-310.pyc | Bin 0 -> 6326 bytes .../__pycache__/terminal.cpython-310.pyc | Bin 0 -> 3993 bytes .../__pycache__/terminal256.cpython-310.pyc | Bin 0 -> 9243 bytes .../_vendor/pygments/formatters/_mapping.py | 84 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 168 + .../pip/_vendor/pygments/formatters/html.py | 983 ++ .../pip/_vendor/pygments/formatters/img.py | 641 ++ .../pip/_vendor/pygments/formatters/irc.py | 179 + .../pip/_vendor/pygments/formatters/latex.py | 511 + .../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 | 879 ++ .../pip/_vendor/pygments/lexers/__init__.py | 341 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9178 bytes .../__pycache__/_mapping.cpython-310.pyc | Bin 0 -> 58116 bytes .../lexers/__pycache__/python.cpython-310.pyc | Bin 0 -> 29377 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 580 ++ .../pip/_vendor/pygments/lexers/python.py | 1188 +++ .../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 -> 3214 bytes .../pip/_vendor/pygments/token.py | 212 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 308 + .../pip/_vendor/pyparsing/__init__.py | 328 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 7119 bytes .../__pycache__/actions.cpython-310.pyc | Bin 0 -> 7176 bytes .../__pycache__/common.cpython-310.pyc | Bin 0 -> 10099 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 175229 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 9066 bytes .../__pycache__/helpers.cpython-310.pyc | Bin 0 -> 34761 bytes .../__pycache__/results.cpython-310.pyc | Bin 0 -> 24773 bytes .../__pycache__/testing.cpython-310.pyc | Bin 0 -> 12094 bytes .../__pycache__/unicode.cpython-310.pyc | Bin 0 -> 9808 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 8599 bytes .../pip/_vendor/pyparsing/actions.py | 207 + .../pip/_vendor/pyparsing/common.py | 424 + .../pip/_vendor/pyparsing/core.py | 5789 +++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 593 ++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 15639 bytes .../pip/_vendor/pyparsing/exceptions.py | 267 + .../pip/_vendor/pyparsing/helpers.py | 1069 +++ .../pip/_vendor/pyparsing/results.py | 760 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 332 + .../pip/_vendor/pyparsing/util.py | 235 + .../pip/_vendor/requests/__init__.py | 154 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4032 bytes .../__pycache__/__version__.cpython-310.pyc | Bin 0 -> 549 bytes .../_internal_utils.cpython-310.pyc | Bin 0 -> 1301 bytes .../__pycache__/adapters.cpython-310.pyc | Bin 0 -> 17037 bytes .../requests/__pycache__/api.cpython-310.pyc | Bin 0 -> 6648 bytes .../requests/__pycache__/auth.cpython-310.pyc | Bin 0 -> 8091 bytes .../__pycache__/certs.cpython-310.pyc | Bin 0 -> 633 bytes .../__pycache__/compat.cpython-310.pyc | Bin 0 -> 1668 bytes .../__pycache__/cookies.cpython-310.pyc | Bin 0 -> 18681 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5242 bytes .../requests/__pycache__/help.cpython-310.pyc | Bin 0 -> 2901 bytes .../__pycache__/hooks.cpython-310.pyc | Bin 0 -> 988 bytes .../__pycache__/models.cpython-310.pyc | Bin 0 -> 24307 bytes .../__pycache__/packages.cpython-310.pyc | Bin 0 -> 502 bytes .../__pycache__/sessions.cpython-310.pyc | Bin 0 -> 19615 bytes .../__pycache__/status_codes.cpython-310.pyc | Bin 0 -> 4665 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 4447 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 24390 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 538 ++ .../site-packages/pip/_vendor/requests/api.py | 159 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 77 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 133 + .../pip/_vendor/requests/help.py | 132 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 973 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 771 ++ .../pip/_vendor/requests/status_codes.py | 123 + .../pip/_vendor/requests/structures.py | 105 + .../pip/_vendor/requests/utils.py | 1060 ++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 600 bytes .../__pycache__/providers.cpython-310.pyc | Bin 0 -> 6651 bytes .../__pycache__/reporters.cpython-310.pyc | Bin 0 -> 2571 bytes .../__pycache__/resolvers.cpython-310.pyc | Bin 0 -> 15124 bytes .../__pycache__/structs.cpython-310.pyc | Bin 0 -> 7157 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 195 bytes .../collections_abc.cpython-310.pyc | Bin 0 -> 371 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 | 172 + .../pip/_vendor/rich/__main__.py | 280 + .../rich/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 5885 bytes .../rich/__pycache__/__main__.cpython-310.pyc | Bin 0 -> 7319 bytes .../__pycache__/_cell_widths.cpython-310.pyc | Bin 0 -> 7808 bytes .../__pycache__/_emoji_codes.cpython-310.pyc | Bin 0 -> 360048 bytes .../_emoji_replace.cpython-310.pyc | Bin 0 -> 1188 bytes .../__pycache__/_extension.cpython-310.pyc | Bin 0 -> 489 bytes .../rich/__pycache__/_inspect.cpython-310.pyc | Bin 0 -> 6606 bytes .../__pycache__/_log_render.cpython-310.pyc | Bin 0 -> 2634 bytes .../rich/__pycache__/_loop.cpython-310.pyc | Bin 0 -> 1286 bytes .../__pycache__/_lru_cache.cpython-310.pyc | Bin 0 -> 1569 bytes .../__pycache__/_palettes.cpython-310.pyc | Bin 0 -> 5091 bytes .../rich/__pycache__/_pick.cpython-310.pyc | Bin 0 -> 634 bytes .../rich/__pycache__/_ratio.cpython-310.pyc | Bin 0 -> 5151 bytes .../__pycache__/_spinners.cpython-310.pyc | Bin 0 -> 15207 bytes .../rich/__pycache__/_stack.cpython-310.pyc | Bin 0 -> 832 bytes .../rich/__pycache__/_timer.cpython-310.pyc | Bin 0 -> 681 bytes .../rich/__pycache__/_windows.cpython-310.pyc | Bin 0 -> 1872 bytes .../rich/__pycache__/_wrap.cpython-310.pyc | Bin 0 -> 1510 bytes .../rich/__pycache__/abc.cpython-310.pyc | Bin 0 -> 1308 bytes .../rich/__pycache__/align.cpython-310.pyc | Bin 0 -> 7962 bytes .../rich/__pycache__/ansi.cpython-310.pyc | Bin 0 -> 6011 bytes .../rich/__pycache__/bar.cpython-310.pyc | Bin 0 -> 2977 bytes .../rich/__pycache__/box.cpython-310.pyc | Bin 0 -> 7751 bytes .../rich/__pycache__/cells.cpython-310.pyc | Bin 0 -> 3493 bytes .../rich/__pycache__/color.cpython-310.pyc | Bin 0 -> 16749 bytes .../__pycache__/color_triplet.cpython-310.pyc | Bin 0 -> 1431 bytes .../rich/__pycache__/columns.cpython-310.pyc | Bin 0 -> 6191 bytes .../rich/__pycache__/console.cpython-310.pyc | Bin 0 -> 70436 bytes .../__pycache__/constrain.cpython-310.pyc | Bin 0 -> 1748 bytes .../__pycache__/containers.cpython-310.pyc | Bin 0 -> 6480 bytes .../rich/__pycache__/control.cpython-310.pyc | Bin 0 -> 6823 bytes .../default_styles.cpython-310.pyc | Bin 0 -> 6023 bytes .../rich/__pycache__/diagnose.cpython-310.pyc | Bin 0 -> 349 bytes .../rich/__pycache__/emoji.cpython-310.pyc | Bin 0 -> 3261 bytes .../rich/__pycache__/errors.cpython-310.pyc | Bin 0 -> 1521 bytes .../__pycache__/file_proxy.cpython-310.pyc | Bin 0 -> 2258 bytes .../rich/__pycache__/filesize.cpython-310.pyc | Bin 0 -> 2610 bytes .../__pycache__/highlighter.cpython-310.pyc | Bin 0 -> 5337 bytes .../rich/__pycache__/json.cpython-310.pyc | Bin 0 -> 4741 bytes .../rich/__pycache__/jupyter.cpython-310.pyc | Bin 0 -> 3820 bytes .../rich/__pycache__/layout.cpython-310.pyc | Bin 0 -> 14672 bytes .../rich/__pycache__/live.cpython-310.pyc | Bin 0 -> 11562 bytes .../__pycache__/live_render.cpython-310.pyc | Bin 0 -> 3396 bytes .../rich/__pycache__/logging.cpython-310.pyc | Bin 0 -> 9288 bytes .../rich/__pycache__/markup.cpython-310.pyc | Bin 0 -> 5907 bytes .../rich/__pycache__/measure.cpython-310.pyc | Bin 0 -> 5052 bytes .../rich/__pycache__/padding.cpython-310.pyc | Bin 0 -> 4476 bytes .../rich/__pycache__/pager.cpython-310.pyc | Bin 0 -> 1489 bytes .../rich/__pycache__/palette.cpython-310.pyc | Bin 0 -> 3702 bytes .../rich/__pycache__/panel.cpython-310.pyc | Bin 0 -> 6385 bytes .../rich/__pycache__/pretty.cpython-310.pyc | Bin 0 -> 25097 bytes .../rich/__pycache__/progress.cpython-310.pyc | Bin 0 -> 33325 bytes .../__pycache__/progress_bar.cpython-310.pyc | Bin 0 -> 6701 bytes .../rich/__pycache__/prompt.cpython-310.pyc | Bin 0 -> 11293 bytes .../rich/__pycache__/protocol.cpython-310.pyc | Bin 0 -> 1365 bytes .../rich/__pycache__/region.cpython-310.pyc | Bin 0 -> 521 bytes .../rich/__pycache__/repr.cpython-310.pyc | Bin 0 -> 4034 bytes .../rich/__pycache__/rule.cpython-310.pyc | Bin 0 -> 3731 bytes .../rich/__pycache__/scope.cpython-310.pyc | Bin 0 -> 2982 bytes .../rich/__pycache__/screen.cpython-310.pyc | Bin 0 -> 1873 bytes .../rich/__pycache__/segment.cpython-310.pyc | Bin 0 -> 20563 bytes .../rich/__pycache__/spinner.cpython-310.pyc | Bin 0 -> 4393 bytes .../rich/__pycache__/status.cpython-310.pyc | Bin 0 -> 4587 bytes .../rich/__pycache__/style.cpython-310.pyc | Bin 0 -> 20516 bytes .../rich/__pycache__/styled.cpython-310.pyc | Bin 0 -> 1757 bytes .../rich/__pycache__/syntax.cpython-310.pyc | Bin 0 -> 19030 bytes .../rich/__pycache__/table.cpython-310.pyc | Bin 0 -> 26968 bytes .../rich/__pycache__/tabulate.cpython-310.pyc | Bin 0 -> 1750 bytes .../terminal_theme.cpython-310.pyc | Bin 0 -> 1714 bytes .../rich/__pycache__/text.cpython-310.pyc | Bin 0 -> 39278 bytes .../rich/__pycache__/theme.cpython-310.pyc | Bin 0 -> 4694 bytes .../rich/__pycache__/themes.cpython-310.pyc | Bin 0 -> 287 bytes .../__pycache__/traceback.cpython-310.pyc | Bin 0 -> 19531 bytes .../rich/__pycache__/tree.cpython-310.pyc | Bin 0 -> 7311 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/_extension.py | 10 + .../pip/_vendor/rich/_inspect.py | 210 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_lru_cache.py | 34 + .../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 | 848 ++ .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_windows.py | 72 + .../site-packages/pip/_vendor/rich/_wrap.py | 55 + .../site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 312 + .../site-packages/pip/_vendor/rich/ansi.py | 228 + .../site-packages/pip/_vendor/rich/bar.py | 94 + .../site-packages/pip/_vendor/rich/box.py | 483 + .../site-packages/pip/_vendor/rich/cells.py | 147 + .../site-packages/pip/_vendor/rich/color.py | 581 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2211 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 175 + .../pip/_vendor/rich/default_styles.py | 183 + .../pip/_vendor/rich/diagnose.py | 6 + .../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 | 147 + .../site-packages/pip/_vendor/rich/json.py | 140 + .../site-packages/pip/_vendor/rich/jupyter.py | 92 + .../site-packages/pip/_vendor/rich/layout.py | 444 + .../site-packages/pip/_vendor/rich/live.py | 365 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 268 + .../site-packages/pip/_vendor/rich/markup.py | 244 + .../site-packages/pip/_vendor/rich/measure.py | 149 + .../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 | 250 + .../site-packages/pip/_vendor/rich/pretty.py | 903 ++ .../pip/_vendor/rich/progress.py | 1036 ++ .../pip/_vendor/rich/progress_bar.py | 216 + .../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 | 151 + .../site-packages/pip/_vendor/rich/rule.py | 115 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 720 ++ .../site-packages/pip/_vendor/rich/spinner.py | 134 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 785 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 735 ++ .../site-packages/pip/_vendor/rich/table.py | 968 ++ .../pip/_vendor/rich/tabulate.py | 51 + .../pip/_vendor/rich/terminal_theme.py | 55 + .../site-packages/pip/_vendor/rich/text.py | 1282 +++ .../site-packages/pip/_vendor/rich/theme.py | 112 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 678 ++ .../site-packages/pip/_vendor/rich/tree.py | 249 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 517 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 16368 bytes .../__pycache__/_asyncio.cpython-310.pyc | Bin 0 -> 2608 bytes .../__pycache__/_utils.cpython-310.pyc | Bin 0 -> 1221 bytes .../__pycache__/after.cpython-310.pyc | Bin 0 -> 1225 bytes .../__pycache__/before.cpython-310.pyc | Bin 0 -> 1103 bytes .../__pycache__/before_sleep.cpython-310.pyc | Bin 0 -> 1405 bytes .../tenacity/__pycache__/nap.cpython-310.pyc | Bin 0 -> 1193 bytes .../__pycache__/retry.cpython-310.pyc | Bin 0 -> 8423 bytes .../tenacity/__pycache__/stop.cpython-310.pyc | Bin 0 -> 4011 bytes .../__pycache__/tornadoweb.cpython-310.pyc | Bin 0 -> 1758 bytes .../tenacity/__pycache__/wait.cpython-310.pyc | Bin 0 -> 7955 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 | 6 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 373 bytes .../tomli/__pycache__/_parser.cpython-310.pyc | Bin 0 -> 16327 bytes .../tomli/__pycache__/_re.cpython-310.pyc | Bin 0 -> 2417 bytes .../pip/_vendor/tomli/_parser.py | 703 ++ .../site-packages/pip/_vendor/tomli/_re.py | 83 + .../pip/_vendor/typing_extensions.py | 2296 +++++ .../pip/_vendor/urllib3/__init__.py | 85 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2183 bytes .../__pycache__/_collections.cpython-310.pyc | Bin 0 -> 11348 bytes .../__pycache__/_version.cpython-310.pyc | Bin 0 -> 207 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 13630 bytes .../connectionpool.cpython-310.pyc | Bin 0 -> 25472 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 10988 bytes .../__pycache__/fields.cpython-310.pyc | Bin 0 -> 8177 bytes .../__pycache__/filepost.cpython-310.pyc | Bin 0 -> 2744 bytes .../__pycache__/poolmanager.cpython-310.pyc | Bin 0 -> 15292 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 5620 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 20911 bytes .../pip/_vendor/urllib3/_collections.py | 355 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 569 ++ .../pip/_vendor/urllib3/connectionpool.py | 1113 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 193 bytes .../_appengine_environ.cpython-310.pyc | Bin 0 -> 1373 bytes .../__pycache__/appengine.cpython-310.pyc | Bin 0 -> 8189 bytes .../__pycache__/ntlmpool.cpython-310.pyc | Bin 0 -> 3628 bytes .../__pycache__/pyopenssl.cpython-310.pyc | Bin 0 -> 15530 bytes .../securetransport.cpython-310.pyc | Bin 0 -> 21935 bytes .../contrib/__pycache__/socks.cpython-310.pyc | Bin 0 -> 5595 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 210 bytes .../__pycache__/bindings.cpython-310.pyc | Bin 0 -> 10706 bytes .../__pycache__/low_level.cpython-310.pyc | Bin 0 -> 9093 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 | 511 + .../urllib3/contrib/securetransport.py | 922 ++ .../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 -> 194 bytes .../packages/__pycache__/six.cpython-310.pyc | Bin 0 -> 27648 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 204 bytes .../__pycache__/makefile.cpython-310.pyc | Bin 0 -> 1304 bytes .../urllib3/packages/backports/makefile.py | 51 + .../pip/_vendor/urllib3/packages/six.py | 1077 +++ .../pip/_vendor/urllib3/poolmanager.py | 539 ++ .../pip/_vendor/urllib3/request.py | 170 + .../pip/_vendor/urllib3/response.py | 821 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1103 bytes .../__pycache__/connection.cpython-310.pyc | Bin 0 -> 3431 bytes .../util/__pycache__/proxy.cpython-310.pyc | Bin 0 -> 1336 bytes .../util/__pycache__/queue.cpython-310.pyc | Bin 0 -> 1058 bytes .../util/__pycache__/request.cpython-310.pyc | Bin 0 -> 3466 bytes .../util/__pycache__/response.cpython-310.pyc | Bin 0 -> 2351 bytes .../util/__pycache__/retry.cpython-310.pyc | Bin 0 -> 16146 bytes .../util/__pycache__/ssl_.cpython-310.pyc | Bin 0 -> 11303 bytes .../ssl_match_hostname.cpython-310.pyc | Bin 0 -> 3275 bytes .../__pycache__/ssltransport.cpython-310.pyc | Bin 0 -> 7393 bytes .../util/__pycache__/timeout.cpython-310.pyc | Bin 0 -> 8927 bytes .../util/__pycache__/url.cpython-310.pyc | Bin 0 -> 10672 bytes .../util/__pycache__/wait.cpython-310.pyc | Bin 0 -> 3087 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 | 143 + .../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 | 161 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 268 + .../pip/_vendor/urllib3/util/url.py | 432 + .../pip/_vendor/urllib3/util/wait.py | 153 + .../site-packages/pip/_vendor/vendor.txt | 25 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 9740 bytes .../__pycache__/labels.cpython-310.pyc | Bin 0 -> 5230 bytes .../__pycache__/mklabels.cpython-310.pyc | Bin 0 -> 1935 bytes .../__pycache__/tests.cpython-310.pyc | Bin 0 -> 5037 bytes .../x_user_defined.cpython-310.pyc | Bin 0 -> 2586 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 + .../lib/python3.10/site-packages/pip/py.typed | 4 + .../site-packages/pkg_resources/__init__.py | 3303 +++++++ .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 100595 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 187 bytes .../__pycache__/appdirs.cpython-310.pyc | Bin 0 -> 20248 bytes .../__pycache__/pyparsing.cpython-310.pyc | Bin 0 -> 198740 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 26 + .../_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-310.pyc | Bin 0 -> 594 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 450 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7304 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4616 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2974 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9300 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3988 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 22192 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12218 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3579 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12929 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 67 + .../_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 828 ++ .../pkg_resources/_vendor/packaging/tags.py | 484 + .../pkg_resources/_vendor/packaging/utils.py | 136 + .../_vendor/packaging/version.py | 504 + .../pkg_resources/_vendor/pyparsing.py | 5742 +++++++++++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2895 bytes .../__pycache__/setup.cpython-310.pyc | Bin 0 -> 315 bytes .../data/my-test-package-source/setup.py | 6 + .../setuptools-59.6.0.dist-info/INSTALLER | 1 + .../setuptools-59.6.0.dist-info/LICENSE | 19 + .../setuptools-59.6.0.dist-info/METADATA | 124 + .../setuptools-59.6.0.dist-info/RECORD | 298 + .../setuptools-59.6.0.dist-info/REQUESTED | 0 .../setuptools-59.6.0.dist-info/WHEEL | 5 + .../entry_points.txt | 56 + .../setuptools-59.6.0.dist-info/top_level.txt | 4 + .../site-packages/setuptools/__init__.py | 242 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 8591 bytes .../_deprecation_warning.cpython-310.pyc | Bin 0 -> 548 bytes .../__pycache__/_imp.cpython-310.pyc | Bin 0 -> 2074 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 5844 bytes .../__pycache__/build_meta.cpython-310.pyc | Bin 0 -> 9458 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 20927 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 855 bytes .../__pycache__/depends.cpython-310.pyc | Bin 0 -> 5294 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 36335 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 1500 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 1944 bytes .../__pycache__/glob.cpython-310.pyc | Bin 0 -> 3733 bytes .../__pycache__/installer.cpython-310.pyc | Bin 0 -> 2979 bytes .../__pycache__/launch.cpython-310.pyc | Bin 0 -> 905 bytes .../__pycache__/monkey.cpython-310.pyc | Bin 0 -> 4633 bytes .../__pycache__/msvc.cpython-310.pyc | Bin 0 -> 42637 bytes .../__pycache__/namespaces.cpython-310.pyc | Bin 0 -> 3616 bytes .../__pycache__/package_index.cpython-310.pyc | Bin 0 -> 32729 bytes .../__pycache__/py34compat.cpython-310.pyc | Bin 0 -> 480 bytes .../__pycache__/sandbox.cpython-310.pyc | Bin 0 -> 15756 bytes .../__pycache__/unicode_utils.cpython-310.pyc | Bin 0 -> 1110 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 322 bytes .../__pycache__/wheel.cpython-310.pyc | Bin 0 -> 7348 bytes .../windows_support.cpython-310.pyc | Bin 0 -> 1023 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 24 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 556 bytes .../__pycache__/_msvccompiler.cpython-310.pyc | Bin 0 -> 13833 bytes .../__pycache__/archive_util.cpython-310.pyc | Bin 0 -> 6561 bytes .../__pycache__/bcppcompiler.cpython-310.pyc | Bin 0 -> 6548 bytes .../__pycache__/ccompiler.cpython-310.pyc | Bin 0 -> 33305 bytes .../__pycache__/cmd.cpython-310.pyc | Bin 0 -> 13948 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 3587 bytes .../__pycache__/core.cpython-310.pyc | Bin 0 -> 7088 bytes .../cygwinccompiler.cpython-310.pyc | Bin 0 -> 8995 bytes .../__pycache__/debug.cpython-310.pyc | Bin 0 -> 250 bytes .../__pycache__/dep_util.cpython-310.pyc | Bin 0 -> 2771 bytes .../__pycache__/dir_util.cpython-310.pyc | Bin 0 -> 5882 bytes .../__pycache__/dist.cpython-310.pyc | Bin 0 -> 34047 bytes .../__pycache__/errors.cpython-310.pyc | Bin 0 -> 4992 bytes .../__pycache__/extension.cpython-310.pyc | Bin 0 -> 7006 bytes .../__pycache__/fancy_getopt.cpython-310.pyc | Bin 0 -> 10630 bytes .../__pycache__/file_util.cpython-310.pyc | Bin 0 -> 5976 bytes .../__pycache__/filelist.cpython-310.pyc | Bin 0 -> 10822 bytes .../__pycache__/log.cpython-310.pyc | Bin 0 -> 2307 bytes .../__pycache__/msvc9compiler.cpython-310.pyc | Bin 0 -> 17562 bytes .../__pycache__/msvccompiler.cpython-310.pyc | Bin 0 -> 14781 bytes .../__pycache__/py35compat.cpython-310.pyc | Bin 0 -> 626 bytes .../__pycache__/py38compat.cpython-310.pyc | Bin 0 -> 423 bytes .../__pycache__/spawn.cpython-310.pyc | Bin 0 -> 2893 bytes .../__pycache__/sysconfig.cpython-310.pyc | Bin 0 -> 12874 bytes .../__pycache__/text_file.cpython-310.pyc | Bin 0 -> 8469 bytes .../__pycache__/unixccompiler.cpython-310.pyc | Bin 0 -> 6801 bytes .../__pycache__/util.cpython-310.pyc | Bin 0 -> 14742 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 7843 bytes .../versionpredicate.cpython-310.pyc | Bin 0 -> 5336 bytes .../setuptools/_distutils/_msvccompiler.py | 561 ++ .../setuptools/_distutils/archive_util.py | 256 + .../setuptools/_distutils/bcppcompiler.py | 393 + .../setuptools/_distutils/ccompiler.py | 1123 +++ .../setuptools/_distutils/cmd.py | 403 + .../setuptools/_distutils/command/__init__.py | 31 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 529 bytes .../command/__pycache__/bdist.cpython-310.pyc | Bin 0 -> 3663 bytes .../__pycache__/bdist_dumb.cpython-310.pyc | Bin 0 -> 3642 bytes .../__pycache__/bdist_msi.cpython-310.pyc | Bin 0 -> 19718 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 12286 bytes .../__pycache__/bdist_wininst.cpython-310.pyc | Bin 0 -> 8629 bytes .../command/__pycache__/build.cpython-310.pyc | Bin 0 -> 3891 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 4868 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 16216 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 9887 bytes .../__pycache__/build_scripts.cpython-310.pyc | Bin 0 -> 4010 bytes .../command/__pycache__/check.cpython-310.pyc | Bin 0 -> 5007 bytes .../command/__pycache__/clean.cpython-310.pyc | Bin 0 -> 2146 bytes .../__pycache__/config.cpython-310.pyc | Bin 0 -> 10328 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 15266 bytes .../__pycache__/install_data.cpython-310.pyc | Bin 0 -> 2345 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 3310 bytes .../install_headers.cpython-310.pyc | Bin 0 -> 1768 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 5170 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2197 bytes .../__pycache__/py37compat.cpython-310.pyc | Bin 0 -> 1038 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 8681 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 14497 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 5373 bytes .../setuptools/_distutils/command/bdist.py | 143 + .../_distutils/command/bdist_dumb.py | 123 + .../_distutils/command/bdist_msi.py | 749 ++ .../_distutils/command/bdist_rpm.py | 579 ++ .../_distutils/command/bdist_wininst.py | 377 + .../setuptools/_distutils/command/build.py | 157 + .../_distutils/command/build_clib.py | 209 + .../_distutils/command/build_ext.py | 755 ++ .../setuptools/_distutils/command/build_py.py | 392 + .../_distutils/command/build_scripts.py | 152 + .../setuptools/_distutils/command/check.py | 148 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 344 + .../setuptools/_distutils/command/install.py | 721 ++ .../_distutils/command/install_data.py | 79 + .../_distutils/command/install_egg_info.py | 84 + .../_distutils/command/install_headers.py | 47 + .../_distutils/command/install_lib.py | 217 + .../_distutils/command/install_scripts.py | 60 + .../_distutils/command/py37compat.py | 30 + .../setuptools/_distutils/command/register.py | 304 + .../setuptools/_distutils/command/sdist.py | 494 + .../setuptools/_distutils/command/upload.py | 214 + .../setuptools/_distutils/config.py | 130 + .../setuptools/_distutils/core.py | 249 + .../setuptools/_distutils/cygwinccompiler.py | 425 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 92 + .../setuptools/_distutils/dir_util.py | 210 + .../setuptools/_distutils/dist.py | 1257 +++ .../setuptools/_distutils/errors.py | 97 + .../setuptools/_distutils/extension.py | 240 + .../setuptools/_distutils/fancy_getopt.py | 457 + .../setuptools/_distutils/file_util.py | 238 + .../setuptools/_distutils/filelist.py | 355 + .../setuptools/_distutils/log.py | 77 + .../setuptools/_distutils/msvc9compiler.py | 788 ++ .../setuptools/_distutils/msvccompiler.py | 643 ++ .../setuptools/_distutils/py35compat.py | 19 + .../setuptools/_distutils/py38compat.py | 7 + .../setuptools/_distutils/spawn.py | 106 + .../setuptools/_distutils/sysconfig.py | 601 ++ .../setuptools/_distutils/text_file.py | 286 + .../setuptools/_distutils/unixccompiler.py | 325 + .../setuptools/_distutils/util.py | 548 ++ .../setuptools/_distutils/version.py | 363 + .../setuptools/_distutils/versionpredicate.py | 169 + .../site-packages/setuptools/_imp.py | 82 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 184 bytes .../__pycache__/ordered_set.cpython-310.pyc | Bin 0 -> 16320 bytes .../__pycache__/pyparsing.cpython-310.pyc | Bin 0 -> 198737 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 265 bytes .../__pycache__/more.cpython-310.pyc | Bin 0 -> 109983 bytes .../__pycache__/recipes.cpython-310.pyc | Bin 0 -> 17965 bytes .../setuptools/_vendor/more_itertools/more.py | 3825 ++++++++ .../_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 -> 591 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 447 bytes .../__pycache__/_manylinux.cpython-310.pyc | Bin 0 -> 7301 bytes .../__pycache__/_musllinux.cpython-310.pyc | Bin 0 -> 4613 bytes .../__pycache__/_structures.cpython-310.pyc | Bin 0 -> 2971 bytes .../__pycache__/markers.cpython-310.pyc | Bin 0 -> 9294 bytes .../__pycache__/requirements.cpython-310.pyc | Bin 0 -> 3982 bytes .../__pycache__/specifiers.cpython-310.pyc | Bin 0 -> 22189 bytes .../__pycache__/tags.cpython-310.pyc | Bin 0 -> 12215 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 3576 bytes .../__pycache__/version.cpython-310.pyc | Bin 0 -> 12926 bytes .../_vendor/packaging/_manylinux.py | 301 + .../_vendor/packaging/_musllinux.py | 136 + .../_vendor/packaging/_structures.py | 67 + .../setuptools/_vendor/packaging/markers.py | 304 + .../_vendor/packaging/requirements.py | 146 + .../_vendor/packaging/specifiers.py | 828 ++ .../setuptools/_vendor/packaging/tags.py | 484 + .../setuptools/_vendor/packaging/utils.py | 136 + .../setuptools/_vendor/packaging/version.py | 504 + .../setuptools/_vendor/pyparsing.py | 5742 +++++++++++ .../site-packages/setuptools/archive_util.py | 205 + .../site-packages/setuptools/build_meta.py | 290 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli-arm64.exe | Bin 0 -> 137216 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 8 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 373 bytes .../command/__pycache__/alias.cpython-310.pyc | Bin 0 -> 2375 bytes .../__pycache__/bdist_egg.cpython-310.pyc | Bin 0 -> 13101 bytes .../__pycache__/bdist_rpm.cpython-310.pyc | Bin 0 -> 1588 bytes .../__pycache__/build_clib.cpython-310.pyc | Bin 0 -> 2462 bytes .../__pycache__/build_ext.cpython-310.pyc | Bin 0 -> 9891 bytes .../__pycache__/build_py.cpython-310.pyc | Bin 0 -> 8264 bytes .../__pycache__/develop.cpython-310.pyc | Bin 0 -> 6151 bytes .../__pycache__/dist_info.cpython-310.pyc | Bin 0 -> 1393 bytes .../__pycache__/easy_install.cpython-310.pyc | Bin 0 -> 65170 bytes .../__pycache__/egg_info.cpython-310.pyc | Bin 0 -> 22749 bytes .../__pycache__/install.cpython-310.pyc | Bin 0 -> 4199 bytes .../install_egg_info.cpython-310.pyc | Bin 0 -> 2924 bytes .../__pycache__/install_lib.cpython-310.pyc | Bin 0 -> 5139 bytes .../install_scripts.cpython-310.pyc | Bin 0 -> 2428 bytes .../__pycache__/py36compat.cpython-310.pyc | Bin 0 -> 4535 bytes .../__pycache__/register.cpython-310.pyc | Bin 0 -> 839 bytes .../__pycache__/rotate.cpython-310.pyc | Bin 0 -> 2506 bytes .../__pycache__/saveopts.cpython-310.pyc | Bin 0 -> 925 bytes .../command/__pycache__/sdist.cpython-310.pyc | Bin 0 -> 6954 bytes .../__pycache__/setopt.cpython-310.pyc | Bin 0 -> 4687 bytes .../command/__pycache__/test.cpython-310.pyc | Bin 0 -> 8131 bytes .../__pycache__/upload.cpython-310.pyc | Bin 0 -> 812 bytes .../__pycache__/upload_docs.cpython-310.pyc | Bin 0 -> 6181 bytes .../site-packages/setuptools/command/alias.py | 78 + .../setuptools/command/bdist_egg.py | 456 + .../setuptools/command/bdist_rpm.py | 40 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_py.py | 242 + .../setuptools/command/develop.py | 193 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2354 +++++ .../setuptools/command/egg_info.py | 755 ++ .../setuptools/command/install.py | 132 + .../setuptools/command/install_egg_info.py | 82 + .../setuptools/command/install_lib.py | 148 + .../setuptools/command/install_scripts.py | 69 + .../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 | 252 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 202 + .../site-packages/setuptools/config.py | 751 ++ .../site-packages/setuptools/dep_util.py | 25 + .../site-packages/setuptools/depends.py | 176 + .../site-packages/setuptools/dist.py | 1156 +++ .../site-packages/setuptools/errors.py | 40 + .../site-packages/setuptools/extension.py | 55 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 2934 bytes .../site-packages/setuptools/glob.py | 167 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui-arm64.exe | Bin 0 -> 137728 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/installer.py | 104 + .../site-packages/setuptools/launch.py | 36 + .../site-packages/setuptools/monkey.py | 177 + .../site-packages/setuptools/msvc.py | 1805 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1127 +++ .../site-packages/setuptools/py34compat.py | 13 + .../site-packages/setuptools/sandbox.py | 530 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/unicode_utils.py | 42 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 213 + .../setuptools/windows_support.py | 29 + .../werkzeug-3.0.1.dist-info/INSTALLER | 1 + .../werkzeug-3.0.1.dist-info/LICENSE.rst | 28 + .../werkzeug-3.0.1.dist-info/METADATA | 118 + .../werkzeug-3.0.1.dist-info/RECORD | 125 + .../werkzeug-3.0.1.dist-info/WHEEL | 4 + .../site-packages/werkzeug/__init__.py | 25 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 932 bytes .../__pycache__/_internal.cpython-310.pyc | Bin 0 -> 7054 bytes .../__pycache__/_reloader.cpython-310.pyc | Bin 0 -> 12624 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 27324 bytes .../__pycache__/formparser.cpython-310.pyc | Bin 0 -> 12646 bytes .../werkzeug/__pycache__/http.cpython-310.pyc | Bin 0 -> 38889 bytes .../__pycache__/local.cpython-310.pyc | Bin 0 -> 20920 bytes .../__pycache__/security.cpython-310.pyc | Bin 0 -> 5351 bytes .../__pycache__/serving.cpython-310.pyc | Bin 0 -> 30447 bytes .../werkzeug/__pycache__/test.cpython-310.pyc | Bin 0 -> 42889 bytes .../__pycache__/testapp.cpython-310.pyc | Bin 0 -> 6393 bytes .../werkzeug/__pycache__/urls.cpython-310.pyc | Bin 0 -> 6445 bytes .../__pycache__/user_agent.cpython-310.pyc | Bin 0 -> 1860 bytes .../__pycache__/utils.cpython-310.pyc | Bin 0 -> 22278 bytes .../werkzeug/__pycache__/wsgi.cpython-310.pyc | Bin 0 -> 19952 bytes .../site-packages/werkzeug/_internal.py | 214 + .../site-packages/werkzeug/_reloader.py | 458 + .../werkzeug/datastructures/__init__.py | 34 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 1554 bytes .../__pycache__/accept.cpython-310.pyc | Bin 0 -> 10646 bytes .../__pycache__/auth.cpython-310.pyc | Bin 0 -> 10469 bytes .../__pycache__/cache_control.cpython-310.pyc | Bin 0 -> 6613 bytes .../__pycache__/csp.cpython-310.pyc | Bin 0 -> 4149 bytes .../__pycache__/etag.cpython-310.pyc | Bin 0 -> 3913 bytes .../__pycache__/file_storage.cpython-310.pyc | Bin 0 -> 6062 bytes .../__pycache__/headers.cpython-310.pyc | Bin 0 -> 17754 bytes .../__pycache__/mixins.cpython-310.pyc | Bin 0 -> 9049 bytes .../__pycache__/range.cpython-310.pyc | Bin 0 -> 6016 bytes .../__pycache__/structures.cpython-310.pyc | Bin 0 -> 35933 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 -> 14364 bytes .../debug/__pycache__/console.cpython-310.pyc | Bin 0 -> 8318 bytes .../debug/__pycache__/repr.cpython-310.pyc | Bin 0 -> 9069 bytes .../debug/__pycache__/tbtools.cpython-310.pyc | Bin 0 -> 11800 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../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 + .../site-packages/werkzeug/exceptions.py | 879 ++ .../site-packages/werkzeug/formparser.py | 421 + .../python3.10/site-packages/werkzeug/http.py | 1372 +++ .../site-packages/werkzeug/local.py | 643 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 185 bytes .../__pycache__/dispatcher.cpython-310.pyc | Bin 0 -> 2834 bytes .../__pycache__/http_proxy.cpython-310.pyc | Bin 0 -> 6927 bytes .../__pycache__/lint.cpython-310.pyc | Bin 0 -> 12988 bytes .../__pycache__/profiler.cpython-310.pyc | Bin 0 -> 5626 bytes .../__pycache__/proxy_fix.cpython-310.pyc | Bin 0 -> 6027 bytes .../__pycache__/shared_data.cpython-310.pyc | Bin 0 -> 9279 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 + .../site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 133 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 4623 bytes .../__pycache__/converters.cpython-310.pyc | Bin 0 -> 9150 bytes .../__pycache__/exceptions.cpython-310.pyc | Bin 0 -> 5635 bytes .../routing/__pycache__/map.cpython-310.pyc | Bin 0 -> 30925 bytes .../__pycache__/matcher.cpython-310.pyc | Bin 0 -> 5128 bytes .../routing/__pycache__/rules.cpython-310.pyc | Bin 0 -> 27658 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 148 + .../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 -> 181 bytes .../sansio/__pycache__/http.cpython-310.pyc | Bin 0 -> 4131 bytes .../__pycache__/multipart.cpython-310.pyc | Bin 0 -> 7491 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 17296 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 24515 bytes .../sansio/__pycache__/utils.cpython-310.pyc | Bin 0 -> 4620 bytes .../site-packages/werkzeug/sansio/http.py | 171 + .../werkzeug/sansio/multipart.py | 321 + .../site-packages/werkzeug/sansio/request.py | 536 ++ .../site-packages/werkzeug/sansio/response.py | 751 ++ .../site-packages/werkzeug/sansio/utils.py | 159 + .../site-packages/werkzeug/security.py | 157 + .../site-packages/werkzeug/serving.py | 1109 +++ .../python3.10/site-packages/werkzeug/test.py | 1462 +++ .../site-packages/werkzeug/testapp.py | 181 + .../python3.10/site-packages/werkzeug/urls.py | 216 + .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/utils.py | 690 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 300 bytes .../__pycache__/request.cpython-310.pyc | Bin 0 -> 21648 bytes .../__pycache__/response.cpython-310.pyc | Bin 0 -> 28418 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 835 ++ .../python3.10/site-packages/werkzeug/wsgi.py | 595 ++ website/.venv/lib64 | 1 + website/.venv/pyvenv.cfg | 3 + website/__pycache__/app.cpython-310.pyc | Bin 0 -> 335 bytes website/app.py | 7 + 1677 files changed, 306027 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 website/.venv/bin/Activate.ps1 create mode 100644 website/.venv/bin/activate create mode 100644 website/.venv/bin/activate.csh create mode 100644 website/.venv/bin/activate.fish create mode 100755 website/.venv/bin/flask create mode 100755 website/.venv/bin/pip create mode 100755 website/.venv/bin/pip3 create mode 100755 website/.venv/bin/pip3.10 create mode 120000 website/.venv/bin/python create mode 120000 website/.venv/bin/python3 create mode 120000 website/.venv/bin/python3.10 create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/entry_points.txt create mode 100644 website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/top_level.txt create mode 100644 website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt create mode 100644 website/.venv/lib/python3.10/site-packages/_distutils_hack/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/_distutils_hack/override.py create mode 100644 website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/__pycache__/_saferef.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/_saferef.py create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/_utilities.py create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/blinker/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 website/.venv/lib/python3.10/site-packages/click/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/_compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/click/_compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/_termui_impl.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/_textwrap.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/_winconsole.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/core.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/decorators.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/formatting.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/globals.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/parser.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/click/shell_completion.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/termui.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/testing.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/types.py create mode 100644 website/.venv/lib/python3.10/site-packages/click/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/distutils-precedence.pth create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/REQUESTED create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/entry_points.txt create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__main__.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/__main__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/cli.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/ctx.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/debughelpers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/globals.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/logging.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/typing.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/app.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/blueprints.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/cli.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/config.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/ctx.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/debughelpers.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/globals.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/helpers.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/json/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/provider.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/tag.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/json/provider.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/json/tag.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/logging.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/README.md create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/app.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/blueprints.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sansio/scaffold.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/sessions.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/signals.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/templating.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/testing.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/typing.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/views.py create mode 100644 website/.venv/lib/python3.10/site-packages/flask/wrappers.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/_json.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/encoding.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/serializer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/signer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/_json.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/encoding.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/exc.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/serializer.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/signer.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/timed.py create mode 100644 website/.venv/lib/python3.10/site-packages/itsdangerous/url_safe.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/_identifier.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/async_utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/constants.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/debug.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/environment.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/ext.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/filters.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/meta.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/nodes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/optimizer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/parser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/sandbox.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/tests.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/_identifier.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/async_utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/bccache.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/compiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/constants.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/debug.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/defaults.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/environment.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/ext.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/filters.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/idtracking.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/lexer.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/loaders.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/meta.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/nativetypes.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/nodes.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/optimizer.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/parser.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/runtime.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/sandbox.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/tests.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/jinja2/visitor.py create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/__pycache__/_native.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/_native.py create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/_speedups.c create mode 100755 website/.venv/lib/python3.10/site-packages/markupsafe/_speedups.cpython-310-x86_64-linux-gnu.so create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/_speedups.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/markupsafe/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/LICENSE.txt create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/REQUESTED create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/entry_points.txt create mode 100644 website/.venv/lib/python3.10/site-packages/pip-22.0.2.dist-info/top_level.txt create mode 100644 website/.venv/lib/python3.10/site-packages/pip/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/__main__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/__pycache__/__main__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/build_env.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/configuration.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/main.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/pyproject.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/build_env.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/parser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/base_command.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/command_context.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/main.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/main_parser.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/parser.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/req_command.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/spinners.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/cli/status_codes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/check.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/completion.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/debug.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/download.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/hash.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/help.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/index.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/install.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/list.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/search.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/show.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/check.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/completion.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/configuration.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/debug.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/download.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/freeze.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/hash.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/help.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/index.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/install.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/list.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/search.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/show.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/uninstall.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/commands/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/configuration.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/installed.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/sdist.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/distributions/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/__pycache__/collector.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/__pycache__/sources.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/collector.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/package_finder.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/index/sources.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/_distutils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/locations/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/main.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/metadata/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/metadata/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/candidate.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/format_control.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/index.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/link.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/scheme.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/target_python.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/candidate.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/direct_url.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/format_control.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/index.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/link.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/scheme.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/search_scope.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/target_python.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/models/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/auth.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/download.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/session.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/auth.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/download.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/session.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/check.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/check.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/freeze.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/operations/prepare.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/pyproject.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/constructors.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_file.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_install.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_set.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/constructors.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/req_file.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/req_install.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/req_set.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/req_tracker.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/self_outdated_check.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/_log.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/logging.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/misc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/models.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/urls.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/_log.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/appdirs.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/datetime.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/deprecation.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/egg_link.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/encoding.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/filesystem.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/filetypes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/glibc.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/hashes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/logging.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/misc.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/models.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/packaging.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/subprocess.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/unpacking.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/urls.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/utils/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/git.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/git.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/subversion.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_internal/wheel_builder.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/__pycache__/distro.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/__pycache__/six.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/certifi/core.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/enums.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/chardet/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/win32.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/database.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/index.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/locators.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/markers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/resources.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/util.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/distro.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/core.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/codec.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/core.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/intranges.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/package_data.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/markers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/tags.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/packaging/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/build.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/check.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/dirtools.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/meta.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/colors.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/bar.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/colors.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/counter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/progress/spinner.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/console.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/filter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/style.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/token.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pygments/util.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/api.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/help.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/models.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/__version__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/adapters.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/api.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/auth.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/certs.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/cookies.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/help.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/hooks.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/models.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/packages.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/sessions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/structures.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/requests/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__main__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_lru_cache.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/align.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/box.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/color.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/console.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/control.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/json.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/live.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/region.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/status.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/style.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/table.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/tabulate.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/text.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_extension.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_loop.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_lru_cache.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_pick.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_stack.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_timer.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_windows.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/abc.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/align.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/ansi.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/bar.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/box.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/cells.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/color.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/columns.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/console.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/constrain.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/containers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/control.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/emoji.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/errors.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/filesize.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/json.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/layout.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/live.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/live_render.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/logging.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/markup.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/measure.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/padding.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/pager.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/palette.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/panel.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/pretty.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/progress.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/prompt.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/protocol.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/region.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/repr.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/rule.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/scope.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/screen.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/segment.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/spinner.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/status.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/style.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/styled.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/syntax.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/table.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/tabulate.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/text.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/theme.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/themes.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/traceback.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/rich/tree.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/six.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/after.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/before.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/tomli/_re.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/typing_extensions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/request.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/response.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/vendor.txt create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 website/.venv/lib/python3.10/site-packages/pip/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_manylinux.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_musllinux.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/extern/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/LICENSE create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/REQUESTED create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/entry_points.txt create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools-59.6.0.dist-info/top_level.txt create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/_imp.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/archive_util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/build_meta.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/config.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/dep_util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/depends.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/dist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/errors.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/extension.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/glob.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/installer.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/launch.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/monkey.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/msvc.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/namespaces.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/package_index.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/py34compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/sandbox.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/unicode_utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/wheel.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/__pycache__/windows_support.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_deprecation_warning.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/config.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/core.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/debug.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/dist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/errors.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/extension.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/log.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/py35compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/util.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/archive_util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/cmd.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_msi.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/bdist_wininst.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/build.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/check.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/clean.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/config.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/install.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/register.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/command/upload.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/config.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/core.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/debug.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/dep_util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/dir_util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/dist.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/errors.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/extension.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/file_util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/filelist.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/log.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/py35compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/py38compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/spawn.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/text_file.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_imp.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/more.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/more_itertools/recipes.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/_manylinux.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/_musllinux.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/archive_util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/build_meta.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/cli-32.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/cli-64.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/cli-arm64.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/cli.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/alias.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/build_clib.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/build_ext.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/build_py.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/develop.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/dist_info.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/easy_install.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/egg_info.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/install.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/install_lib.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/install_scripts.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/py36compat.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/register.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/rotate.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/saveopts.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/sdist.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/setopt.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/test.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/upload.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/__pycache__/upload_docs.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/alias.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/bdist_egg.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/bdist_rpm.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/build_clib.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/build_ext.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/build_py.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/develop.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/dist_info.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/easy_install.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/egg_info.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/install.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/install_egg_info.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/install_lib.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/install_scripts.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/launcher manifest.xml create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/py36compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/register.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/rotate.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/saveopts.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/sdist.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/setopt.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/test.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/upload.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/command/upload_docs.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/config.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/dep_util.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/depends.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/dist.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/errors.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/extension.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/extern/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/extern/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/glob.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/gui-32.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/gui-64.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/gui-arm64.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/gui.exe create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/installer.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/launch.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/monkey.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/msvc.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/namespaces.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/package_index.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/py34compat.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/sandbox.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/script (dev).tmpl create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/script.tmpl create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/unicode_utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/version.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/wheel.py create mode 100644 website/.venv/lib/python3.10/site-packages/setuptools/windows_support.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/INSTALLER create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/LICENSE.rst create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/METADATA create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/RECORD create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug-3.0.1.dist-info/WHEEL create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/_internal.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/_reloader.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/formparser.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/http.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/local.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/security.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/serving.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/test.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/testapp.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/urls.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/user_agent.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/__pycache__/wsgi.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/_internal.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/_reloader.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/range.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/accept.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/accept.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/auth.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/cache_control.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/csp.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/csp.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/etag.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/etag.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/file_storage.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/headers.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/headers.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/mixins.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/mixins.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/range.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/range.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/structures.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/datastructures/structures.pyi create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/__pycache__/console.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/__pycache__/repr.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/console.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/repr.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/shared/console.png create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/shared/less.png create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/shared/more.png create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/shared/style.css create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/debug/tbtools.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/formparser.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/http.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/local.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/lint.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/lint.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/profiler.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/middleware/shared_data.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/py.typed create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__pycache__/converters.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__pycache__/map.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__pycache__/matcher.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/__pycache__/rules.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/converters.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/exceptions.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/map.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/matcher.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/routing/rules.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/http.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/request.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/response.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/__pycache__/utils.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/http.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/multipart.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/request.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/response.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/sansio/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/security.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/serving.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/test.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/testapp.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/urls.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/user_agent.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/utils.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wrappers/__init__.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/request.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wrappers/__pycache__/response.cpython-310.pyc create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wrappers/request.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wrappers/response.py create mode 100644 website/.venv/lib/python3.10/site-packages/werkzeug/wsgi.py create mode 120000 website/.venv/lib64 create mode 100644 website/.venv/pyvenv.cfg create mode 100644 website/__pycache__/app.cpython-310.pyc create mode 100644 website/app.py diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6b76b4f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Python Debugger: Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + } + ] +} \ No newline at end of file diff --git a/website/.venv/bin/Activate.ps1 b/website/.venv/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/website/.venv/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/website/.venv/bin/activate b/website/.venv/bin/activate new file mode 100644 index 0000000..066b0dd --- /dev/null +++ b/website/.venv/bin/activate @@ -0,0 +1,69 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/home/sascha/cs50/website/.venv" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(.venv) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(.venv) " + export VIRTUAL_ENV_PROMPT +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/website/.venv/bin/activate.csh b/website/.venv/bin/activate.csh new file mode 100644 index 0000000..59e9e5b --- /dev/null +++ b/website/.venv/bin/activate.csh @@ -0,0 +1,26 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/sascha/cs50/website/.venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(.venv) $prompt" + setenv VIRTUAL_ENV_PROMPT "(.venv) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/website/.venv/bin/activate.fish b/website/.venv/bin/activate.fish new file mode 100644 index 0000000..b3b7984 --- /dev/null +++ b/website/.venv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/sascha/cs50/website/.venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(.venv) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "(.venv) " +end diff --git a/website/.venv/bin/flask b/website/.venv/bin/flask new file mode 100755 index 0000000..e12b7a4 --- /dev/null +++ b/website/.venv/bin/flask @@ -0,0 +1,8 @@ +#!/home/sascha/cs50/website/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from flask.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/website/.venv/bin/pip b/website/.venv/bin/pip new file mode 100755 index 0000000..5afef26 --- /dev/null +++ b/website/.venv/bin/pip @@ -0,0 +1,8 @@ +#!/home/sascha/cs50/website/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/website/.venv/bin/pip3 b/website/.venv/bin/pip3 new file mode 100755 index 0000000..5afef26 --- /dev/null +++ b/website/.venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/sascha/cs50/website/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/website/.venv/bin/pip3.10 b/website/.venv/bin/pip3.10 new file mode 100755 index 0000000..5afef26 --- /dev/null +++ b/website/.venv/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/home/sascha/cs50/website/.venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/website/.venv/bin/python b/website/.venv/bin/python new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/website/.venv/bin/python @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/website/.venv/bin/python3 b/website/.venv/bin/python3 new file mode 120000 index 0000000..ae65fda --- /dev/null +++ b/website/.venv/bin/python3 @@ -0,0 +1 @@ +/usr/bin/python3 \ No newline at end of file diff --git a/website/.venv/bin/python3.10 b/website/.venv/bin/python3.10 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/website/.venv/bin/python3.10 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/INSTALLER b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/LICENSE.rst b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.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/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/METADATA b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/METADATA new file mode 100644 index 0000000..56e9429 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/METADATA @@ -0,0 +1,105 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.3 +Summary: A very fast and expressive template engine. +Home-page: https://palletsprojects.com/p/jinja/ +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: 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 +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/ +- Chat: https://discord.gg/pallets diff --git a/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/RECORD b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/RECORD new file mode 100644 index 0000000..8a511ac --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/RECORD @@ -0,0 +1,58 @@ +Jinja2-3.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-3.1.3.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Jinja2-3.1.3.dist-info/METADATA,sha256=0cLNbRCI91jytc7Bzv3XAQfZzFDF2gxkJuH46eF5vew,3301 +Jinja2-3.1.3.dist-info/RECORD,, +Jinja2-3.1.3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92 +Jinja2-3.1.3.dist-info/entry_points.txt,sha256=zRd62fbqIyfUpsRtU7EVIFyiu1tPwfgO7EvPErnxgTE,59 +Jinja2-3.1.3.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=NTBwMwsECrdHmxeXF7seusHLzrh6Ldn1A9qhS5cDuf0,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=dFcmh6lMNfbh7eLKrBio8JqAKLHdZbpCuurFN4OERtY,2447 +jinja2/bccache.py,sha256=mhz5xtLxCcHRAa56azOhphIAe19u1we0ojifNMClDio,14061 +jinja2/compiler.py,sha256=PJzYdRLStlEOqmnQs1YxlizPrJoj3jTZuUleREn6AIQ,72199 +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=0qldX3VQKZcm6lgn7zHz94oRFow7YPYERiqkquomNjU,61253 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=5fnMpllaXkfm2P_93RIvi-OnK7Tk8mCW8Du-GcD12Hc,31844 +jinja2/filters.py,sha256=vYjKb2zaPShvYtn_LpSmqfS8SScbrA_KOanNibsMDIE,53862 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=DW2nX9zk-6MWp65YR2bqqj0xqCvLtD-u9NWT8AnFRxQ,29726 +jinja2/loaders.py,sha256=ayAwxfrA1SAffQta0nwSDm3TDT4KYiIGN_D9Z45B310,23085 +jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550 +jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 +jinja2/parser.py,sha256=Y199wPL-G67gJoi5G_5sHuu9uEP1PJkjjLEW_xTH8-k,39736 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=_6LkKIWFJjQdqlrgA3K39zBFQ-7Orm3wGDm96RwxQoE,33406 +jinja2/sandbox.py,sha256=Y0xZeXQnH6EX5VjaV2YixESxoepnRbW_3UeQosaBU3M,14584 +jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 +jinja2/utils.py,sha256=IMwRIcN1SsTw2-jdQtlH2KzNABsXZBW_-tnFXafQBvY,23933 +jinja2/visitor.py,sha256=MH14C6yq24G_KVtWzjwaI7Wg14PCJIYlWW1kpkxYak0,3568 diff --git a/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/WHEEL b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/WHEEL new file mode 100644 index 0000000..98c0d20 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/entry_points.txt b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/entry_points.txt new file mode 100644 index 0000000..7b9666c --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[babel.extractors] +jinja2 = jinja2.ext:babel_extract[i18n] diff --git a/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/top_level.txt b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/Jinja2-3.1.3.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.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/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/METADATA b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/METADATA new file mode 100644 index 0000000..dfe37d5 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/METADATA @@ -0,0 +1,93 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.5 +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/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/RECORD b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/RECORD new file mode 100644 index 0000000..1a961ed --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.1.5.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.5.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.1.5.dist-info/METADATA,sha256=2dRDPam6OZLfpX0wg1JN5P3u9arqACxVSfdGmsJU7o8,3003 +MarkupSafe-2.1.5.dist-info/RECORD,, +MarkupSafe-2.1.5.dist-info/WHEEL,sha256=1FEjxEYgybphwh9S0FO9IcZ0B-NIeM2ko8OzhFZeOeQ,152 +MarkupSafe-2.1.5.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=r7VOTjUq7EMQ4v3p4R1LoVOGJg6ysfYRncLr34laRBs,10958 +markupsafe/__pycache__/__init__.cpython-310.pyc,, +markupsafe/__pycache__/_native.cpython-310.pyc,, +markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713 +markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083 +markupsafe/_speedups.cpython-310-x86_64-linux-gnu.so,sha256=kPt-fhZ_RG7PUbDvwmyC26ZvRJ9DvUlF3hszBIB6_xs,44240 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL new file mode 100644 index 0000000..1d81251 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.42.0) +Root-Is-Purelib: false +Tag: cp310-cp310-manylinux_2_17_x86_64 +Tag: cp310-cp310-manylinux2014_x86_64 + diff --git a/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/MarkupSafe-2.1.5.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/website/.venv/lib/python3.10/site-packages/_distutils_hack/__init__.py b/website/.venv/lib/python3.10/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..f707416 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/_distutils_hack/__init__.py @@ -0,0 +1,132 @@ +import sys +import os +import re +import importlib +import warnings + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +warnings.filterwarnings('ignore', + r'.+ distutils\b.+ deprecated', + DeprecationWarning) + + +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 + 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 + warnings.warn("Setuptools is replacing distutils.") + mods = [name for name in sys.modules if re.match(r'distutils\b', name)] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib') + return which == 'local' + + +def ensure_local_distutils(): + clear_distutils() + + # With the DistutilsMetaFinder in place, + # perform an import to cause distutils to be + # loaded from setuptools._distutils. Ref #2906. + add_shim() + importlib.import_module('distutils') + remove_shim() + + # check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + + +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 DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + if path is not None: + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + import importlib.abc + import importlib.util + + class DistutilsLoader(importlib.abc.Loader): + + def create_module(self, spec): + return importlib.import_module('setuptools._distutils') + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader('distutils', DistutilsLoader()) + + 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 + + @staticmethod + def pip_imported_during_build(): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + return any( + frame.f_globals['__file__'].endswith('setup.py') + for frame, line in traceback.walk_stack(None) + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass diff --git a/website/.venv/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/_distutils_hack/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2d3c473923285aecf994639412f8237348737dd9 GIT binary patch literal 5107 zcmbtYO>^7E8Qujz2&5!hkrPkSCLJ`+xM5?H{>W#mDDGIc>(*g9mYg)IQyAnfMMxk) zFF+|`shPCWOp{Be{Rh@eFFtjqKL^*IeCi>$9_&8vf&?kaPA5~$V1We|yU+W+&-<~6 z=I2Wc$GhMDTmGZW*uSVVeH75SiZlKz8o>k)*?M;6>sbPi3g##uQ_Ko$j zEbp`RQ{n}&h<6L(w0IHM7X)8rm6sj^6|1L?=k<1byPlWY!A3Vya`40ITdoM=q@M&~ ze6K-0*;BIVCsH)&qv^v$=Nitqibn8+ZSrldW&~ShiJ=zIH-)jq)PjCuJuC?GkV722 zuUPf8m@iZ@9@AWpXVCcjoUxTL1b4@e-JsKp6acsl*#by+RVMvj5=CKr-fi@g(fgpg zG4;mv!#Hx4?1g?)#%|J5M#_~+;SOI!uD=}x7~GaIri|mh1hDK`KPFiD!nlJnlW_OE zE4y(YvLtOkapPPdd=5}?;)fyR1v~;}@46DNG`P`c z6)fEqH301RThe{rB7TUOPO3IXTCLcr3Du-CBi*DkL9E%5&TUH-1C1ASTT$xl_^Jyb zocJjm(0jLvcTJ_L0&S>c5TjHtcB_W2$gvK97)y{E}OP=sXBw_M{GiR zAthd;59lpv{h=W^EMbu5g}Fsqum&HMTpYg$!)OP-6T+iFM>lFsIa*^E9=08*sM`TA z+-+Y4Yef}p9L`Tw$dgYuN)h423TAEn4Vry-ujxU54w}Vbv%wj4@I-lKo znV+Y#N_L`cnGHjNXa%A4JP2*ktjA?OlZ7!)YiqLLB~k$~#pZUQ#BE+OU*_uEaaEuX z$wwCd0d7bYYIdv&QUK*EowJO=Keg?yPsL3Nj(TOc8TEFL5&+(ZpwL2;Mj(Yi%FQfW zE$L}irF7d#(u;pqt8D~HyWfD;ItWHRzcvZSwJe&~-oEtSS$&H!#HR~aKDd1OgZJOQ zcu7x&tb~k$Xx@pEVB04)W<;x3OichCfVBKm3e;98Kja76I{A#8m{t8+Fz zy)sU+AIrqQ5g^a0dXsoNJ}59zA)_7gZQKk|vh=yKiFbl;GGPUpw}0n<;d@qM4A~Gx z3=pt=bFVNg>=Qo=^}*@5Cz~F$Q#C++q&kW1x(wZgh~H7L5h?#o)E?gnS}bkZve= z#P6d)WMm=xCcE-)*iH6l)JE`ZX4+!(m$G{cQZc4GIazvRyKPR*lHXJr*%$e#V8cv*r zCynw9Qcl%xG}CgPfvU9GNKJZZXVavXezcGoLPZ_q7vjrEZ`rgu7HB-$#)~Jdc9+ml zD0NVCylgBugL66F?=<%jw<8-8TdvV;E}9{DdB_k2!OSdGWifBaJQOQnt2NlvX@QEA zQM$@<&s2S~)0SOV^}AF$>pg~YdqFSD8uT6IC!LJ&^z8fZy?e=}B%^e0@yB%x4XmH= z;^&ZVie-5iRc}F_Eu88+n!)AoR1e{sDiN~~is<k7_vPWDT`Y$oIzDRRr32} zsKVfr+)yhrK^^G^EwTgE?hQ$%8Oud`F(124Nae;&74(v-dq=k1vzM>D^UlO~sBOCrd|_LbkuV zgAY?XEB)0PbxNQ5VP9USpB&Ewb{2!a!l_fW!58@)eAalX=y_!^o0Up>MSJorA=Cab zeUW@93A*EiLm4PmMS4}nUL%nz|DmwBGWz#~dit~MFGE&H)8;U%tIyFL70B938o5@H whVd-isk4+N)@2G8F@5jo{6IOPWZI^IKL*wlr{F9&MNr^WdCtDzm~+;D0io3gjsO4v literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/_distutils_hack/__pycache__/override.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b762ede132d543895b00342e5a9813ae40fb8eea GIT binary patch literal 232 zcmd1j<>g`k0<+KWQ+0s!V-N=!FabFZKwK;UBvKht7@8RuFfL?ZWJqBQX3%81#UG!N zSzJJT50cR>0NRk4 io?5JrW~)BT3cZ5LTO2mI`6;D2sdkJYcY{12zyJWBNJ1|F literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/_distutils_hack/override.py b/website/.venv/lib/python3.10/site-packages/_distutils_hack/override.py new file mode 100644 index 0000000..2cc433a --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/_distutils_hack/override.py @@ -0,0 +1 @@ +__import__('_distutils_hack').do_override() diff --git a/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/LICENSE.rst new file mode 100644 index 0000000..79c9825 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.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/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA new file mode 100644 index 0000000..f96613c --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/METADATA @@ -0,0 +1,62 @@ +Metadata-Version: 2.1 +Name: blinker +Version: 1.7.0 +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.8 +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/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD new file mode 100644 index 0000000..51a7d03 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/RECORD @@ -0,0 +1,14 @@ +blinker-1.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.7.0.dist-info/LICENSE.rst,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.7.0.dist-info/METADATA,sha256=kDgzPgrw4he78pEX88bSAqwYMVWrfUMk8QmNjekjg_U,1918 +blinker-1.7.0.dist-info/RECORD,, +blinker-1.7.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +blinker/__init__.py,sha256=s75XaRDHwSDzZ21BZUOEkQDQIcQEyT8hT7vk3EhYFQU,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=S2njKDmlBpK_yCK4RT8hq98hEj30I0TQCC5mNhtY22I,2856 +blinker/base.py,sha256=FqZmAI5YzuRrvRmye1Jb-utyVOjXtF5vUVP3-1u-HtU,20544 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL b/website/.venv/lib/python3.10/site-packages/blinker-1.7.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker-1.7.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/website/.venv/lib/python3.10/site-packages/blinker/__init__.py b/website/.venv/lib/python3.10/site-packages/blinker/__init__.py new file mode 100644 index 0000000..d014caa --- /dev/null +++ b/website/.venv/lib/python3.10/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.7.0" diff --git a/website/.venv/lib/python3.10/site-packages/blinker/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/blinker/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2d0ed40e163e66ce59d5659ea80c7f55b7442a7 GIT binary patch literal 496 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/blinker/__pycache__/_utilities.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f75bdc459aa2e264c3fda870ef760904cbbc55b3 GIT binary patch literal 3522 zcmaJ@&2!tv702R(U!o*hk`>9VQ>2qtVv~?*Gi|0bsVh~@cpOjU8C$8RY&|H5U0RSq zfLSc0A%{Lm*ZvRoG57v8d+n*G9(wB~{k;WAQC6nF0K5C%+mHA5_dc@K)rN)V=s*7! z`zx09PZ}&gE(Qmd#qxik!!6DdYsh+xQQuDNo`cp&+@aU=49!g{!)mX}Ea9Bh@YO{_ zGzRvrC05WnyH>CH(BdAiTv@zwY4=unRjdYUpw)O4v?^%p{5`(P*RI@NOL(F>uzPpF zU*|3GLAi8#8+DuS@Lhg~Z(Mo3P4qYU))nh*LGCW!hTJyRxy$WmR{P$+NS`*-D`A>u zDpYZn=EoR2QVh^+{2?n+{oy&j9WdMGj3m5uzTGQ1a9}oLk64B)OLwyI|5iQn2XUbe_Y6bK$&M?uQ+&{trl`JCVhkhz9 z{4^X2?w6}|j@!1b1p(25K)cj};^rb5$SM~6&XRRB|9#p$&4!|zhk0}wcBA~)pLQ=q zKaZ8@cFsk5-c90ucQl69>1Ul^e%d9@C!;WW6}}XCx1Yr6Di!Zb}m)iX9=1KiDbjI^ngnw6(#vIZfeLirP8Sq!HWnglhMr9O*YxM-g?fywK*NYY+gYJTU*a8N#|%Yv!Pr=|K07NrxYU@1e;)* z%_?kJ&ysoEu1H#xPB+YWkw#@F+{J(~pk5v<+R6B-NycABp9pcg?D? zn%i^?Rjz^(;k)sWF%JkmKSt*oiajSL2-@5M6g}<&NuF6C{5>pi=tqR9FjaFHH5xvi z2M-?12>W}3EZb}Qaek9v#7<-(epud6F|%Cm(9e_j<*D-FLvbpG0{dkHU!4m7>%)hS zj*gx@dHm?h-(~$X5vl#QKMIu+GVS>O2}DLR9)@ykmJInh4htyK{1P9K$Khg?WA%~T zZCVA%Par!b53W|2h<2)535h}P&6edZ&w9+1350t%#lLT`Utf&f^nuF$G z`LQupBxVcUa$&kF1FB!4GpP`)rfk=G4sf}aV&ffV(M$9<_LM1S$}ZVkyJGzr5*IT7 zy1H6wmh0MMG5%7@OzK816c>ZANR$Bq{KJWoyu_+O%>p`zFag3t5PXC~n}Dj7`g}M44*D@*P1vJ?oe0Ci`13U ze7gCFvAmnr^$UtEXWOtVwOhT;9k2Bt{_<>c3AzlBKb3 z#DEcbN+h%sr%F2r#fTNVkXo{jiAr~{>S@@A-^Vk>2@W|$lm^>k^sOp{7S-kfDHv*$&bt0tcx`m=5aZU+p9aPnd_ z$|PJRDsq(#7kKu`2ywqqi06|X)p;_aY#1hgS-!a!dPRyz#OFdnF)EnMK>r+U4Ooll?hp=$TWP|P)USz*^ zQcv0Q{?vZsytV#ly=eT^e(k>Ylsk2%?i4iwv%cM&IxriX+<#iScbNLKb0Q{?%_vTF z+McdafFPsljd>3VU?8Lb49pp|hx9ni;jsc01Q1b?-{8BY?I=M^4*s8IKAyt}anc> z&fJemFEZH>9>hJ96)RA>s#lY6G7d&E8wsh#ll?>gU_L0l2Wcitld&)83QYpZfP>Dh zd!da@M5A~*1wK*6u`_B>AI{4RTi0O_UmSfkN-#1n_>i+|v CR1>fO literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/blinker/__pycache__/base.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/blinker/__pycache__/base.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4286b113fdde83dfd881327ae605d0b37d0aba9 GIT binary patch literal 17496 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 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/website/.venv/lib/python3.10/site-packages/blinker/_utilities.py b/website/.venv/lib/python3.10/site-packages/blinker/_utilities.py new file mode 100644 index 0000000..4b711c6 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker/_utilities.py @@ -0,0 +1,105 @@ +from __future__ import annotations + +import typing as t +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 diff --git a/website/.venv/lib/python3.10/site-packages/blinker/base.py b/website/.venv/lib/python3.10/site-packages/blinker/base.py new file mode 100644 index 0000000..b9d7035 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/blinker/base.py @@ -0,0 +1,558 @@ +"""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 inspect import iscoroutinefunction +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 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 + +# NOTE: We need a reference to cast for use in weakref callbacks otherwise +# t.cast may have already been set to None during finalization. +cast = t.cast + + +class Signal: + """A notification emitter.""" + + #: An :obj:`ANY` convenience synonym, allows ``Signal.ANY`` + #: without an additional import. + ANY = ANY + + set_class: type[set] = set + + @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( + self.set_class + ) + self._by_sender: dict[IdentityType, set[IdentityType]] = defaultdict( + self.set_class + ) + 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 iscoroutinefunction(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 iscoroutinefunction(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(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 = 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}>" # noqa: E702 + + +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/website/.venv/lib/python3.10/site-packages/blinker/py.typed b/website/.venv/lib/python3.10/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..3ff0797 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/website/.venv/lib/python3.10/site-packages/click/__init__.py b/website/.venv/lib/python3.10/site-packages/click/__init__.py new file mode 100644 index 0000000..9a1dab0 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..841968bdae45eea841906eb5a8fc56bc0a813be0 GIT binary patch literal 2615 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46bf087a0b5e508e68f886fd8ad66f9e7ad1879b GIT binary patch literal 16313 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ee9aa29344f57de0ab9693bb435f5cfecd34e95 GIT binary patch literal 7665 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 LEm@LU_J95t<=^$1 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5bc7a432c3704190da8171650e4de4c9f8f71e99 GIT binary patch literal 91143 zcmdSC37i~PS|^wh8JU%tm369gT9(tYTdK09l#lkMcH5TAl3U$Y*;uj-YX+X12a2A)2zhpIe=jq1{fI5-5q*&hihQifPtAGvox^maG0jS zm*)Tf-g|LmWl3t9{jpP0M!t-A@s96(?|a|%zSkZZDP{0C`{ti`-}_Tm=J)s``8SLo zkKhxy*-XaGxK=YWufDB$OMct)wtQ#jv-0iCJMx{I&*R%}4y_dC3l`tWHj68z`I4j^ zq=)B+C7o-QS4QSXB%N=Lu8hu)NqPwB@%eE{7n&0*lk=03E;cuD}|YCB3D2%gU|uw@P{|((jvppQN`Ty=Q)pq_;Qs zu1wEQOL_;=GxIZ&z5(gm=5Leq&gSha`{wsa`bMPp&+nJ?E~KmTRY~83^nv*UlCB_q z$NU|Vz8UE|=kK&KUViy5|952s?w)@?Ahf%A&&s{?_sWy|+*|Pce)m>fA6T-tXWaL_ zZqFa|@|W&&_guE-Kj7|lr`;LvLH9P~_#i$HA$>b@ZqF>`-F@!<*PQu>i&gg-_keqc zdncaW<=*bz?LFe&=2}Z7_x=byl@!|oCMI)Y!v@au8+cKo{CJBGY-`28XG z4*b5uo5SxX@%yOzVf_BE_auHlh2I}>pTO@Y zegJttfSQiu*H^huaF@I&&QqO;g=hoef46?W|v4U6sc}r@Rhdz{5f-PUn4Z)vNRF z$O*r`=$*v-C(f;Ue`ujT+|70HBX|ReLnqrl^OYa1yHC~q`ij?)f=6eYjl~xazr5(J zb{g##vN~)Da*iKs1VN*9D$0##rDp=P_ptA`+2)ZCdCk=$ZGWYXw(&-Jx!q{h+EP-0 z-@~iz)tc@qAFr+jr_Jv-tZ<^X)U2PXwLH%aYG>-rHIJE|l-E&fpa2uBHX9uliible zY^mX|AemqF+beQ27j(`w`RY{7MXwe+H9R_nF4kJ;CX1|jFR#{HZmsU0VzV4?@pK#C zTUY8YdU$84zSiv2g42Ld?KHZCM+JElbl9uOr|OH1rE^D`X#I0)MBcy{&7%6IN1z?; zcq^fGq>8+`lkK&Z8(PnX*~QMw;n1ua=djdhEvo!ph(YVD`7J(N0Rp&-HnBthxO^hh$y~BJb}zG>y=1BJ)lKpJP%Dglp=xBF;?TJRvsnnazO6Rm!3D!=cacoLZX)jgkl~aCu zZ55B|ol4ND`<=?!M&~rMmMZv*yHb%stKh{--S=91JC)N7*Y#S}l4Lx%N<^yw5Ci?Iqz6pIn*wsrtyYfJ&*5gp0}7l|@6OE> zLaP%xi}j!rmXBdb8ydhw8|hv+(nP<3fvU4%NqQHsci}K*m3b28RX=8O{_Pk7e?Kl^ zZiPjL4w1^g8+YEw_y_Uz)`t(AZm)O;f_kucx_)3WxaW=oXT6g_qvIW@p7B~|4m2Al z53HW+oNl-7uHJda0Y2HkikXV36dYLO{5!DN_Py%rxo`)YK(z8|XBt7{WYaTk3hqE% z!6YvBE2G6xyJVFuUhP+$xBUlk`$$+mSr4N8{$02i78X}rnFhee6*nyS-YG!9^A{aF zHGjmnF??q630z!&YZ<@Lv3hpLzF-F>H**}A<&U}6d8cK&z_1Q*>a$q>k<J=&=>f=a91sjRj^Y|!0Gr(LPL zZbg920as{Q4=RhN8%-BjCOPoRY0ppRQV5Ik8o;sBbzE24u2=24M>r>e)~PZpC^ANT zDYP$x;QzYfDko0!o@#Zlwz>+c0fg+9s+C#Q+Ddmbp9fxtrK*;2igXWE&Z1KE&O>XE zNY;OH4WPjP7OsKUTw)1*Ev{CkyLolLJ1J8Vx$CL|l-M1r5H*poXR0$pVNPlWcY4tYbNrZ97-&ynV%XMlIVy+IHS6@RN1kb)5V=&K3W0 z7FEE!@aw>VuynHCSv*|}8eK0%97!mNtWv=iBs!T6NF$IDNY=A1*x!in5$x3TIMSiHmHXKepN_~9Srg|j!&m7LW2JZ=W8Xp7~~;VaAu6$^{eI+$uw7Foz{ zFX9t)ars21n|Ccz+vmVqAI~^wp^>uj1YF_Q&nB7T(XEdr-e$jNZRby&va0o0+k@59#%$q8SS{C9pi#F-k!N41`|? zj)C%G%_c1df_i4{52^s0KZ-sms`n&QQ@G4z;~Syn^}}tdzIJNGYjtXCWDaT`xr3mF z_ks#8_A7P{l*%eud213M+bX=Gelcag>vNF{#~ac5P;2|H=Z6!nx7ft`!Dgyk>)@Wp zn}mO`4;R;RZ8zJ=EDJ)AAzgAlnOU-2$IZP~K5utGqk5oDuiIeAhPuD>cmuS#QpYrX zY0bmr;L0Z>O~y!Q2$x1_i;#-b?X{-MB?rq_&_D}4SC%ZUV&FFxJzl~yn{_6k{FW~;yWLnl)E(O_g zre`e?Z1!B31@>TaMZmAJEpymlvYx~cjD!k#o{D$QpM>;Xt z3IVyT7rk>IW1Gsj*g%pp{@GW`+3r39uqNXX)Bs|#bQ;9f2b- zJ3pyELirJV0$#ifWogLK)_m4;F6Ay~=JUmjP7Ot=LX;{-sgg@rXT!0G;v8?U`HNot zqZm`O`qW#MgP0#daB$({UTbZodKi}ly#%)026!z@cp_3DFAHNQm=YoR-azqhnp=A& z@G1u(7Mwn~AUsJ`(~>F~qv)lYDh@TZD|o;fq*PrCXG1-nN0pQ3WKq&pRI8OUm|U3A zSeqcmxCakb?yue<1(36pCJg8mS5Mb(lO^>k3k%>n8hTSCuE| zsNf+{&?o!#4fq7xa4BRQt1tpONvaur97}So!@pbb#v^?753(`-Jp;l>44ltFq8)NU z7QKR-eK1pWQvY(PUyi%v=G`H;fOm>6^aO5^DX)Z7NmBXcVWfwnyJda1?D6@q(g(OB za(4tdN2Ao3H|mbduTk8eh*FbLYLle$%VVq$d8YL5aj$gB@=Chw%~Ad>QEIE}EbVr; zx!a+ym~gk^{$$*qCEMNM-T(=HlY7eD>E4Lcl)FopJ>+ecx^9x+NV^qDZ9$5q7TlZN z-FRcGx6M5bUCXGHzMZgvX5fA99?@p(@NO7TEA%g~InZ_N#4`wD?u>gIO1crciTv^| z?g(uyokaxfSMg5F3Uv*bRGvmw?vU{QJde(i8 zEpxwGt{j7c`!(*ojMW`F&rn|;_N3rGZ*sZMAm5DpQH)`_EZk+OD3gpx!F_>m%-`XD zEoN1JPL^167x4T}fnwdeOK>jlo^%&+_injMY%Y3t$=HF8;r{zw2kS)3C-+nTQ>^VL zgl!PTk`fbwRd2CTZ-S-3YT81geR7#Rg|H!~+fB&(kPJE=*pQ}orrzoZ86^!Tkqj37 z#%c%rp|`ju%p%kQ9_Tl?5D4QC)$oqjtX3*VJ6K9uBuV5p>SVci3Yl}S z?z`=?{pu72&Vw>W8nzW#G_^(rY^APQEo)j0gC!iTSFfq`z-*KbL=IFr`BRqgxbT=& z$JjsawZQ3e+{w>MKe&>o|Ii{L)Jhxdt?Mbg0{fjTH$u0zzd<3otElscM$k?hd>&BH zU@GP30MN&B-8{EJDQpMVa`Hn=tH$h;-bILd(rdQQa)27Z>@TaJ6vQ#x4gw8m7yd8IwOhbARMax)f31=@F_JaMlY#}hjervbYC6%DT&pm*jrm6EFsh~o= z{xwQjh143%Xq+`8APds{cTmd)0}G&o8MAbaf{4m(ER?=dhGQgJ6{W8{3w=UxkgF(E z1VVtWQB*V>m{rh*z*dAI0ZHKszEAgCfQ~w^Q4~N6f`K=&x&;KcDJ$K(YXV!NCg6l_ zL7CZ*kq2o~ZBo?;pjH~EPG754)b$2XpI3tVlGizhxxc!~<(JDJ2%pa)QZor_bpyBs zBm%;d5jm(J2>{WWMDpXcg!-_6Rsu%XfDeoF02c_9(8bnUju zK{n$0GD zjv~3V&nl|mVsNfeJs=pBirlCrs7&jD+=u0@-GKPD@7jfUoyBUjND3v=)+Hh>F;=9X z>uF9z!tf^Lp;mx4VKsqZaMC+nKhtRYDbOson{EG~um_OkxDLw_5iOCLngx|ZbH|S& z8*;;*?US?IaDWnnLM})74*<6f7Xa`I8$llha3ZLZg%5zzBHpFwsrygS7L<`ljzLoV z$tti9ca#W-f(Nd&ra_!9GGPH4)0h;r&x#>Hu{Q(SBbbVXY;`TYe8PZm*0?+ztQ^NL zsm4?*t5ixDsv1clszl{M2iQie2>U20=>mjZV!L%g6chMUF{e=x5xrhmm{sCzHQ6wz zWi|gKTq&wD?IQ?KUR00>^h=O}BDyV)25W-vj9xo|CM_)VRf#r2Fa$brQpNmRa-245 zEc&GRW_%N?w{8IBaLZtP2q)ITC!87t z5BN8b!iVJ~wkp%-1bS}%n5Nlo7N4LD6I~CUR5chhakbzXm8sbc7&&X%Q@lEIh5w4b zy_1KnedvPKvOD<;d^QBHsthdm)373E;9Z69NoHWb+f*+JbbAPZ!PP5z6Zap8t&sd(i@UD=k*)-ULHL^)EmOH(OyBGoz~Cr zy*zfl(1Tx1ZL9|$9n|RetmX0ZrCtg5#(S(Q^SPGO%kkIwoRnetzlq=5V7I3)8}6a> zExj=*{r7e0_+H+Aeylf!XWM(@^6W44Gkh=aI6vMS$Fm(Wo;ScVDO1}i<9uUhmyG63 z^l6&O&xH<1e!ZJl>{w{k-m>=l;yqdMSAjEXF1>`5%%%ED0HYt=2*Xh@qf~onVIa(6 zB@9Q%hHA~77x*+9hjiV92ZkT!YOKod@Mab_!$}H?FQS0h56NF+oo9G?nU{0C(5=L$ zo!sy7a+a3>moNwSBe+To!3(qr?@#|cpM0E8#z709My?r&H3;)q^;hBNHnGl@>vMjD z!;tylX9;@%Tu>)MhfYYU^8yA!K>8y!OD7U-l_qW2;HX&%i>KJz;c?Vxq0*WIhzGBr ziu_a_u0r`NKDjOSxShB1*-@+D6kz{^#~YuO)m^zd1?I>nuBC#_yexw`?7Z_{eyETu zz*DYdO=aPQ^a@I|%gB)^hxNfXrEGP_XO+IJYMQo~bfjQ<2p^#)w;}=DhIb|%DTw8C zmcR!TVHp^=3_qZ6&(m$94rlPp<8?4D;4PBgH)IYMjYmg9y03#nhq>aEDA!XWJ~H|H zm*9{}6GeMbgl_SXsfwz#0=QA|s$@EtJoIYLg#@c9`Pcm?;aTw_ zZ1T!kQ5n_woPXj1s(~{NfpCV#61sLqi>1m(|4^6=KFDWPXtQPEp?Ym!n7yK5fI{#?M7r16ccYPF(;S!p_!ToM(3D@uZ=m_YS^MB4vH zy!>Nc`nrS(E>xxVdG?4dNTd0ZOy%T6Q(53GvDoyW`d?k==vBmvi}(a2MW4Xp9bkb= z!n=D*FY}pUI!9~AJKMqY3t21ED%_a~Za9mv;J>fI=Q+N=&%Cc7L5~}L@C1%^s$}&9 zZgtuEQ2_D;jV0twFo%`bNlM@~9@2*EHl`lvMX^w_mO|O2bk&e(XmzZJ zUsGi|@Zg9ea{mHdZ*(T5JAb*eFr$QG&Nhk*Mlv!Yvywp2R{TdbYKajUOhY$PAZSrE zYL}MZjq!%QJ6O}iHVcm+85wc=Sx`DIB~wE;Bu}DJjCw)|!@y9uB2f(^Y5^s_i4rDK zM*^it%$6FkC_}aF#)egPQOs0;l&XcDq8<*00jNCC`$cVe)rK{8K`U2b(xLxc!VoAe z5WidVmNv{LDB(q{-wJ-)8JQ!0fwnfI6WGz^1uX@un>q#H%(H`982MpWv4BL*E z<01v4a1#!Q4a{H6{f#R83M*PqZSR4|5{;PFa%vE-SFjk^$0G}tTYDk;YcOqWthU-(ivjim z2}y-ZqL9(gfv|G;}9e87Dhw6|Rh1-4U}wNd9$8 z72cPn>P;>xB>Uh>tolE|+F+0{Wde;Q74q^AaoX;)2c9RsA;$1j3PQ#QLe$mrBZoL>u&`P zf{K_D?0F2@25gziGe=${#RKJ0PSGUvqL@cfAJRZMtBZtc6&|mc63N06FkvJh&LvxSUK63bLz!@&>{g~Nm zaK74vBk10k7;$1@@^Iy;@zEOS@U(C@1IR7NDT*6NZKIa5K>m?#Q~rA1G~@-mDh02v zoFzt;52#mpZ4a(kDxuHpw5e!cWiM3v&m7--RR)+OS+%rM0dcs9i8_c&^uG=d-X=Yu zyK#O;w`^uUJGXA)lLHhUbrK0qe0)SyaV>F#x9cB7S+ih2jJt5;RjhF9L*RIT(XL>1TYM1|cX17fz5<(uOx;Ln1stXqmn_btGc>+xHUOTGkOwjRqq4~`YW-G>sBryG2?Feu?v`j|xlJ+37LIB51$sK!J(^;d zi4}(Bf0J(Y9CS#i*dr)3|Np|nr}ZYVN*z8H+Hspsb=Y(SpEQyn84awBb!bUBC<&FQ zkZ78EDR9zrP#0iaKZIKVk;DeVv$VgHQs@RJi4k^&uF^py8sKLrvl6r!NDlV#Dz3W2ShBvUUuL^4H#q3AA z(b$~E#)_RoBp}6qh^k~?cgzyAF%KZ`=eK0ikpaRS0HZ8qyb*A> zWj*S*fv`r2eH_6Ent)Obn`orz0Nj(lJdH|>3K1jtK`dX`0T7LVu>9PwD*kXStcPf! z=DKxl;NAVe*cmu2u1BBnh@vmD`4g%EGn@FWA1UMH^zQxpX=L3!Fb_RIjbxN6gKG$C zmPp#yjd$M#>{f|A4q3rXbQv&!cjsWkQjE2 zcuNY^k^ohG16xRgvvC(D zBS$YV=+g8iJpyB6fX7pG4huJDkpEd;$UF_?!T5BJ0Ah|(u58Ehmvkuw8s?$cC7_{Z zA3HnAfj)HC%NhBN{fqbw_0zJoOv{UGYem}WD0;EOZMPV*eUYw}Y$S^E+7hCS^>;dLz5iRUNWRHceIie~#SG z5kIDoaG>$b!}w6bcKu0gft`YZBGxb`%SxdQXA?hyHoKAN5lt-Wn1Lo^OvS&0p`Myu zJC9&vreaUPNWrG!%Fui%IMV6kj1O~NDuBn0zH6+R@%R%14Aq%5$xGUUyy?C68~0L;(Kq+q-)KNK4+(BgtR|{!f^@s*z$y9BsDSFRrZ`$EI&U1K-3a<2bPtmCn+gNHj4*NHYj|A}$+RsV6g()SQk(&Eci1L!X zVEI$HqW`@tj1n>pl>JZ(y++|r8lBu~tGIV15$ink@C<B82zX+3KP^$1)YOic(r64+&?2pDRa@2Q z*(Pq$5j=GZ)(@(FpthDMS89EWeD_kl0p1lXXFS0ECN$45gg=LL9~?r5FMTfo!CsZ} zv8ss=Qi~PmZZv<%>~u00GScPAM3)s?UiAsrL3~x1t20W~511H03*pjkkKiDao&e;jWcp!{!aXWyFPFz*kW z78dLnD15LEC~N|7BcKrP9ZTP6zBz@W;52pmfNrez1oaSct1e zHa6prci<&QLeoKr4@ASlefX>ae;}thU;%TCz=lX|Tj=GtTf^S>? z(r_;a`3);Sb3B-N>84(8c}V#N!hOL8)12$T2k(OQ8HAVYM#CgeE;CVawT=)&A{>z|SN=}!RUQ3ExNGYge@rK-ujZx6* zb5X|*ODYEuWDj~X8ge0L`ms)yroqnHHnU-tBwP}}MktMb!p?ptUT2x2QjB)QfW?r# z1&ZsCHjv<8r&qs z1j)`AO?b6vLNSM>H6K( zy9QJtMg(pTQ2hX&u;hd?hAOjDbqX&6bn)qsby+AYKr6Oej&Zz&6$pg;N}B)}A4&Kf ztgt~z)dbiD$We+UOQ;zE(%I93s4U0DmS^^~4sf5sKI;e;G`Moq#0v*oun#V*tshNMS(x+qnFauSG*E-bP&UhhJd0qj1Ed8tKagRzl#i2XLeR4GTMmquTib&Bk| zRiTqJqe{#c!ubYBV^}i26bB)w*YMcH3bLr6nk0yL6N_bnts>3^FGU=?B=ob4dlJqIKnZr5-UwN8PIf2Z|y#*lI{9Q7_1(&LSl z26p?BBxx0a8Um#q;8da;l$oVw{zcdlQGvw1KkaF@s4X|ZA`&~bO~oLCCg4#y;-z3T z@SM%66%mrqn?m_m?Nhs?QpF{S$KTOJSy<526%+6JCP{Y(xgNF1>6io&TaEZ)j}p%W z^M8XW!EbUDcqC~0+q@gIHUrQy9MVmiz!Ix`Ps?y^hE5QEJ+ExDyJLpg(fJs>jM2YR zIt9ENi<#6~aaRM3`__Y6W6=HU<62#y&9kB|i)Cf4?o9;>qx&Iga5Vm+QBb}>L>8H< zk+d3ZmLfH6pX`8`r|h{YT>}XZwGQjvj#pWoUp4n&Pz=hL;urY>$7Gh( zXe-!PWBySXgt|?nR3VqqYcuyqh&|t9IZM2p;)Ofe zl*Y{7`J{@<6Ik6|l9}hJtLeRQ_eX4ZG8Frc=;#1h#`^oApb{s5taLoBNZ0t3`+r-||Auj8Cbi-ofN7l=#v z=IE&X=Tl?$pB2XKKP^nye_~IT{%hvzcI+>0wsWJ2vg};xZF_j9WxsEyHG0Fg(c5k; zmF?oVRhry2w5{wEB|T6z zgSH~V?A!hK9Ne?f@Hp2fTX7HTKuluwu}kl5*}Sv32r#Ao#_;PAe1aB;xC!N%4yEXU zokJ)^8!K*hzUVshC43JTbMD=49--RG9>X3ENh-fQ>M<1Jm=0Z7aB~QuS9D7VSvQU# zijD+YoQU%v++EonL5R0WJQ+biyHR%xzc%T-BX~aUPTBAU!mH1D*`Dp%pKb1?pZ4H_y`FT zcq8tavS!?SuCFX_mnn-SqO{vgX{J?02O$!#t6eDT_P+8)5v~!fo4--uy&rWX#u&XD zN%V{3U2v=J0p!0)Y8=Bs6w*&=Ti(6Xy$dj_xH*Ub_l3ixNwZ4nQojsBMD~fX-3==m zM}JW(E<#H+5PYw4=qbiMApK+DU^qajGPDqQOxc3r6D{j-OI(n!?qku$Dvre)I-E!z zjDs^Eeg;^7l!mNeAY@%K9w-RJ3cqU|yPP^2R&3Y+kqsoqxp;Vz18stwwm{C$DD4nd zCfWO;v_R|&1XvgG=1?JaD>6)sW;~R#f%!cIg^)HJ0V89qpE{aypQF%81Ym*&UA;?P zf|5^^-!kGU!2~NML0*!Q87u;O>fm>#t9aB~tP?;<*i&^N4IBU=F6|rx>4#J%<)d&| zAkcr+k`7oEVZ)$SfR76N3h^ET1%O9J$F)xqSpi!3wDKr&`=)-azw3A#UFXZjB}vR1 zYz{0X*z$lCOzDnva6Hk5NUb9GL&tJ*tnY<_PxiBvkO|ntbu3d z)}bI}p%ZYVBm=fF$%z>b6QVC6uR}(fBPrsj5R4H?&d8W4m0TOunhu$gbo!^;mF5mL z!U6D76pI`9r!_BHL8v=ulzsAQIAXdj-pof%%qg|UxVdehA^g)iQI6unESH;|xX9LY z2y`wtZx__pMU4JC&d?(N0%U zrK}TcqPCS#l1tr2rlE||4e%9zhnrfXjjYk&sj!Vo>8B`Pg8zR8*kt_3sJX1pDwIj> zQB}^adJ8S5CB4W%$D%5*la>}aL`6#Ppfza7qfQP*0;{fK0TysXa71_;*-W=V1LG++ zXiuyRIsA7x@^5H|PEmcute=ecx8Qk){ow{|s5)vL1RP%T23-^0k`c>jg8v6_5K6k*7-#3bop+Xq{LZx4{i6 z**cS9Llk^dnRXeT9=2tBuDgq`N2{Enfe>Ys?G$n0H_f#>M@^_S&sAE=FRgE$aN1vQ zS_TKL&B>NgI1+2@hE4Nn|6-GF+^|VvwzQDVA5=e?{EMjH&mu<}F05T%eu?eAz{@Hw zVNOD?r8fK$K>U0JA32SJ)0JC$p^hwn6wwr5hk{KCD#-~%oj}|LC?mO39b>#i+h-O# z*6p4{yAq>LEW^6xW?#2HGsdmVICp3W-i0{F0w-HI#^Tf)5-ZZZNh=cX&E)F8gZ_vH z!mtZU*`S=Zz$`?Lf3h6KT1#P1UQ8M&+Dl4bX&44B=E@RKQHEKgA~G|MHkg>3iKees zU~*!EQ-S8dAWx*z#H4Spor0T0^v;Qmwydn6Of*Ak z;1z2KrnWDPT&#`J?;|59ybjnaX+Q%E9s)x{e^oyNrx_|L*1adw7(qehaF+GvI&gv7 zRGDT#qUN)Y@gJ&G3lyWLMS0@I<$9c}w0>@5v^3TE|0f8|5iCpGzd8pkI9U)J4uXAw zf&UjsE4@icV5p8?E2zx~Xft|24 z?m(!=@j}=;1vP>AtB$|t*y$xOS;&Tbn5O34UonTom~kZCiQ@^z6iY4XiCuKk;doy( z-;-NPUW;B7)?d!4YAkVEERip&3-$*(BnJpe9OI18Q;KV;?Z(i?EF+N_B^F$S?`8^AeG6k__)Hm?3ml?8zGDcPewc$ozN3)qZb`16@$g@30quUQ z59C_1Qynw_Qcg6f_y-ZDM`D@s^8%#7!=SZTGe`aEwI8$`?6x z312Nc2vi2HW3UC=kG;C~Gr}Wf-kfCv)kvd2$!s>@+sp$wekeKZk1d~f&kgw5N(lm z#fu+M7K`+LO?8u2L8x!ddVz0qt`W~0q^=-3*evxvHh;Ep{=i9CAmYuTrfiX+VH{{+ zmZ}iGtMKIqAE34d>1?c1cMhB3(BycYMme~oV?GKeqTN@;#~^++*^wmoe>6JCDw@d( zfWSmue2j6?s;gUBgj+iQ$7bd|V z(nH+>ie$hd+84#qi0q@Ad0ibK3AZOkv;k-BkR_!T`D-X7oFtQqun_tLO@xv1AspD% zJCvx(iXgQR;}f)<0!vtYkQ>ckUiBaP_h^<_L_y6ndF(kDeJ^i2?{@bmClI1GV3(2s zS9}&!RLV>-+_ESFUMee<>ry>gXJy9~>%?9Bd5D)E^>Ou@?l@u=P_z2lU+J2vh{ScG8#2cg13Dmz$+o%EIP z!!c|!ZMpR(yj6H4k>~$ww({q3S>ynkKT-{jHTnKNZ}m6wYQeq0N1NGnIFRA|IbLMd zO%rm&LxUyvx6u=k(VSv;JlSqOtX^-`KF(@hw@~2B=FAsRypIE$v8CoLcAK=%;>fW0 zgw{p&#{5z1zz=&C?8f3EC+4C3Jn0S6iS_k3VC6i{e1oi#MJS^!y_~;=XT9+VvleKh zO3Aj9jK7<){D9&a?3~KOW}dwaajW}%-TNT}74REW6V4cU%0Hjk1qmpF{ZvEn<16%> z;6uGa+Pm&K$U*SZAL9Nhb=seiiCSg&)jgY(h?tjC$9y}P&Tyx^WS@h($N3`KQ0k1J zN29LuI%srf3^D48ucCM7iytq_8Gz&GzD?)cjJCY?DxP1OknMFD_z@PDCrR6%Lx3ao zj;by3{-$%ktlz&Kxu-f)%bNkMpYLqBw6(Kkd0S^YYTtns!tNkyUg|DR>y*2rIENNT zld+zb_3DOooyAs{&JE|jsB7EabNv6zH%%K`MW&v^LTB1asF*ZilxX$XH(BS#8Mq1Z zrxRRxH3KN^baNLh4J*i^ajRIy@eBes9=a|w`# zr9$0`5{^>7#R`G{WKtN-hKk{Zh2s)rgFftuO?Yx*GCKryFErE=B0s808lyDoEKb59 zMZ$-0FxqKH>Lz2vwi!)2mfonOdP0#UELYO^?P@}kY^{xA1VN9hblGGBQJ?BAx*1gj z<{|zADHKaMdk-CS70mLP=kGj-K-ugL3tP8-M$}UaUwS8n=#@nm9|tUw_bZi0BSvm; zBcwTm3ybC<#!?pQ2Y0T-EA$E6AawZ#f=i8NJlt`2OiBt6kD5fc?uf#FGn-)}6ni2I zfZonA;PfGk8h9KE3la<)ZM{lQQ25DufP;r3&c~P;1bbtjjYRAj)9}>y!ou#_gAuqN zs^R3jr=B=`;_z;aj?AX$88GVV4U*WEbdX&)oPBGaf`RcWiQ=4LFyblAq3YZ9ooaXD z2OQ_(3e*w76>XW3DU717(Q*`~0+m5#*XO1S;oxY%s4r~r3i{u-4Jy%wD4E)*qY7bH zVucwUa>Y`2bzq`E&8Eu!!P9Vl_6UV_AbeQ={G_ z62Jp&2?hm}5K8P5DIG~3L}C6^&Anz@l&cTq0clhO7Y=?@NT07#q7|tm3Q2oYu0y;5 z%*esYVc|?Fr<(1Pkl}gKeJhao8ZZ_%{B-nc)`tU&&>(~|0HUSW4Ct3=&wNg?JnL$| zh8~F0=vSZ%s#K0MuAnF@4ESla>)Zi z0TKF6T~NW+NJ;x4#$5$P0zP#k3fWj4RkD!yQ$^ zPHr&t@o;l|6c?NFgB;YrWTbKwodjP@nuOm^f-XiF6`C`&Tb&sQVqAE-1=(lkxi`<; z2Mh+QU z?J#%vsiRLFj(x?${0X4`(I@@)nF8Uv?@zG6S8$mrZ7jgtz~+h+Bf^?&UH&S*m= z_L2Re3No4rWID9ck^@{p$dTr`YGszRUHdLZ3dlwa{_1M42xxUw1UUq9RH#_-;{yVn zL|jCAo3h$7E1EbES1th3hj?NPn1946V4uVd745#}(UYk2~?C|-BJ>nrRQNBSG;r?pEn}U^B9&5vAWEw9n zEFg4f3(Rl?6c7ax8y)pqhmygOmk4i0Us`#shSy@a%=w?-tat^N(5k{{Yxp)5nHXEn zfgCeM|I^I%_jsw`MmVIwr8ZKJucH=x%cpyxP>UI@+TX_;k*0yJ5u$GMlzwA40Y|CU z9}sZBzZqq4?gW!)Okr{g)2fUe*bc7a_Ndj}om5I}K+ApwuP&mT=nn({!l~Z6F^&YS zqdi3J@7a|2F-xrO);bC@|x|wf2Nut1~&KPt4pr&_i|~YZQ|TJ!Jjgycam1(fT8J*s{)=a=jE?_) z{*39Yq{Ic`O}zFfU>*EhB*gJ_8+XscLX&ger9&pdu)k|NrFV8sjE+ubC$sjD^A7JD z*HgHEzHR4AZ|&YYHMBGD+-PTE+rdBQ?X**={k8)KRePxX*Vxf>)jSUJ*kx4;%6Y55 z9K@A>%Ymb-Qz-qFz2>~b=O|GeVd=aI?wY+?#3%K4gZ>pf0nL>06Xk*1MLY2?i^H|W z6Vg2d-%w{6M{#ebZzxmPAL{X5!T5&iyG0zi9p5eKyCoOLFXLVKaq3b=qSR=V8jDin z-Y|~X9(E`3*@VxOYcK8iBy9ceW_QbLBlBhWNRHruZ3o_qQ7e`l$wAN1^8A?2k%!l( z@&p}^-jUWs-k>~idjtn+Pf9I$_a?UjpT+av;-b(+~=zh+9pXA@; z?#2Br`uR9cY<=zLqyvpxB zM2}g4_QUQYfcEZBfpF zvN{m`^yUS%EbI40Fw$-Zk&q;s4HFDa=~YDh)lfEN!sjz$DuicH7bpcicsWAWGSZ&f zHUR-AzI903cX3lry460yx>dC8s2(w8Vo;z{9H7DGEd8dp+Gw_MCZ`;tOAabofN~Uu z`-dEb28I!Q7xRdtuXy+j>W`Gb_+naVO21{q>!Y;j;jqONIAar(YQFqdZP=*wQRuTl zbrYhLXGHqc451(^4W(>>#$gN{d_T-INHqzDIdR|8Clnq`7?Hs~^E7a+ST+L=h8*0U zI*=xz^i7O#lvF5{zz1rCP2_UXPg1EI;Z>?#t+q%gwMHP#BfO9|QYcC&>C;eI^PoWZ zufRt*mYvbtji4oM1FI@JT+=euPELYkpw#R*H8uv3=;t*) zU$t2Sx&h#DTeZAqkYA4NJy)F|x1@DM=}^o;YJ5oy?RwuKw#Wz(R7f!r6E(9>z3m@hD`d9F{Q7?5}K zE~c*>eoQ;ZnmA^#w+jo8=y`xvMNaEi?QR?|TPaXDYv^K%0yt$Aq~qmGq98t;}aqQ+^ z`>NV<{1lS@F!*nTF%)_mmf}$j$JA^K3Y37*D<5uO;kOnHPt>wuHgdd}*IoVW!Y1b#czNz`(3LRntUFdLGy!U}ReSy4_T zE6EvTIH^p>dz&eTIqZOdrbvVqc3SnB-SzJmnS+-Hc=-S?5Awne_zYz}GorLbk%zoL zs0exc;08s&o$Xx~7fUp3$`7OW64`WgET1hoJT5B!SCWIHlv|QHI7%EHQvOba9ldh} zhL0d&V5ouxGNz1czeZ2nECUGAV+Rsybea^>ut+Z#;E_vx500yW+_;ENM1K%MWRQ;I zTO1KM7%$`{2x#VV=9}%8@RIZk;w(i$xNnRS3Qr=PkmbZNqx2xxI84gbhko72vQwGv z^sIKRPdbw){4k=IaEjBbEH)lEfqFbrMgJkz&35=9FF$bA>{{}sqE8=Z$ZZ||!z?2n zDwg)E94hg{fc9<@AM-E&mQ!HpO*K%-4y+p|;`%H;Z|=qgF;oFQ@f(OS-o9jC#z?ss zDU5{OT{$9jQW+*x>@G1C(+*Ur8y<>`t}=aKRWA0>;O*~5tj+4U>X@Gi#PV2{c5Yi(dAdbpTAI`mhB*!ZG9Dt{Ef~ zrZ3XyhQnN5^wa)k6KB4FhDe}NhFN9wPB?u|no(xyLa_t?C{SgQ4K{!5K%|hBfzDjQ zU`x|&5;smsOhzbOFT>STh9^(OtQ|hfCaHT8eb)aM=voSr>^zPzlo+@DKs=0R ze@Y+{Af+5PW*G1#aVs@RQn0%h?{V;b5~$26t7XAmk#07CAqm+FDqJy?(~7iFE&bA{ zkT9!z`e})y2xdupVyH%f^#UJpie4L-Km=@JQYEI5tigma)Y0OoVSE^g{n&sOvzLH} z(0rjY;_mfB{ZJBJpkAltG-@W3X(G-87RR0WL@_ZV;yBxGu04^73IikMkNeZ7ktbBI@#LD#T9cfK|XzmH{>i!pqD*$4M55nJ9@nVG$#vPF5edQf%&GX=A zY=|F>Ew@8%;WY=Q69?{JP^h`3Ubd5Shc8%e`E?%5IMTf-3Csle%L+n{c8( zi!ZURDg7+(Dg}Es(Hdz;nudo(^1UL>O%nJ7TL}vwOj+-BZ`%O$@zNc=eBwy=hT|wn z2|q@F;gqAz2YTvo2twmhvwq5-XWRY*FT!SVt;f250$++b6Rovqqo3iuSCBJ>S>*(2 z5B%qtC*3FiBe*xr-f&wQ12;L=4rr2%E|+Iv;l#$R8}x1+Dxsu!z2Y2HGcY1l1+H3` zfLb727^{~MPaTM2b?;SiAT`yet)+R65{BZnDHAY&3aDjDVywb%o;qS-ZNd@q;ov${ z<`f)wPBRJ^IK76&mtWUl#N~yvov%1g|1!{}pg4 ze19;L;y=dfG@CN4ml9_8k8q?P=jB7Z^o=>q5_{28|HF95K%Oxd!nglWoN{wbM9J!` z>ngj;t_F%$U`;A@EDR_nBiZa0V{c^`*z604Io`r5FJw69-`vSFpd%P<+4zRL z_NBsQOjLx=UwE8hxkb=Y8YMN_v4n}i=OB==qwYm=dM3<$v`oR5_f%3V7OzkKKSjIW z+BE%GB<{~tK1OlzJpHYifQgPwH0EE6C*LEwi5wP#P3wxyz6Aw{7^F;nc?EJvR1(Wx zbI>(H{NwJ$zux*Y~xtva8fR~Dn!Og41@GdskKn{Kw2n+@P3q}2)33J zlQJXdVkAF`%%k#%z1ptdfz~8Atr$yFJQh_`v_s2rb6)|&B}m-=KGnHu#xH^EQYr-< zs~{1wazA(vZ7b9$E{sZiiv0QvtgXfYy;>$kT7s)((Yl=ox4Qg#)9?k9^oSuiWq3rCVTO$fPNIqw0&pRWR_xaV0raT_6Y)%h-~?AhisZ`EZr4N{I9@-Hbi5YM zfQ-{n_wIgd;sDSe=_&|?-Ogo+W+ZddUjRh>IxcWZ;acZY{Pta3;KGlMD>&Q`PBhd* z$OQB~J{eQYIi6#|tgoI9VFGudEtU;RVM#re*`3^YKz@DTEIow>U&T?`0??N1Z7{5I zhT_};gpn&FdLgzH=NWScB777GemS{KtymiTx;rW0r)J5sXaQF!eCWn4V|}Nx*d%C z36wk>@M`gTsoWW%oY8^&dcnGoMYy8erSZ;0XOi3OK+{l*65x7PZ4=&_y0jUB+?2Wp zN|c}TpCt$_*~{PE^EegZ+yVvsgiQ=Y$*)JYmdfyF*w z)*+E6U$@;H)*=zymf>&*BDe>mN=-+8iOxgTazVKdxeR+y=z7=Q!U}T=EPoj6$Y4C3 z;~X=f(08v6NN+FVXEV zi=(mNJZdkUI)Se&Mq&=kWqRdO#s})f{F`_Y5l@^$sZU643H~`g?;Anp{0v8ss#wI> z<(OT`+j;o^li8Tn2N z*U|43g}kU^Bquj%T^i?Z$;+}SO19JH>N|k9N~uu!+ucrU)@O626y#0{r5J%ZmYBWyr-#-L@&;n9mVCGlp{34a0wNi|f8)SIof z6(Oc-i>W9*Xz>UOCN8)CpV%5PPq|Dj^CHSf;X9sYabgz{7raUS6cfkCn3AUR!MC&N zd+=(x2)+Yc2>j=8J{N)=O6W!yJg(Tzq&IInrZ1S%?zu^p8kC(^Td%O zN3bY;Es`_04)j5!W^15>;s3)2f5c0j7ct$5>gSL7Q!G56XNnw}iuFk;MU<*aSwt<5 z(v--;LQ`Uq0CiwRQM)pvzA%_J!eGLq@GoqH!L&z5|9p34vb?RhrMRuI zZFpN@a`WWSRB_ArmI?eT?=DVln;uz2t*O5W{VVuQbRg+G=-Tse|DMmmZIG^ma&`B+ za2tfPU;)l%d9Ns;C5OBselhr>x?jY7IHA#{a2d{dxDIQ#LWW)(c1K)iXMxUgFQ-J^0ul~mA%Wo31x4M+B~dV!+?`z zxC5?#dppV!$jJ8&1nkshFG22vquy@!7Swx#ym>2vd9uAj9`fPY``kTvwlk_t_g{ii zI`cQm{TcnvxO*Gl5y;-|?n7&Ki6h@l;0F%)cVV3C--!u}nAYH^8j-^fJR-=GD|fyq zE`^F)0l%Vpl#!MYk@1ZW9<5IZgRpjTQB7-o=mvJP$#H)xE7;1SPrK&ok6Pq);}7<@ z-(HIj2GdK0T7q$WwH(21&N%G%3Q}5OufHQ59_%7jKo@egKQzWT{Ucxz1V*tQK4@*B1hUo-9W-?mlH!eJ)kHwKZ@`v0Xr2hi11~xOP&tG3JnUv zDGVsX@E?Y#2nFH(@zdA{21%sThD{DmqbaZ`88A8(O34@MW-Ph@&`O>m$i<0J>WbQ+ zX%x?k2Tb6!N+(5v7pSZ^?Nyran)8jPYwTO7)vA5XSV%gEkv?dQLMwc@(n?4d)6E2g zT#q}1Pol4Yv>}C>FVd#=6GwF5&Mkwdq6pRDWIXT&b^Svi^5IxtL#sH^j%`u~L(0$Q zuZRR#k<2hY!9`r?3dHkJMWP&{JP9plR$_oo^z1SfbIQdEGHMN5!{o_s1iQdSu=5Ty zsJ5IoLZ>UbUg2OVT=7}XL4OLzAyMZc7*Ma!DdHHbhkJ$PQt)tR*v&GS;!Af%hDc`) zrotzW9XmAl*qxQ<4?X?(@fUFZSLJzq@2>bB@8hgEl{dcKeehUvl@q)cB$K_?9DjQL zZGgtrnX=-3g@qK?uCF7v_X;lp<8iH+h>%iw89fRZh6Ur*92R`+T0xux*Pq1$NVcNm z6RumzlaixC{ZFv?S9uY=pYV(#%?jhlw){sj+_xctFyz=X2r(8cw*w0awXgV{WxyKj z{lh=7-mf_Cg6ZBYfH0i*#(rT$3?f7ppWqvDN&1B$04#N~v`5mB;sAzO*-9LoG=`mk zf(Sca8i7EIp@)f!CynJOBI~$~IcRY6m*IWWa~?#b4HtOlWG-Y8#iIaa`F%;HAxeRW zOhj8Af|nUp9?Hw?h@S&+W^CA-G{Yf-0WDAL!u5VM+`pHXf5!_0<}0@@4ja4?VlC^V z1oSuXA_GF9587ECTi1DckUv)zit1noa`CL$QK}KKU$X?^X588dSdV7`>+LC6U)8mX zU=~m_+HMlmP-Tk-$Y|>H4lUJ3I)L~u@j|poI#sC+Y<)Px?3>wce9&$=CHLl38wa_J ztanjjLrEy4!MhR-j_hfX4K4Pe%&I0+SPI9q4muh*F}U`%mN|E@wXABCR-PMDZB6U3 zWt-qS!)w$^g4IQY78kK($f8RuGOAO`G^c_k&eeYu-GN&y{i6r0CS0v`bHTPen&h7n zryuvfh_$8OL=1!l)UyoN+&OpEsbPVR!=C9@@8gOiWnUJ)0m_)S!W zT|ZpF!J0(H#Ei!b9irq+IeZhU!VhyBK42wx5YQnGycRjab4``C9E?5+kCys`ef03l zb?)jsn6QKLtw&Voty2^*reif`;*nxqruXh|?A=${yMKS91xI=$HIMwkyY5cEhWk7Q zZ(8!r#3y93Nd9Rcz5lLwgDr2fA=SR+xUWGhS-ZUJHDy}8un!}MMr~Y~M!nlrzPMt| zhiIG;b~4RIGD5z_QL$K)qwGT@Ha__mA(kL9I49p*K^XMprs+Wr==WD+_jnffG0nLd1NS?4lW;Wpy9Kq#cb~*DY=tj9b z1;vZ-Grov>wai8MQfQKZCF->TLU$o}7fpzCxVf0QU^|jelZtHG!I?CMAF87RDwq)4 z5blOOOCO^q`*;y25v)`H-Q;=V^rNgL30zH`Ll+<2g&3whdL1$A*x#_+Zn`nU5pf1# z!2~3E)DTYw2 zS}4)TPcxe=u%G5#axGyoD*gj(9QB+y;|{zE*U)Va*31K6W;3B2)D2KovC?m1eFBir zn3{!~+GPN;?M7#`yYp%_rObWgg9`Y};uHKPE`2uXZNmRx#Bsi=;(shC@26fG!l|jY zzYX7XF$E{IBue?0hJaXLasAWaY;vx>EdvK1u0_BQ`qy8uwq?%eQ3u{5iwv`$L#~SP z;lN8Ff`XKW-MOOpzqdE!FVhX7Q>2?hWbrPkNDGX*X1FWuj8ISVSH>BE-!u6x&K;tu zPc5$69auSYt_TO6Iu-+yG4_x(i+M!zRX8z{cx@(#4MlT*h@nVtgtu{n(!YN`L8fbfRthO#q=l!eX^R^ zArooKd}(`)cO4(nvU24RB#x%G|0z8F2$7g5@4y*Kv7N9u!v0vu?gZlxV*yyD$nO6o zY%WM6dS8Eqyri(*&@+ixNHpzCFNdvYiYI$!kCBc@bgm zg9j1YH0$4UG4mM&!0b2xVeTUR0<%3EPxAgPrx4tb1VchSVv;CPN&JfLNKWO80DcDt z`;Z7QI4?_woiMXp{7%T@{LO*DRmu%6p+?~1Me9-tixWr}{16a~AH*z=719c7AI{+1 zP_(5s9JdPM7mh|^!2XNS`M;iJNPe~(&Z$GoBbRa{I{hsj(C$ws+r3Tz{A}_mTDgSs z9sm2>p%y4Xe|tbE5en1)tquF}^U{yF)dhN8zm9M;y~3qYMI_O7K*pxNVhAYc1V17q zz5w!jqx29KH4t&+Hhm<7*R}gg$#%c=y9|8O4-1akH^DnRnUg{itX}@l0&Ui_F+fZq zjKaq3!4HPQfuarH#>}#WumNWXijzp}wDLLVRvh{rR^A)Uj%V?U z_p)?q=ZU@J;-iXld*7PO?|dsiN;2)_xa*4&cWl(lzg-%FgUA=1kpkYB61_p*-t&d- zrU771k!TJHxv*J$f^WwKYb4f1u94KqMeGQIH%020-5|aov_KoApi^MbCMt2rwj}c% zLcVNpNUi4qj@N?x!gE|DEALV=1cyq=#SFb^q3NFA@T#tx+((~;{lx+Q{HmXz=jiTc&Ie6 zMU6)?%k~d7)_rU0=TO2=aBxZZ%UMM8$xb@5Ii$c1B3rB-R^JNRk99<&)bM0+1Es3r zaggYMkiuWTKaRXQV#G`j**Bv@%PRpAyj8?Z_3MW9W)KS7k&7Ia*XB)ixM$39No@F( zhDfl#4;c5NvA+&r_&<$AcUuY%xjjZtw3MEOjGO7LFj=Qa&aCcQs(9bfv(JRC=Uk(d$Q4^LJu(vn=fzcAL7?*giO&s!&PU86Vm~H4a3bKXkYgVd zN063?^9pB# zrayvv|1YOK1-m>PK}WCTuk?uqX}^?sp^G;mgY&2D!$lKE-X4L-b7ZD6&=V#Oy4B|sQ)kuU4kOE}m@%lRNQB?| zBmNY1@@A%}dlk7_Ss^HQB%E6on1!AzK8dHI)tr7RblS&xFQzNPXA8*bbMP}XS$s7T z^mTEzV>whlc(N=ye@!nJ6XU8N5x3M~uQ*8cuk7OJmv-;jIk_WOaklK=vvb>+{TLS0 zD{zszQh`s=&KtJnr}K*_JM~9ioPWWsAXLVqS4ZHtax;8mz`NsVUXDg(j=UVXnwy`*-A(Q&u2b$9-)Ae}W5Xa$a_H&> zYksrjVa{=c)si}Jo#H2c2VO7ICX_tI!&>ZUFyB)?d^OUfw^{gTiqMrxl=&xd4Yaj9}v4u zp7H*6!Wk{44-XE974MiEuypMXbK;CrKL(6BR1v)~mE4fZLCWK~->Ivn=YYhgBA<-aP{qSi+FMPfsUux~I=E_;;jE<|L)Epif`|Sw z8UfVhtE((t?aM{GH{c}_yOL)`DU4H1PI`&etN*=yh`G`LKPOsXL}7{+9(`8RtZGS> z6)zBA`gk+~ge^;%^}h^5d0dZ<9GqP27xt~|pRA7SUP?r3G?6f`rL;bQhA%8=pa%;K zd3j2lKa2-KYNeN$OsPm#a}s!x_myK{I4r}cekj8u^+L+(TLsZdv6bW``4Rj45hPOf z`K-3jlgH2a6Fj4{H3DwM?qKsatn0gUAP<`=MryKYkr&CcPoE8>muimVJJ^K_+{w8W zfdYV%JHY}mM&-At&>bH}7V+PPP|3g@p|zMG|D^n3=|K)R;I{hE9vGG-1m&(wcehNl z=&aAg0vlz=0xOHDtXYq;CN|H%mrx?8jCMziwlVDblskNTJ1UkHcM1n^Q%u7ynQV77 z-2{;kQb0Gn$1I8n?#HEPufi-KF(n{!0n{UK)Q2$iDoh55b_>|JU=&|>C@4V#1|<#_ z6sjz9-3w1^8zATi{0)-P(DYQ%0qe#7C#a!Zq&Q(Xi6R_^IgJhr#*1I%CR+i`S`Yr=J%w5E~&f5uS zuDT_M$DoY^(A^0I=0vWrT$6jX8qEvU4JC^HlVkKTqyLl$kZy#?{P!62LLh_@RjF=P zY)46Xd2@VGRz`d*ev%y)e3qi`-k_2PP>D!Lsgfv=^D~Bz2<4Fg0acNkr3DCEdBLx` zIPVF>2?B5m}jdbTRW$h~{qoQ#4pP{v8+XOF0*6HJq{qy9@7K zwA~?K6(TTzIVs{Qi@ICt6qSPUllCXGSlEW$GVI&1HOTo~Prw2Jbrkfk4zO{gK8Bfe zNNosSWN3bKD6?!B$FC+r5o6V$V4+;8k&+b z!+p@uP*Bjs*(Qw@SOXjIx@yMea#fC6IIzb+ttiHdjcFkDVrO&I7}^inQthUdKsiI@ zDMy~bVzh=JV=IlW^29SG%Zh@i9z5wp?4*e((a{lv;X#zdZVyJ6# zKi2AI12$3Z^GfSDScKC!sMiE` zx-ye6kU-R`q=-Yj^h5(PQ)2Kjb5OZbDEIZe9t&+)iBta>kZQ$*~`C5QhCr8Tcj4u1@t``aOhLdqUWk;I2c5<7Vi#|Jw3 ziy(1|JhpNvQaOYmWyKEk{31JHCqjx;mfevAshm%d%F%lEZ$>HwyqF#lZTcG!N-5*Z zC6lURIr}DNCH@wOq$+m+iL7W6BN;SdjCxJZz5(|p6X}qYW-tN!J0_6H)^p7>t!9Jy zXUHRwUX#arggnZNUoLU^|GV%zH5ro>(*Hr`7T)BCnEDsE7{bT)Y)JUN zm9z7IMvm^T$LRr8mBtPvc>a&DASvx<&@4sizK8dO(mlp|edO+6@~JROKgN`hG%0{2 zt%4W&N!m7$G;rRwA#2JGHBg04S~QD~aP45FX{&(CgE4K{%3V{Mb}4Fxv_+ahUG{gd z83bcF;z6&b#%4~bk?bpMDlo5+VNyPqwto_LRizs#pf967k!}!tagzdfO85MRJvXOH z+c{8$C(BB#z56{@D2lfK!juffpED&x@%v2u0WTsBeSs-TIL}$05x{m1hMXZ=X6E84i{eTcM(JX0DZE=e|l-O$1b$`lDT)e*wE_^mrz$y*ue<5!4*J z(V!P|B*h^1*d2!7Is7gn`j*kSF#^}fd8y%|hb_?c7XiaV5!b4{Yw>_`8N%=; zebT|HVROlf=br-aEKi^wQVF4?ngs(ttT#nKT?Ebxk#8X*3fnDZ!n2{yjoEPX;0fLF z(Zccm6sf4b$Wy}D3gg*nBC(+n$#x0X9<JNxkuUlcOFCv1kAPDLs1aoP5Ws~6Q76fg2xW|@jp!>#0?bj@Ddhuis0s%tAAXQ@h|KO(el(6+6eCKc0||=)e3~rR zF??CPKZ{Q=j*F&;!W=7)sP3KM_&K00?`(Pq$)S_=P~OJTem%d+qjII)^dU!D_~xHt zN7ABoSfUuEp!(zJihmFCM1ckq-H5YoK-Z0sEd3zWXFuR&v0ZFwP%+Vk93m_Cl34yu zJcV%Fft?zP6^9!HdX5cw{dnf3Y&Vy!sLnu=e7w}e;?%d8BV(a`JroMxhbnnD~ z@lzZj0+yyvc*x8{xG8mRq z@eyTALcFis&A9FuT$AodC!{-lJt0N^MfOCjS`wTBQL=7YN0_RqRmuMe4*$f!6)9ef zWV!hxHtH^3zQBu2g?~eYk)=hJDj9~WFD?HXZ+s7%SwSJP>vVzqEcpqpbf|L5{ z0Ci|Ts7R@-)UMJwx2lwGh(*!Hxq6X-9b`)t(7`RZKC9EnrEEotFkX+M zQ7R6}Z!mR?mw(K@qz5e=t|9Ek;)^vl=vN69qEHF;z=G}nH1aRvXX@`J{CWhR;2&nw zOCb$f*q+S|+Ptc7wPic&9*N9TW?`f$isq`Khj0`4#@WBJU>0CFDMrt5AL-FkG=WJD zoy(ZWM!hjto}J2?99VQ&Ufvr=sw~^NwHXFRtPz-_MzB@c)J;>2v`Cjbp`WO73sNdu zgU#P!hMO?PG@XBwn_a^BD(+@%;+_=K*CuQnkJ_pXQS<+;xpR+>^Dgha=Aw}_8eJ^O zvMf8!#JR{y90danNg#pX#37_LZsJlJU?thFY|F7F_nlFUr=vE6K*LgYDYSb|OGEAU z>~1-`hg0@)PFr@{CM>7h?e;9)3zwnW0xgts2?e?k4A}emKF@oV$BF6wv$E$m@4WBt z{av5m^Lu{Jb%G~w$q+AXWjo)D5GbnES|ov)1XU&~;@j$ozaztJHwfRdG!>O}Rj|VZ zRa>LqS6gfumAh@AH@GjjhH=4|+ghYimhi9=To+vb1YEv{w_Cm&g4cLHMnrA!*|^Mz z^Y%>qc3Q&~zPU?pVmdy%bd}YpQL98TYIfM2-PC_|I&#(?jY(~(u8}79&A}XFca7z~ zMNceGjVB(#W@ixJ9fJGl@oTQ_lG|h0T<7huUYi+z;8AR@&)oM>D+jj)w^Q>C_GDu_ z@1O*muS|=hJJ#<0D9+7HuG~p_YFtwz=I#vcqWoP+4u`RF@Jb@!lpmgr?n~TyckpWN z+-P_9LO^QP3^EyodxCp;c2gh)ko&^}tkA{BQE|UJHF42SyqKW}&^toXFbv#{q z8S9HHT4XN1jU?Z(0G-kC@JV;4L62FuN7h0HH;nDG)PK6R93ZeT^4j{Dz)EEOASmz| zQoPu?`u*lWK%Hg6SZ@mpM|PoyMN~_{z-}L`*-VHX$zM()s)&usG`~(~)vrNhnO1FycyqVsiFTg-z)3(8gG3}vER%Ej% z?CK|eAwK1a;0RM0V%&!W?J>92QK!{fMT9}30|GU>f3?e8$ts{!t_U3Ptu_>N{lpq* zC9?<@+yw-0dd$&e$USrrYyqAAyA49riTFqu3Dg9T79>pI76soC!l7lt0r>w*0V*Aa z=*mRdry-erVG_9&t6ZRLcm9; zRd5Lsk-W~9LArWk6>Z%sk1mI+E2iGVTNcx`>ulH?=?-BhfemAq*8`MVPi&Fr^~EZ`F3?1xi@T|$ zi!f$b7q&sp)nQf(;F86t=`~QsCyTA5G&jJOlyP*K@JQ%1nOGP7mkhcBxp)OjAcc*n z%6UskF$`@?#{8_Cip9#i$j4`6{BB ztQAArT8HkCA*Cn)NfyANRYk5%wU8s^5XY35Itit4;L14 zQxi|FX^bqLPCC>8MM44|mK;0wW3qUNuyi8>V(s&{ z&FvwSJ;k2T$mp2u3z%G|aa9avNp>Y=NJr*#R5NXc`!5cXlvq2K|i_SOz5BNRVtq8JKUP89A|y zv^Zi;bT@d&Mn>C9LyyvK9f%g2Yv6KCLziVv6JqK$+H|wfn7oiKg=CMVK!_@bY9cm5 zYn)yUAK5Jz5HYkT{eqj%rnQKlRr98*jtd>v&#bO-7mhBGQ*1pf1wl9kj6= zdrmS(;4DN=4Ey&TjGf)ui7GTv(%WG(b^0Q3GM}oQURwj zD&I5QaRm>BWQ+gAO%)$$ZX*`* zZPWt1ZL$DwV*}zotIR-es?+od&s!eAHxv)$<{z~b91sigkl$d1J;LrvS+1M?rCm0gNd2`QF_0gJzhMGC1p^g z#y^VQ|KnE0-;`zH%DBDtL4S*qebE=DD?JCIY4O?PwdfAdNFIww=+=Kmhxtxz+=heFd^X*cPWD+6^v! z*Y=aRvDe&L-!s>`>9U1+8BxzX^B{cJlXYB3A8j7%RQ$VDO-pEv`4HGS$ajW2XSbri z$P$M(_f=#{kv~q~!v~cNGK8I4bTXgUK-oI$)S!d4?XEVc6h~Y-jD%Wz?#K9}y3&gC zh4zfDwA#Y|q^pmSbSCGW%$v_|(4lN9!ar2CW!!c*jd2_r-&y)fv!gByd0OQpD?YRe zKBza-nyso&>YmlCN^Oy&x@=tP7)d;%y5u40I4;6Bu(VAsu#2^C_T%LVOg;FAF6hPK zQa@UuXkf**)v}#T{uObgT{J66{8beyxUCo2ueZ?7P~&u+m+A;q;woq zbk5KO*B0rJ?*Ts5pzv$hvJ6u2#CYapCF`(-=n?|*&WP=72Ged-nL>RESSdIehzW@BonVXPzX_l= zyz@Q^_GQrJ#qgK(G%qtT_q~q^z$E!8S7QM4Z>5!QwQEzyWi#&koP(MH4={1CKxWx1LPuGGqtK?%`xE@bIqY`OWe_W$tt8PO_ z|A+^_qK+1MuTsi(DvN+F=~PnRS>D4M^WAQX=%G!*%^HW#rq|X? zs#cICY+R++%drY}GcFCC=29218Uc+wwe^|C|z|gNN6row_@~(y@G?HhdGNyFzcuB#~xQC}g)U!+B zH9Rf8Om~pf$}NSq$nzz94Pu{Q2veYsH3ufLF{xz0{w{7CZjFWOmN`Ggotj0-ir)L@ z>Z{A4)Ysi&Urfz*~<|IlsgA-;(I;8I|N>{*?;YXMu{c;@vG(W>B zRNT!kCG%8X{P%#seK3Utkx`SKa^ZId&JTvmODS_ELa;GvJ+Zp_$l9s6#|!l%%Y-nE z_>3yoyd=e?XRv9^OqRF%y)J!;S!wAyh%<5e$0xpN%)~{BG=jkAiPq?DyW(^(SHB0B z?m7--^h#|>xj#2GDSjzt^<-L=;&>e$IOpI>3oJkP;$(MFSqF`4z39>8b7xZs8SQeM zkBpK67A)3wa+1A*sx~NjW~-7!;K(8ef7k#pNSD!s$2^XiGQrbHjy3RVSByWBYi~5S zQ6P441L3d2vqH)R?^Qdhu~)^$eBlP>O8!x1pLr158@AV6RM9*pbqf(F{E!8rqay|e zvqXtZF2$sfm{h$FHFqsa#m@SDzJ2Soz4Q?u#wIxLrQU^+63)-fit5qAXYPMw_ zaDf*qL&|bZ(JUU9BMa1gQ0ykS4xU6&cC!1u$$h!9(9tb^(w97$52mp!4hgN<%e8-daiSTB{JhLh|W#b^vp4x(<+`Mf{TuT2Sk4kgNS<@#GS6%NTrCbyHv4eQSqO%L;V1er>_;=o9ilyiafs_l z&5pFzK+TeP+QBbjmM%K?sJ?gZ=hp9$wtA(LBo9Cjv7I#wXC@;a05+M5?SuD0 z?Pq|vxB<`=t?AcG(vuvyL5ETb61tzm;>BR?brj6{mtv5g@6a%aoZ^^rk-4q0B`PiG zPBqmnx**6K<0g)3IXV^ba>6l7$EokPZcZ1i1_!@_c+9ZXkZOvjB^mvbqqWp`LE<EY2FgM~=?QANr9%JWsi8R)$C;m(B znHdzk|Gc||23|bUM5=lMiaQzQzWuH1U6zCcAo%R-zH%GJ|J(zo6RSRxIJIuPY_^|) zPqU62S=h6l7vTD+x-M=<_~#_K4rXUE{G779mR^RMtMKzmx=hox3|9EpdiVtr2>mbW z+RC?@Y~7)**W;nb43hswS@L7PSz|89!{QjjF8`+(VKrieDQ0lxyHnLm8Y|2$u(O@Q zz^)Il1LzVjhzY=1b?O8ryqe@p{erd|QfQm(Y3;rOXiI^s-JJ@kpsLEHZ%r*qG6>BTo2k2wv*lf6&mGwRm3) zMqy?lSt<~`xPcmXT z3uPSdX%e0=oR*6MSpNKm!lR!YJvZlDddL9;}f^=Oh zms&g0QR!AhZg4c^`qX?-@h~`o~$n(wKdm>0dAZ z6rL|nU+QP^wygI=MyD^_hopy?hg_FlfsH`BBvM~AN5Nb-w z*%`R^Ei#3HZR@_~j0^WTc|iH81%Z+H8U~}nyV3b!lhWRxaTTe6V?gZOiWYxW{#j*A zz4c?o28)Vy zV_}{>4DIEsIY${UP|a`Cl2xh+|Bk#_RHsTT*!29VTgGu7Oq|6?J%9O#?Bm7V7N_0VmJv6{csuaX#Xc~Feb|tV z25Lu=7bj=yBmj>q6rPfd0G0{w`MKQQOj$JNOZ8jom+a5#Lqi|!?6yDSsTkjf1te`f zPsK!`T3NnlT&k zlC{%z2K3gv1ZNu&{BXYHP!Ox`43{Sgt*Og3z`W+=b}hY=96pcpLsQA|vk>0Q@-}o} zyAjN~@H((P?zXl%zQ0aWe4=!+{7wMdoM4rMUP#1}rW{P)d$!V)+bs<3 z_5F=O?OS{gy>^y1fDvh9z+a2ihhlAD!9sL5(Y=AsmikrfqUn-oS0$8aJyhF~L*w-&ctVTKCzP0n>jWh*l|n&*;Thaqk~%o!reumW<7h zTV|aIC^YqVStLxvSAU{nU#()lsAQ9Vn&yI$wtIB%%S!H1GNGqqN^HSeYpfx9a7JrJ z^nZ15*!IscoHmRWv#TfHtl64e_vu44r~TpQRKw>8YMHlR@3L-_Z)vXM-&o?Y2U9w5t~bAW1m zmJ9O-cz-eD4KO|{@m(oD%h~C|B(`DX_ zm*pV|o2Q`4?BBPFO?^%u&$**kR^F;~(Y z@-#Sk4L%BagZ=%YqM1%lOuS@zU}|uBjMhZ=RTJ(zF6^9`Dvg!ueTV5|?(h2OSL3~G z@L7B2j1gCPATr*vh?~8UNf-BmmvuGf8d$1gl2Vevl6k(f-!g(RbFTDPbxDyptC(iV zkO^S z*lGyd=`GyH2V(sGk)l1F4z>}Max{=Blo@~#XR~T~y;h8Zcrqq)ulPGM#d42*U}+@FK==d*+$O{!6^I=c6erU-t{_}=2&vHMB zG6s@n3c)3oOtDTfWF#x8u|cr9g2tY5M?#gmQH?X@@>E9Rt;lP+OaD#mUfUKWx|X2L zH5^v)9c*ogByExh#j?CR>JP=5`LS@&IunTq+2g&FA}5!d4J!sla7LC?f4$hX-Xuw# zR63Cali*O&V?6;0n!Fm(1u(Ep7L{#{so*ZSUO!r#CJdwr-XbnilEsxJjSf)((J=a5 zwUuE&^kpui_?cDqPTH}E?ngX#Qc$FP{_`TrylYrgF~QI`vC>L#20{Pw;aJL_Qa$?+ z{YM5J(NG;iyJbmIJlRk=EfkNf+fy{^$CeR+F`}t{IfI+_b75g0YL#dldo|g4^8-2J z)QnXUb#eO=U3*Q1Yu_Y&_Q{FhG&Q$Cp$%Ip>uH++*OX1AjcfK9 zkpjCJG-UN$nH*a#Ntq0`B25DBDB5{(oJOQsVNst995xnh5N{gdNilH=dK68Fsc0Nt zJhj}6P4fi8vD|re1#z}4!d6$LRZbi4s2{Lz9k=j)g*>FW%)*tvt!LIsODc?@(|nMN zTFy3ouD+Map+8Z>DbTDWGBBBxlZ=<@$@yiAPHzw1U(LW*>O!O%Qn)- z*Q5NJL_0Hd>QLj<(qTVv@&n8TSSRHqmShgRxh4YSOY=5&kzC(bSlZ9naL4k**wb5< zslWjuS}_(TOYKvy(p8&Ts6vaV63fPeSYf#a!KqZ^?+{SQlZWa0L@>gjgAinm<~^K~ z=1;0IaT((qnGm3?&_w+Y@X1xCnw$Z3M`X6=fRZdqJ3Xa%R{22)VA+hUPH>v}+Yq;w z@l4<T^yFN6l0ltFe4?862%PCWa~9yUJ#u9ZqHg zD44r|B{KP>^zhI!yK#u^ZfyA1y_C59`4K?7aRqE)aAfo63i~Yi2&y=EgYu<>!95uZ zW808}5|A#Nv9TF7bD;6uXhsvBj-$g+q^H)ssp)8@v_Om$PhmPEqzZadi!!^$3zZey z7SIbAMevsvrC)Mn`7N4Jwl|Aa>>JAq6(vA3Eflph!ou2%++x;tB?rmeNI3$)kPxim zBOZ;hb;jOWU2C%B^HXHLaem0y!v|uO+2^wZ!9*t$%I`I_zph>}KJ4rs30p%W3k`*F z#{NTmn1m9EVybIqlkr+uc$N2QAs0#6o_AMT$~HmhN}QaOxTBa91mvJ2Wb9HxY++$< zHyZ59JFOaH$_9`GZ=hy`R#r4IF-mgG=H7ap00GTq`yH2&(0Lj9=XpB+qPbL!YGJ|j z89XGr;o}(0u@_4)F#|%?E-bZzI~8v$79ru&I;j6FC(=;7>&|$z*JlX>6n~8{NVeTh zHQnUGH&8&Qn%3raBfW+sI%AivbZ4>*s@j*S#+uFD;bW`IY)+j)`{m?b#);FW=*X-u zv5~}m6f>l88%OB&5RP9Yb{IlTGK5*lrbi3wW5}1J$Bj}6CLaSq@z;v&O-UeY`P01x zuBBvXJ>m7u-T<=>m#Uqu1cpe2s*wp0Qa(wJhvj07+)cH&iZ(J9Mcj4Pm$)$ zPY^WD*C@4LVw~02aaFCs8=W6&Bln_=V{Lm9z6qbeeJfHp9SRQxeO!+UpE-?^r1kk@SV{XpiyfIX>EWM|&WATY%_ee$xuA)VJmC3I7StHxZ_rXZFrh z?V7dVspi<(ahTQpW?(a61~Z%6eXGBP`AN_5iRRexEpL2@`ICVKxr zl4F|%(Sjp8KS4{L3DAkB-a*ps?IF^uFyQH#-_b@zbN=e~C~4iyZ3uIK`1Lc4buAj} z{_soGy4ljH#+P`4A&bqzRO6dG84171Jq%v_-g^q6%yR~#ZyQTplZTPBJk$KvxbEb8 zl>4L6{muNI=JzK3PRw4$_M069(q3cyN%DKJbpr+^Czs4VB_=bW&zr~UGrkJUPH<)} zd<^gl|24@z=M(ZWa(LnZF0X{2;YaHRQ*prVP6*M?h>70~k@vm?8!}n(f~`vB10gK? z5rE^v%~^ah*V^-tk>=XFvk2z-Ub#If-@B2n-7YoeYr7uzzwGrJ@_8{a#WFM3y6$RH5uEtGxTasr?$a~<8H<{>ZuXN;rEp7`y`$I`&XI|N;x+Cf$kZS zGTeAUKQAizs1nl=n8+B`BnWh4d#wppf!?uNyliV=f(660g2&0%8H+ZD`BcpS+dap^ z+HW_;Fw{_fT&(GLa8aJ9B50Hz1>blQR*bQ%)y)JkRk(*jXr)*y$r*l`=;dOZR^Vbv z;~a&RQU!|~a+Gu*p|`H}hW#sA$?!a-r(W1@$}Q!KvhU%aO88#6+!}eEF^aky;DEMG zW3I$^L;P;}OFLUI-Fu>yv4qV8hi|jPGV`81A@MG*)2uo$-Kg724xWJY|xASUm4U-xY$Q~!o!qOWLrR-hD3f~z1ki)TVk9C*gWoU zSI&Yy+XIrfGOk!ZV3Vn<>e&i;s-XVYx69nM-}YpnU8R;oO@wsqKI|j=ye+iD%fe1F zDGS&2#BHrw`w7n5uIR(|h(G2hdWgiRnks=f&+x6!4k+dg8*i1G74(+AH{PQ$iQfNp z!jZn8%}eUM=oK;=zBQB@A0lq!hxk2Wqcdvhrl-u_5&O_6|LoZQR%O48(q~#DGYR$H zJPqODW*voF&KF+Z8WFA#C(AK(y)_HzzaqrUd0P}*-3(z2{R)xGit&~s;#|!M!6kpX z7I;6z$3#X_3H4BYgWLpwLuCoyONvtDU-9J-mw;WT{}m?|PaX;u?`jJ6v}T5TTGz+x z3Mx0YLd*)k{EhG*scfs@t-5-Qq;>6HV~wdVI=+YORUTf#4&>h7){O+~^UL&zBl~3B zOKR|p*(3K-L48;2HMmf@hs{bh$tN{t#u$)iCh>q125)=>c;zLT#kWx0^;U7_m9v9F z%n<7sts&_TP06*>Yq~AreHxyhRwB83_-~ZFfuvJz;LFNFPIr1aRW5~?oBg7mCW|j) zbEe& zf(n?vr3?mYjlPiy$@CGa)NlpkMRY@^?1@Yql?NRW(jw8o$``AZ1es**yi9f9^gDCN zq)Z#6ifG8>x3~aR_Jk#{_5Y@GizSzuZej3eA1x6LzrVb|ya_r0I2q#$@;T9#@o)P$_o2_lYB|Q?Y z;O{pri@3G+;kSN{wt2Gg==bXtzPIYF4YNW9xY|?m!zDUJ7v=BZ);hk&;O}5OYM1SbY zxpRB`9ZIvJCbcngbGkvvro>fmI0Krm*j*5$5HxrDPTdp`{+G?CmtXziDbfKpA~(Q4 zz^`g}07w|LjYz+Bo+$V|ps7!H&JLaHc|R&J(R+pP6sMX>vxJ`C8{3r?=Kk!6&JL*f zR9wY}ElwIAqro5{MK`gL)uNE1h2vxE{g|&8=Eqt!${t5~6LgOO*uYP6deQxrvVWfj zr>D1EA}+)Z!H#Q%si7ys0Hv&nih5cQ_Ea!Yf|*(q(I;V0?U80Wd#%Jr18 zHT)WBZ}_$5G~e68za}lOXl8nYam9oQCbssFS2b=8pVR%ubM1k~bIeL@rHtk$Tl9LZ zU9-0Nm~FN(s|AxjX4dEJ&8v>@cw3QNdnn^-zOUnZ`|)}({)q1SuWRU~LJ=#^_Om|Tad6IgyR z3R| zpAb_dNVn=t3E{s|3m+qC6*2guVaXrM-4{OJ->{o6@Ku0yE;>RdA(Jt*WY-) z@aFS{H-_Kf-t2XLVl<7KRGG$RUi*RXKz1y!)7{5(&(3}gwbnL=cj@ZYN_X7kt?+Q$LJP2rux~B?48m1{l{&5;EH;9NVC-QeHu^pKi)(fV$D?V|wOcDR%}EgUZfOe6BR6qqVy; zo@JgIyz|a*oY8sGl%d+aI1}aT(&uoS8enQYr>OQrOjYAan!}lsRj{L28>&F=R9P1~ zKSJ;nix;cxl#@DZmMRyCdGmwGUPacH%Iql5*(0TJPF|VFP4HU^wUgX2 zUC{{szgtSzYK_9pK*-T7OTO%oc3J30paDprdwDs`b@~nLbu1KBlNhIa)~F6*jPLivVX2fC5-6 zH2PlKLj<+LS=nZxP^`Tn+)Si3nWM2|(>=@U^bmJN=~Vdi{XFJM&`VN2?#FU?wGkS8u0uyJuYczYEGnW@_@4CQ{qp6Ii@$G>)Q|HvE z+KkN6-$C39N+8sOi<;Eby!jiGm~O$^*ktx5yD+Kby1_*u{EDU;__@S{s>;0|(^T@^ zQ%g6Qh=0YId82({e9VQTlOjmt_ZeSIJit!X+HM~3X8WBtXt>va@+xX_o?rg0tYWkm zZQIVTs_8;mozabrx>XII=FxDaTB?*WmIVJe^{!(c=DOc)ZHZR-#&>goDiTH?1JngB zoWo^?$q?m6sMcic!rCl`bFA2s-J8=|jjp%{Q3b2rozWO^T~g>j44h+gn7P#AFgmvCj^z$-ZgQN_ zFT8FsvOwssQpIdv#!6<98-6IfM_13P%lnlni<_JjbTGqdVe{BV8s$^Gc37h_#;e+& z6sJul+%k}2Jf@=Y@FGmS9Z9l`;E>j94uuPS$3xSQW^D{2XwQpTXIAjdBExgjlXTgD zLa4pmxaLU+^m=&jJXQDX}mmsmcPigLip1q_!ng}~`?BK%G)GhF>+7k}a z$-)YDO&NuCq((v$zS+H0Xz-Wx)9{N?L(*G+QtiT%TTg4(3$!cIS%#SiaxgjvVjaSD?{b)m*FM_Gc zmm#P&m!BoFI;2?f;+P1mq2cGm@bVxm3;Pw4W16)Z-x(bi56a~2#tAFU>LBebGE%iZVS->r#U<^gS6@F1cwiHU<%Nki4 z;F;9MRVJnLJ(~TFRKYzA7ZDhi#w@?(L1}tCn4m-jp4a_8?raVwxif*Xw?f`?m)0rV zyyAgOn%eUgXufUX6HM?T0`s1`W4~2!upy)5vk%rIYO{%A2?SOqo`b1qEuD#+yP;8P z^dIEGqf*;BvIJK;r}`Yr7F;h&grq4-<3~<*Mp9^T9~2%GK+0fhMRR(wU}N zqn$+`c>`B#MG+eBRQ}&2fKHt7@}$7KjBS%v_2ax z5~FQ;!b#YS&@Kco*0wVY6S@fNP50Pp&J}~+N6J|J;l-0pWe2hw01)=*r= zbj(#YOo70uqTAW&djrX!Ud~%E4l@G%nhW&zxs+A_?Cb-f$JXuhsAXa$JHKnTeiW*k zQD4JhB5Ix@-XB>yWBQYE$20CG=M0}7bgBNX)IDTZv3@M{mwzxLuRftx7)Cd|W%TVw zX-`agJguQk$9DrErgwf*xO$R{{tCxhhz-darf}aefy|))Vrx?juH8kglrMgQO9-a9 zU;yFXGbxe}L}b_5;yJFIv@f}1v)joUzDr5Eu^C1*WcX(k`#WlwB$=GL*+N>|lZO0I z4%!~PY@1>SZ4JBtWnHs12x)Hymk2`5Sz86u{t}#R1fPksw%+~W4cafSS7Na6-!<%g zsoS>je`xH}e%dV9+(e?_oqE;!oOWEy!{1lOC)9D~1Jcj-Ph(kd-P)WCL(W^<$5q)S z!r+(&G}2g`P`l6=LeL2(`Y8WQ(8)5g#X+Cp6w9p--j5_Qg|lrmBBrx&`w^W=uv=QG zHo?Q#U6PyQLnNS;81!htOPuY;5y$h&0^?=i14qky!nZ1UjHGpI+(ED)p5ZyaatM}X z2-3s^4IyDnBDCzb1!o>&0ef2!YZ{GTP?5t7GSVF55hP<|vjRmE9^E+p+T{O>#$TW; z>6_$datI2$04W;c7@UXJ%9&ZnNzrcNt=u_{+SBDBFwxoMT+dN-3~V{TQPq@(-{H~5 zw){5tK0{l=-z7(DYdkD-V)p2zka0mz zzpTW_L8AmUPi~TE)S(fEmnHK=1^fyPZ@iSZjLhpJmZ^oP>(7L!D{h7>*_$WIrZ$b0 zc9e{c2!BIk@>+_ReSLUL_3zS+!%FM`zJsey1^rF9Lg94(^i9l*JLO}`IP_C+a zV);-gkO{TXb_R^EjFLhl)MSRjz_u_$34%KVavUXJvyD(fLsyD|Z0#{2L#OItRIC#D z><(qk8cM_%Zc;L)M7Ry5PV-hSH-F(~-PIn{={tI2^$^+);TGKz5V>Sp%Q3X!6{DM; zp|TY`At}N#sF~aRB;zq(4X-m+hw_H;G3tV$eE@K*Z8C$MY zWyzWC?V0|%`|I!V`@U{;#>dMUeC9s?FaM!8GnxP3kHOCre!PM!_|nN_R7P3N%!2v0 z7A*N~FJ$p;H=R~)A!qSfwwZ6`7YZmlD%UKwN(&_^=TR;%l%-rid2C@!%0-kb3l%As zP##|xmvR~9iG>L%k2UwSCKo29TxsrYO)X4W89%$WPhXT#+_$jb-@kJ}jbFDG?)S4h z2h{{hhorOzrNemlh?>Oxfo1zpX5lDG2i0EOAM}saT5jREvedCpE%k_hLLJ9D zkNPLjV!t|pHy%|dujLm`qV}LV<(H+uQ}{Klrv0O!SYCG2W9sp1&Q)vSvA8~=FoWO6 z{8ONH8l?wJ|NhYx%ReRk7gcqzWyw+()HKHO+uNN%yIj&E+FitG(q2JfcYngG<)V5b zX;-q)>V0YTVA9e*Dja3+kK&S%4~_jnzl{1LG6SwbIi3f3$*ZWIBz@t-LG_eh5pF$> zHVL;X;MUXX8Q~WDVSPGol#cn25A|sJdOW87>|o1X+`3!4ub~~eB|Y8)w<>XeUr*W% zaq9%u-CE9KoPAEA_n~n==vOeCKBp?anM0pb&yn`RjM~Td`ZBJb_a`8E79?+0y#P5r zjn#Y+viTBZv)^B7SAR!*NVWe^Jnom(Hz2dskuAsX+VT~37A?<6Z?9rxiOlw?=hd8g z4dZ&^uJ63A&f%RWWsNM1!%}a2npNKfMWb7s&70}3x6;zvX=!xt6Y5*)ooj`Kr|#PO zym}YCKdr0_nduLHMawvU!-^)l>&grL+J^Sl*L^*0MTHeV4E+zoUs-qszl&$}O1I^= zLq419v|3(UnPQu-p_qF^ce?8+vrSqQlT7Ky38&bnuoY!o6OHKd#p@BJ{!Yd`Gj_RYzGCg=I2&PgO68wJ?@OcvMY2XRy7k2A}bDyZVM$`vcjY+2ix zt2X#E*8AZ*p1u^go?FKdmc05U*9+VYuN^kpD{k0vwO{uemwh)}_1$=CZalTJi%(~1 z&98@SwA|1E3NaI_@-%YrJGhxYU*&g{zqBF0i|4DRqz_cO*5oZ0Y~f=1|{sb2Qmm(MgCOJ~+M!_`jv>FSeDoZ*wx>)?U6;s*zACn!OPX;)%hEFGq}TeT}G%M zU@4utCLPRxqt?fGb9v+B^~1PDmB9`;#el0jkt=8Q2^4Og9FT@x0u)xywl@>;xucM1 z@)*MKuNNAvM$^+=_*qVKc5$%l#Tj?08@io#bJJzL2t_Oaoi=~TqQ~Na_psV3a8J#8 zVW?*pV_~kM#o~0;buX?q0vG?gfxp~sx{YN}@IYQ9N+@Z6UHbvF$#fNj&9#eUz-R^*FwwEXJlEM9D0U%Mw>eR&53a5sAZA z@3629Z;ucM{Rmrd&Gm8KT;BSNT}+xjih8rqc`WoP{5ltn8Rpc&&2>M@`|Y5s{hN>6 zdHFAC9jGX-+=PBU9X)eI(x=CVcF{1 z$8ykgq&i|2aHG*|x*HvRN!BnJEmD}sqDWJtjV1IHmz6UYvjbaWCd%4Wtc+nztj~i+U{kN6B+-KUU<>^@&2I=tgib%kqku~)$ z+AKrzjRiVY4?mo7AEQ0R*JH+>?xMtYn6LYiiFK0)%=komj!l+TB zd5P1!hyq>a6?;3Q$F}SpYumnVUCFj{DBGsIg($F_(MQ9q!qYY9XST9G%U-oUvbOBC z+_trqU9opN-0AFm@5Oh#HasMBt^<{$eDuM?Mg!gyJ_2~cK$nE;Tt1qPUfK0OYy^ZC z)#>tTqxaVB{Ip|cHY{f{N6cJ0lWv~@VKeimSrRO< zZ$uwYC8L-;u}_I@ z5;~f7-$rkZw!4@jAR)d;I=30IU0k1aU+XVH>yp z(Xd${AB3992g1uBx?jT2w#j~qc-OIiXFkMe6U(L?C&sCq0 zrbaS}UG8E5^LV@uSHSlW9@;9)#8Zf*ObkTwsvx0?m4+(CJKMrKsHC4EGe|WsW)LRL z+O`g5u0U4SU=&9gH-q)E#wa;lB>e;k=qGUl1Qgr;bym2%rPd_CuYgm^TV)I2?fs}!w&tzkgKIp;WdZrb4rEET!6PjLDml(emN=k z7c?r=P2|7LRs_wCtS+3y>8fPd0~TZY`R!~ufFP{yvzJ2(S`WR#UEfi=s2zf zMwi5rR0mM3IAtWJml_(&TpEt}E~Pm!_wiGr|I}c!)!;jc_d!GyuF8y%T!Mv0@&a>5 z9NqNl@Ci$suJVFaKfpZSTy{4*UCH&(1t3MzUSVM4A>G6Wb+0XisEXq6;81)JRi@*S zt}&j$S+EBt2QeVvbv$`+1W0+gqnQ*i;E|J%VKz7E$&z`>5*j>xu7g|z-dbD~rUi>w z(3l=jeH*heHVgF33(^TQd@|6mBQqccR3!Xt0)EB=eYag7@Z-`|%1I{L5XsStdbi6J z!&VQi;|^di!7mqKg~6qmH$^g;QnS& zEW_fsMjv`#A8M6G{JWa1>(1qdf_NorS2ezv(N5}LP|nbf7jf;w75qDHNDF5|>#D6w zp{*=qwRf_>W|`~u72q%gi?s_b=A$>mT6#@tuk5nVmhviPsU9ZrLjTX?8oqJn$8V^tPNDF8YP}-m_QGHnQTMA+-WZX{S@oOikyX2Cod#4POo)n!htO~0r#Ro~$*9~w z!pax|UEpgaf)Nv|X4gCG(PXVAaRq`&82tc&>jZ|T8_1)^ujLVKKu)5f_6ezd6=kuF zpkE+0D~!f3e((J2wYhJ;KKJ&U^KY18P)PI{zL0BnHhdiwVgo;&lf{n4U|e+ErHnV4 zO!XzM2A*lD8(9NO<~XH38WLtAaS$zU5>mtO@+e+ZEQ> z_aS~p1pOP^$$wGIJ4k`Xyd8mmrwjVK?C}HKBB$;JVdRi+`X$y1A1gKFt>+Sj$nC;W zkwcRn0Uc!xG zB&T0N{Vv26I1li8$SNT}sHUyQjs35@+&~PN|B7q{wog*c-3K0O|0cCg2^W{21%4ILVf5XR!Fr5^yigF)G{8ptqF zaansI6Xv1L$Ub9RM{1$Mjz>O>hIYm+ik)}8K_CZ1ZL~Y~Jz|!bhYs8h9D&|w!0ZwW z1O!*`&oMlU1$EI~>mqe5u@B!`gi&4;8lt=04L{l9cqoP@wUiYowpKiqElyC8WkTIVK^cW&WeN&$z?!n7oXl=WMi|~u z;@E32i(Bd%#$jmfo$QvFbjDL5OfQ^;9qeC$(XY`dosGL$d_e+_ z7+DLMWCXj>HO!;ndF7t+Kdk%fAs{s685?iXF4=qYf7ESU_L@LS;wYInBNWHnZtFZo zcL2=T8Sg^XHq8hCtg(LJ2^(ThCgw%D=_i3$Rc0A1V)rBk-wC*n;cChx19)Z-wJbyB zK<@UTBsu%!$@wItT4aO)6-(2W(0y(!B@tH)1$QIagpHtH4o8x|@eh3-%T@!Zj%NI-ZJ{nst{|^MO_UwYA$-wbt;-wLS)BKGL0nQZ2jHZ8N0L<- z1sQD3L1-RsLwbppNejW(5?Y3Ii$6&}DkjwC*hvvp#VH2}0GXq8{J5i4&}(=KUH`={ zUGGR_pGfx~NYl-^lK&GukGuYZYkAB^32H{@cruKyTEhps{XO(M9^R1t{eRJJeF>6p zvX@PkB=;-|T( z0z;^~@8SwLDg|g6`)Ql8AdVd}N9f?tLMFiO&=o*QM6D%NzD}#eGPXa{as|gtlllp@ zCoNB^y(|;X^iLN}PkE;?zOxF}8piVU=}jLV)Qv@HW3_=yV6fWRV5SFgH{wkscHn;q z1bBd|D<07pZ*CSdlg1nZGH*l+aT5axnITfxBQy0Y+y|E&BsNQvWYs8V@-Fg9@DMF_ z8jp)P9pv{0w|7XDCo7sJT}4L%r{86|wtd9FIrwL}=*FOxkmpWzxGR!Q* zFEa|8T{Qj11T@1%P5c(+qz~B!ny+V3lYCev#=L+l;7-Ao9Tc}RJDKYUc8Ds|Og+!Z zc}qA-0Z)<=)&ZIrd2(42!F&g$YgjDVh;bN_-s+veGGObD+1pOLW`^09)g)S&wt6{X zLR4r3wdJO_a#537RPjFqg!5}MjdMs2$P)JszSbE|oSL=vzoFkktKJFhm$6e>O0UkY z`#CA0fQ6_cQm0t!F?QrE;m}A_Mr08~AyEcQSv(wdLI$*J%F(_N)8p=EKqq;)N>9U!!;ln7Ud$&hYC4J=TmKbdRmpo#45I6ijbh(7ZR7X za-&K_dlI^_=>L?m!EH3Bm`Dbs;!jX9o#h!rIrk{%E20v5T`|Q1tVw|59#J9Q@zsBd z7W&V4`v|u*PeHAw&8J*5yb5mOh9n*RotNzTAwgM=v=b(^HP&DHKe|iS9v5G z3x^oi6~lrmg+)~kOKJ?KtBYoP>EkTUqr)K}z(e9N_^z5jA~Cm9R(sT>NIuJZ)l^#E zH&A~cX0#uvO=?JKE2j=1l{vQMKqGSIXzKL+-oF8|_MJz}zTFDZXtjLBj5!ZgVrM=+ z>lnW+3eoQJAd+YV-GSMS;R?Y^#3B!uvbfmq0X{_>j!6c?ugviajW1Ij?uB`od!O%; z30x83ApvO4InzHPguR4AA;x=3e4LyVW9EN=WyxG)p3Jz|B?KE~yzn&u1+-Ix`!f78qA;C~TgJM3X@`9JS8fjDk?yvJgG*zk z6xSG*^hJ+cN@mORlbmBZpAmDtmpLY8%XB=r26NwflWRz3BF2#=iY;5h+q7?}7WYt~ zHpvlFh@sIJETJ6reb6Q`)c(?FE{!#h%IL_{8l z&a*P+6DtA7kiER@;h;A50fvBHIs@Rkg#1j(;{htW*X(!4d$ZbOT6OT0-t3Sms&~3g zY#9Uo4lps6|IztUbC8HaP2)*U@3tyXqd1|%UEt&$%(&0GlobXq5GlmVarf=Oe&^h7 zn{9Q}Y~NO;_Ha?c+Hm<&5yV>M)IjT5LvR#gLbWOk!>*^VS)NIt}&L=O9K1;4;;%ht>$BW28J zU>nL7%t;5w!PbhKubX$n(zb;ohS|@6SXAaCdxNNjy}t+i;K;L_ zIVT&Iw=ps#!?N6rJOKQ>Hl_+cAtuP|RFY^08=`vwq;hDJ} z#JndH7Se{DOvJ6)J3g1{6D^W%@npe}CB?e-_6#3esRH0Rv^G&8CabT4#WxUL)jQ3O zo*s|(LVj^P0aC{_JBJXJe1fCDUsjx6Vk_?!ES656 zj;*o2jJ_`F4cyN~MFfvNaI!XG;Nc5&G=mF6LnYC?jCH!Axp9V=)4-6Z6909TAdo1( zTq6*|8q`*roh6(^((m*25*8m&TrmkYBewVy4eGek z4>kVxPUonKpl+si#s|_o6QQH_#E2YwjA{~y92R6CM&0ZE4AbZ%a_;iqBOK?e(9IQt za+9STg~XGcm2Mz=Bsf^p#-Gq3gwpsstoYCrb4kOU!#Q|7NeiqX=Gx~evlw6u>oN#7 zK@L6<4QiwkFVRcqASFKL(=bQcjAb82nqN5vWdC0snAolP^b)tHj_4{b;1YQpb`wlW zFrb7XMxYrRVkb4k*o^#hG(_^{FYzUoCn_SG5jKhq(m&;cE^lsnqe6(197Dz=p#0Ln zOd+?@J36ocBU4Lxv(kg6LjNu4NwVljY$dS#30O>It7^U+=2p(??k5TITi?$cvq96=IddY~uFhj0cYgXA{dcI2av@Gm z;Ey@+1vg<%ag^kY8UOaloMGk~83X6=2%_1%;mHm&of1n-7MKKBA+d4esETqtC>I#N z@Eum{H9ghjqzn(82az56@!#HFKoF;yZ-@#!(eZ(&%~9&TtSTl)NTMvxlW0%KzuyK4 zlbJq&3i;DIy~vUn(r5Wn7MpKT@m<;T@tShhSWc%z#SRQ(v*Rf_ylZyf72B@z#+@az zE=;ybZbgisCaVXQ$>mR3tKy4*nBAuTvW2SP2e=nAMV_`1wN3u5ZGreBqRA8?KMF zsBs+oi-}z2*G`$W2}PdsnXoHg+6A2K`4aXXzYK+APWg+8_r5yXaLhxrkL|a|%uM*i uj03YfdVAgR2aX@Kr^Kbhx#xc^W5*~tt0HDq%-O%j{BKSa%Kv@pNB;vXNe@c^ literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29a47db68ad0ab45d9da2c70fcc51d25b1869348 GIT binary patch literal 10257 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3f44ac9994273a6e7d165477223c54fa52f357fa GIT binary patch literal 2434 zcmZ`*UymC#5MS?Za=F}}_O30xYYP~Oe?e_hKowGi5a`sx2?$kt5^4}ioVAnPtFvC& z-sEz+BGmSk@6bM$Przr{SDyOBL*FW-GUH9)t~xBO*Y?bgfAjOqc-7ik-GjFC;xF-R z$@Bii$?*nj-k0#0KcM3tC(`Q@c>B^H2i<^pg6xO-qLWm*RUYtAE{$v58c2diUUwPf zb$*d=@j735TzN#gD{f_*SH&u?!FY`?Z+pX#uPx-D{km)&W!)8iiJ#>gkHhXdzsxuJ zIT)ScSNM6fB38G((jJb$-Ua>!d~=qQyI$kX=YZbpG)PgADq`|Efho+Ec2sJ`fxT5! zO(I2VUv5~@{4TLVGx^gkCXM*HsA^$zo$3(2iSWZk!!bTP@Vr1N_wIVnNaq=Jx&m{J z+`8`N_pMlsMawV~#jF*X8`oP?F)*-Gt2q(rq$QI4iO1vWZG*Vw|B&Cu61)IYZRLT+*S^ zG!`-w+E9~6F*-6gEuvWU=`>DYb)1Z13(h(t2}G_I#)8{PN+GJ!QId{mVhw1-Y?6S@ z0Yg?`;}a~F3^eP`%$}lIZsOB4uG02c*tp%FXGzmUDii(VjL(fUn{)!$!9~Wo;O#cO z(Y#*TZ)Z%iF)h=pO_L!t!XkbBJ)MIwL{=skoiLdL<%aex}-*kE|;h(>PcKFU7 zh6h3eKn%_jBH&~&b{b0su|*g$V~c9fRhgnl8RWJ!U(|O~E)LvQ#p>~m z8@?+W1reuZ;|0vOP3ZhH=gB4sNuAVRg+c9C|L-D*?7@j7#kzzg$tCF)46L_Lp7@-M zAU&T1N8VFHpo&9n3=TiK4FMo9=2J0U@V$ueMeaFQn))1=>NG-)IEq@Y$CJqRdPN-$ zbxwUzWmzUt-XI$Hea(|%6{BsDE7w55U_IIL^%ZzU@SJEUb1q;NDqVOAHP;n&|M0y# zVyq^B9D~TJj7l*PkWHA=xKv{9Gy(_LVK0JAWydhN`iBLtSOLKT*C(*xaIO3LEfiKF zC6zwGFhUF9aqvEb!4bg9iLM?&@w31!4}K#Lpwzk5%_Fi8H<1G#9{#?I$(u4c&w3;q zD!K!`h~P3C)X*)u?dedm5!963;XIQ6O&F{{SO@F}W}ZwigQ9~)LGY_o0ULUXDd1G3 zQuk3Ib5yxtN4geAy(q9w(Am>?JwRyUjiBEy$M`z+crQRnQgR}INg%8@cjhxtH^_3W z0%7ad{3?MXmmZ{{WALae literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b1576706943d0001bc00f5bd9c15d4e55e4d892 GIT binary patch literal 13675 zcmc&)OK@A)dA@I4fFMOtZ$*-?Wm^(r36dS>r6{&!`4J^Ctwf3)Ggd$l=Yj+T0@S$| zq{x67$5O^lT1}g2S9LO>rtQMZZadv{rd@W~E^c@2OlRCpXPRlJQDUp#_a8h+icYgD zrF(GhdEN8)|L=dD&iHu2!r$dz{YU(RuUpo?@@4a15ib|O8ey9YEcaQg;yj9#@CtD@W1qu=)(@o>G{D^fP06>Zm$~@)NIG>M<4FwN!M+ znc0iC$JKGX9mm^lygi|w#M_g2JBhca)Cs(uz}qS1T(e3it6y;~t8jgxkwl9f)osO5 zl2&yZtEkgWqiPbhs(L&GOma0h_M|IsSI0@Di&%*C~87ek>@V{xe!FUIYZ zV=YFFc67PbsNIY@ZA@sPF~1P&s1+~At>{#}qYI5TX5X&GQM$SmM+?<9X4jrS9WBJI zr3eict7(dY2o>nx!siz|Ixdw9*nv1&YE|12HX`lxCo8qmn9aGB#dL0ch@BXgxi(Kw-pSEpbf#2oMV4e6t70+Od8a59Lf3|#Ert&%d z&hd130I}8`9WBO5Qk{>J!hGD0b(P1*4-P+u?rdyME5hC;(R`ey@$Hnmf{8`*osPn) zxr_q4E@E%f$ecr$i%Pn2g4LSsml1H@X%cnnqtC491_o_MbF0y-I-c+7)#z$Ddb6s{ zbQY_Pc8Vuf1+?IVuCAsF*tct)db+|TztZWpRW)sN+T}=S61&oBEH=0xoJy^uKoV^b zAt+6kmsU9;P^Fg1K6~!mGiQ)|Vf)9+(WO=^l13y$bOjxjxAuJ2^!!~D+HsJNh;q{< zJM&e1s~aPe>+dYGVY{FI2&iYFVDiPPx}@j3r0DPP#85VYve%cm=0Qnux^t~tTQG%a zQILw4dD0woFaYwo%bhk)5!qnaJb$&StBY|O>&$*5^T5AJR%r95k}SowEYLAHvR!jH z_5PoaUp_9LHuA`}0!n>2JMfy=T`Q6{`H*F!g)x z9s4BuggB4)9A58Lx< zV;OW#xWG17=K!1F18lLJEC7J`vb9nUAmRZu>W!MvcyhWB;jfW`D0w0Tjx4l%Y-6Tto#y8AgZ|EciL#X(+j3l2WsmEkB0lHBa;tL=ku65cVerbOl1v|`3 zFpyQ<#W~>ImX!%cB@3NyOGR@rII^8!%}Ry?lFXiYW|o|aIdPEyVuNYmfnItY33r66|Qja`<$t#FfKUJOR&@rtq0#cyU`FX`O^DByK|RZ7Avw=32?Bnu{LHzttU1G@CX%16QO=zmB3%|#>Tz0Ic##X3 zK;qb;U9byI(GG0q;o6akA(IOEynLb6sa0Fa^JUXXleM?(2YKJaBm1!znR%@KMzC%h z4*i*P3$(5eqC%3AlR4#cnO!M4`Y;Q34Qliu(&a~v46-;s{M=xi-d@{3do8`KjR(Swz%qokU zm-7sYlP@3%i=pk|-x0^lhj!@TV4O)D&Otl$LVMCd8UHy2+xz$Ma1kvdl6O|uQLASIVUJ5&^KJp9E!IdoTUrj^OWw3l zL}q=&-K899B-Iw!9mji`^YR5*M(1zVpHG%rjkJO}FLHX+>5He)fZD5u6?GLP9kRC~` zAjQ3D=Vsilw5iXv8f$T--fh?9>m^s_ugT$Au%zR9!-z-ziWA5&)VUr$_x< z(C|EW;QVZ|(28%D<&rOd9yshj7|M+O58>hlYR%&^vqS>~zZ@$D*S8J%2Qr4)#dmt-nz{JlZt@zc@q zLG_K_XRyW9w?BQH}r?b^t>~$O$hjKA7-4$9bS%K!X~dEq}z;i+GYXB(XIE zE}e1mb{>z~OA1$h>^8mFhjkht7f3EQ%!P4I<>k$7hCrX9DyXr${!BhDsA4<@J#So1 z+=UJ|Q&hXqE>x3hw<;~0N zjL@&~L|47Ajb$9@r(JNrUo!lG4bX$i^yAy|e&0EP_g_)1D`oCz+eX5U>U=<3x~De+65W zxmBg~Q^*OKYVM(ai3xXGzs%$!l2QRmPu!}@i++*CJ2j8Rko*hZVamQQmkWLt1WzRwj- zGsL&7W}YJnr52`TN3$`Zy^64J>^WBH0@gta1o1%~ehL24j;bewM4kdb712Y0e+FUzEH|mig91-- zNLi8SeyMM)8t@>*)W{iwKjw!#ydN(;=)o0eN=TuDA$3T5MoV-@gUA;?^b8qXM88c{ zqaBsa8*UEormM@Tn?m^Bv72NxGA9J^J-8-B zC|TlSc>$$4h*S%1lNa!v5Tm@nQ3Ocx>~{g1)+}s5*=~w(5@yXCI^Lq}a-#`N2_Nbb zKf)SrU%uaK(O-C%>642mM|BIjD zK84m1TNeMwF786@MK=3BEV|Jy&baDn<;GsqS03=vNASq&qiX=QJIp)kv_Vm{$;D8r zp-7{(}&i8v31n&n=z&>v@l$~91WEFY>f7-MQvPqyc`LJ3RxP{;S7=eUf@F(&Zr zibIY@93Ry2SM3M3i}P0@F^6*LaaCN!An=K$cO`f zsR`}0(1^Y=_+B|J8A&yCTw`yz188|OF4m8VnQ)D)43_|c$XmF zfltXWjNRd*I_fKT3FC9H^rOBl4hPfu{t3W&YywH=Wr^o!e<*I#@?{einT=K?nkI2M zbLcV<2OIqLz0va>@uc(}%Hlv0FP1SSh*g6>=J^PAeH|IWD;N`0L+F~TK!S@5-Ur8! zl;T&)1?5~xJsQ&sEcFHH0+Gc2^z~OB*k>L%XU+hS#EW$RYwWDRFrv2rY9S6?e7xEI zhWKmXlN5!SmK^Y(hTYK0%ko1bFB@lr%D~3Ud>Lebp8V1#Y#ZuAV}Pn;FDe5!@B=>- zXC@6Vc%JRGeXq+WubODw(D?fl%mtC9k2AM3jSw=G@@Dh7bKd|cV{u?7$Gi+&@5^iZ3*HG2@04&CTg@1 z_|@oss@rZgZuVn20~RWYkBl*Iuxf`~3~dOW{s!20I1*HV<%U9tGKwx4E2swFAKF&i ztBl6X&Wcqv3m;!UYpf|049A$AHFlP1wAtpGoh5J0&WhzVixA4N4_7t|U&}1wzVf|3 z@I{zRJ8jers~I}OIt6RQ&_awhF%Uqm5}wCyn4lJRVi@W+ENFO)Eg#W1NjiH-0+g;2 zk_gu&1j&QG<7^5`fO6@m6&^ueG*0m^TxID_Kbo=`A!1_eP&@HYuFL zPzJooFLAV?vtzmxishu~VatN<5@OY{{s!B8jmZy~Tw&5fQp#^KIX;aGvcT-8@mtHh zWd&rxtT3A26I{b23a57O75lUZ4uo6e;o5;uS&^=z^&Y$ZGj1xVnLSjR9<@LhbgA47N6;0fFShS5uc93s@r zy=k@gAP(TJ;)wYVhl02@Vj~fAO+R`3UBm<0_6kk601qP4&9F{2+o{fA%7VY6`0A!} zG78EdxI8<1${0tdd63CzzyO>irPW^}*9X1^@y#aDW?fgJiA=4MxVs_eV%b+=7Axg@Mze*PKce?(`sB z5nb65aW^d&skSjvz{@$J4UGm{LHL*`x`>NN8et<`a@pFtzp@cNO@oE0-Dig&IK@dM zQnP}68j9Qfk5+MaH6@yn;JXo2X|x)E&`#m3SKc@$~1&&6CVJ(PfyMoIiNFC8=-04R^-o@9rs|jsT0eRoV z&^E)nZBTasO}6o@CZv<@1=6RiwJ&aA)t!%HM|ck;2&?5B5`Kt)k>z6qLSZw2t!YNX zmK6i@+pP1kr8rw26ufo{K^eSnpWlyB`(4g&0vU&K;D=M*6#UgtnV$GP=DOvaXjAeL z%zhUcoRCHD4w0MJTc8*LNW^!9%Q^7)?BTxmu>1YcFwSh*(kJ0Za^ZhE3E=T?W^!Kb zJvdPxS99!UumM;RN3eusH$v#M4$o9Z!`BkA#pO&9KF0DaeVYl12y7zzw~qx+F%bbd zK0J#Kq6~VK6|&h8a#?`Odhl`%yeZsY{RdKkJw?oZ`?lUi9cf8)g8+07CyMLAKRW@t ze!`wWNMPbuYbXAX4aQ7}X(r4)F;KpYLw}2~B!Ukap?HTHb2Khfotw`4{@`N++c%oAR+n%J@>x5o`b{B zw7QIYOt_t-5G!kr!JzQ(K>>OfhQ)fW7i<)JIkfK|58^^{AP7M2h6}vHux(s{@mgDm z6U58MA;MwI0fW*8+*DNd2m3Vgq75uLai;;AMO2g#4Y`TtrE$?{vK;Ru;@XP-V-#v` zk&I?s)ItLHP?qhha2hf~g~}h|xMU~l9^z`#ZRUi#Lc?96y8RJLg$`u+pYin_CgN$^ zCb@T+1r80I_edIajuqS@VnlG?!%PYN3EsfKos3EP+x$sq?Z{RFkzE=NA_Ta_lgpb7 zL!F7vBn2<6!qMYM-~(BQ^@ii6A6Kqd02{xJFrwA-ad`oO!(YI{qvpEKkcorve+Z66 zkWV>Zv@k|K`4Y(m92fveO}KC}MSzjLc%1-5lyBzr8$B-tk-#sE&4BpNZxnFNz{WW8 zRUrf)-eU`%-LQuXa3G~Z8*^GO^ztAUTykTZo~!2&>alN4%2!uogy|_()c+bNDM<_!OMNg$7VsR@5alAAj>frXH3;mA=@51>{@_^$N zp#K{CD@5f%jHdU?AebP{-*NQIu$C?5$vq*fS%5Hj8Q%*eR_!6*{|ZOg7*n`^Lcxx& z7G+EzoVgc?Qhr0;zX}4Un|FHcDYF|R9MOnx!5>AfacD1;2WHm}%?5sZfWEmrS=LSL z%O+wQH>$vhcrKzo+g+)*s`C{wr47^=e4(%ue93U7dT<}ycyK9{w8*F@kb{FoDD4B5 zzQaVIM~pp^QIAA%1+{rR_oHmRm@#_N@;{n4#j}L)x834*;A2khi2g zz$2GD|1N1a+<=rKSeP2zSn{SH*k3iLSH}EsHNcnqDVspzPf>1AK~99i)xgD2IT$Ei zLln@I4Ouw2vXIFot`Tf+l@0n2(fC&bc>orN_T}NCq~nv#r*e$K1ds_+j`N>uhqs=< zK+gvkClX22Z*zLLkdzK>3lU_wN=0>QmCB}|%{Rrl!W6C%4z{Kjxfb+2HZe^6&}G8I(%;&+(H5 z@Zi$Qp)}6MY8^Pk#f_E7Wlrs)*r);I)vOTTuEl+=jO1`sBHZDTUTGMT>je2 zm%njk`qgZ=8NAYWQPbn;;DUu$gFSBS{5l7r+%~?NOU#Wkxq~Fj@n+~729 n{0E}szd&whnLN}M-*I^ce9mEak6bvCKbV_1KJkT#Xe#_)+n*vh literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..031f23e9df82a3f7e6995c6bac4567427a37f765 GIT binary patch literal 16850 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18be9094cf12587c266a5d2009f81738db19eea3 GIT binary patch literal 15208 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 UIhD62kCJC`IarCY>8Zv40R(8USO5S3 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e007f6f1c0c1502029a485637c575b5e71f9ae7 GIT binary patch literal 33692 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..162001483e5673b4c1b43a8a65c1cc324c72a6ce GIT binary patch literal 18848 zcmc(HTW}m#dfs$T&lLj@yofhZRO?EP1P(~u7ul6XLZn2A0%4I7B}nw3F{c3xIGDzs zZV<#|pva)+Q7VBhNh1KF*QSuJ*rMVLFIhAjfS4ZYXBws+j zGFOp&5&6-%QOTE(ADbJKd>Q$DbNeJeg8ca0xa2Fy@1NT*`BCH#%pH*Y81e__4oZF> z@`vUQNq)Tb(CXp2!&b(3R*vX3nf1}RWB#%2<7)psYwls+**>8TAoqwm=$}-F{F950 zdPp7q+?jh+y|0d|hmmvD3ABGK`TB@DiL%Gl4dtT6WBwCTo>z~nCqB>3J^4mPJ*l4h zJfohvYtKD}x2M%9yq&_^(#RJB`97zf$BZV>_Y3Mn`SPN)I*C><^>VCzX0fPVRvIJx}c`< z<*fQxy^bC)qWn_wt*G8mZ{piI?8;^J7Ix(=?8_RnvCGAyvWkUvbwI``#eAQlCrL4s=x9>LibG7ipSR1 zlo$E+4ehP1`5GnVcLKHE@~>~M`FI<>uDyo8;5BZs;D;8Pq4ZE)`HS9qE2>BSov0p0 z%GYeWyF6HrP=2t!*ler%LbL7ZO^nryWT*q)dKAde^~FHfy>{3{<*}q%7-`>I4N)=@ ztodz>!gsvx50``WmSRD3Ep1gEdaES!N_)uOxXjf)r2Q~x-S+E^poIaGMa0%@Y`q&h zZEw|&^V*Nrb-Tfpra$H#Jkxl>14xv$o#|$_t$Ue!*0y~wgDtgZ?ptT7+1ObLn(a6j zuCQ9DV*jV-^8{vy*CpY|s5PLFNyY07cPqvy1 zlWUvNa?pOhcJAyXznoda33y9>IN4}58@DFcqh>3tt!>7o`dSb+?=%-TAK~Oco-zk4 z{V@K-&f!89{n>yND8wr=2HoJ^G21V!Y3AA%lV%WP!6um}vLi|No+TeAo4BKgA7 zCz$6^>ElS^LV_Dl;w7vgv8{2dV%e5s*zh2Emyz+!6OYz6omzFJFh$%(BfE~dMy z2{@WF#&9wOJ2c}w!JG_MOuKswMInLC&6W%L6f$w{w%1zshfau)$qkss6J9_PVfm4D z*Vd18ihxi%%5FP^(qt=gngQtf_jJz6~TN?g$XS_?#?T8PWdu-OhHuifzD+`?w$;}n(O2$UaZ!_6>$ zXvvQjn=K#t$Y1r__=29|%6si5D_zt&(5M*^Wlm!?W_S8WQC#(I`NaDg*E@!!Y@5>< zx9kT+TR(@QAD%%HJIj7+EiSKmcj_&_y%a4sxb^9edq&8XeLIa^#C`y}?^#=R*H-qe ztlrlJ>+agW1{mK;aD6M=&4x#mb1l=&svJmd{+6wuK)#@|QV*qDPGonpcP&*on%T+$ zACP}NbMxHC_EvtY(B;>{U8|c{xm(VW%*&ZAr|WdBTaKQ#GVLe21%>fc5&gceO4|%}f*eJa?^@EkjHG{4Mn+%9aK`EA zucV_}`d8aUj)RiC`5LbE$2ViE@)3+(9qBy#u24tmcVa?1;&I{NhQ#8xwQSZ60J9T8Yc z`50J=j_REHD;OkXQqC6bidD=ywqsSY70bcfxP8bf^4&g;JP5$2WxJ9sW{;xO##6k1 zxTs%8;|89g-w57b!xR25Bz}fsBSc1PE?cro*^*PrsV7t(Og!h~92Nx%kSn32;N#R( zxtAO9i(uy!H3|`+q{dKdAHJ0#^o*75O^K8lcuTM5c#OItGF4 zusVX=KID$7W5|uGrxM|AzX*2)v^n4(JeI-ekI3lAtCNyDgxo%rh3NFCa?$o78Ram( z9g$HUQ;(zcsLBFjo{o!Gyw2t&;C<(RpLbixyCecGPUTkUwwkwmfRgr?)?1!7Ul!Jd zNvOaN-F6UxgS1+kE~S97i(j+WC27gjbKM+L5O)h?jL!u>ROni$o$Wez zosZcH45MBmhg9h0c1AxRm09Diy*+XdEfw0w(E;=C6VG9tswMchld;INnY7uTF#`46ubd zaJ?DT>)%F$kbJaK%vruVpkjbk&Xv;AvhIY5mK1|H9VS@W=GHW0oWJdQ!Ds|1DG!VQtLn92%HVufi@a z-#c)!J{%&BW8Ko_2#3BRd|N>tLmvF*`#iwRii5w|Kg2g#C5!n801Be)(vL#j}c;#ENsV`iuF1h*6V+j3nE~avB$@UciGe! zS`h^ss@$@-caV`4Sy&N(a0MXPIVdZW6>%+i0LCkMWq&sZUP@3e+{m;ahIm)pe96je z*;b|lilm%YX|=qS1)u{^R{+Q>BP#b@{QV4Izh!@7Z&({RL9|DTy~%g}=PAG zh-P%k5S~px60(yL0t$NWYIA8BG|6kW+>K_mESOHRuWTcJWjDr+LS*I-@;6CnOHR14RSko4^BwW1Jo2F~CEGIbt0M z5Y9`~SG)7eb?KR~$w zV0+AR9(2ZflNFlu^|Pgb!a3@ap$^6*ycA zjIsw1T$!6F7J#ZtU_+^-ZJZgKRwjH`oQ9`Pc43d{8C^N*ejCR&&X3 zN3G32PIo2mKmdBsIWfE|!LT?IG0MjWL>PCIb@R6)wQS8t%VxV=e4Z;*y zpMC9zxpDQ>M<^e;!nLEm+N)NAF%o$UjZ9k z_gcx9LcOkn2B`c~XcOn4s0D3(j-5Qs0%suzTKYP(+4Jp9eS=><=Bs`Asw~OC8+TbR zvD~2@DIUGxh5p4<|JGcIUghWFWy~KkkB;-`?;6-@z;FGdkQ`aOtb&IndT$YsVwXsG zpqJmT*!EX;*8XYHv42v`*34yp++&OVdu(U9xqCN4fHqk zqoVj4p73uY>5J`tcE!O%B@hM?h~6-XK;X?ogog^pFDNUhBFc&oxl5{yTuF`KOBv6I zUlFmoBJaqnQOS)a{T0=i+J_cn=nKj~BG~Vfp2tyhzX;hzz&{{D_Cs;yZQoxbD1jZB~e@qT+SRti81Bh0f6ZQ{S5r+Q>>I`hZ>^#r=-{BDqg-G?#;LyWj z)vm#_XeTs*2uX=*1)}SKJf+`5x&D;N`%L;LFGCZ+{sSHvx?**X?il*(1*nu5=|y%+ z;m!2D2c8L}{zukWM$$RFV~m7G?I0JsNKZPT;AwAz&7iH`@O^kD{QqY>LRy^su3h~( zW3i=vzmAk+wE4I1p$X5Lj!Xo zhr;wna}(bQ{2|;gz&r>zP!+mai1C@bnJufGh3O7|(=QZuV1}X?^dyD*C>uFZZZUh; z4xfZ+31a_Nu8s1oT-Vl9-Q3!<%7)R&?!xc{6W~kToXWxolxsW4Im~r);f1cXolnIn zsmng0<$>%%BSfDx0ddUvv}QNIUF_!WSrDr8{kH8#qY`vS3nnk>i4J-QqLFS+X0<=6 z=ue|j>8BHoO21Y+-*v)I(>mxq?R8*A)tt9KpUKR^#2C4rn`|#6WaYN~4M@?xX!4PQ zXTgOO1oJW|UCrp}Mx}HYjD8Q5U5S+Bdy0msDav6}^K0yS9+es%YS0)BG5mH@L7ZIh zMQjY$*VbST65)#qziKWn`Wk5O!dK!=$cW*D%nA1TrViS$WkwLvrNwlx3WEZMhQ(oM z$O$8t(Z65@jE6YTFxrGIn6po&)vx}pzZ%@exAQaCE@QGlrhW^& z^RSF1C*7c)t*8|Qw|dht#-%px*AOeA7CKHc`@ zM5n|+l)~Z^U=8*mF@h5UWdpcf=BR4!Rh*l4gM}5pK@++*(1=6fuG6k=V8ir~sCLN^ zgk{q|bL>={WysXr*Nw{!uo1ZP^APVb-u%2-MbaFkXUe@n_gb$Kist7BvEXZ(wp&wf zigYQWd5hR90hjZ&% z_>qzz? zgx9Yn=$~L=I=ci;_gd2n18X|36hRO3pP!eL!hk*7=dM0H*2bA}TZZSrv8kw)={rEqvBvU6dJ9;BHz+Bk zvWBKwg?NP>h_g@);u5vbi!`l6+C0eOJZFX8b{yz_)K23S%nB|5 z?m_}m8D}>R>$3hEco7A=Z(D0*QI`IA0=-ipWcE%0_IZ*0cAo+q=(M==B)tED5r5WU z2%{Z1jKo>79zuPGoyi0;7}o41wxiz8cshXH4AN7=k;+eq9d^rJP_!S^UQc`ZPWGPJ!BXbpx)16W^hF~g>kQ^LjmKfzJTLldv` zlnVhwYmo~H#|jRj23dE?pi+@+hykJn+%~)0O0-O3`lYKUC2D^SV4?py5`Zav4ElGO ze2)c=G2Xt#g14Fc9+Mq#x{n7l5bQG3gVKG3(z2z0pRGuh`tFq2p>0vj$U}}Lfo{|k zvO(3bi#ZTz5$$2)$sWr@u*4HYVO`HD>$|yo0M!VV`N6Wp*IfuFcC>|Jao4&BPk1*E z0JpvOfgQA101Qb~C&ZkNh>%DFF8yWib`vlJ!Xfr^GObf*NCi*=DYn^wdssl!+lluR z#>q&`rf?~A--zqRn`TOC?zQG>lRn2NkbZc|ymRMB;90moUwQXSy^$ zCIs;EVsCQbTuYELfewb?;X}&zDG141vkg)=NF196OO1UOIGV)Ctdqu4L4oit&UV50 zRj*Bj(|8c53y9qo)eKCD#hETluu!Nr0SGlDHcp4y4%gT-N7H)&%IbQJ2Ee=x2YM^P zRanMm9 z))ctX*}Cg($c6$cV5$wWX9!N>CLjgwO@e(I$dg$DSP_Qtll1hANn z%)I(4p19MclePgpH8eWMbG;=mbv`7MH<&k|op`;WlW+ivzOXnklt|9opb_WUn?8_P zfc@vns`@6V7bH4bjbf*PXpjNh(M1#*@0ggHihaV^XXN^CveFecw-$}#WC!If5e@~u z8>G1uE1f4D_&%KnhaJa03aL+jABCN7L^Uy+)6qX+v_*jLjsSq+5>Y8{-i!-Sp`b3d zcUe(;V#T`{p=;?9_1V$lg^C5VhG&)yy5oWdYn7b zh#pU@P|_Q?12`1ruw_QpqASwGK2b93;22zogbsolg%Z93H!=2CY!?`#U4P?3?Y--l z&b-oF(mNjZEo^|O>ShqS&%nm;jD)3dqQdU_n@C$yu)efB;i`3E1G5)r-4~yKg{r1Z zLf&6EJAqwpwAQJo57?t_U;{WA^ec16ipjeS%>+XUQJn4qql81S%jM)$9#5?kG)R%a zCHllNplE*n%K4c$zBQdLYyu_I>{)o^?A2?RKR|1DR>EL~n)V5h;iri`h?+pUx9LQB z0A%22XdW{GEQsJJW&)E}rt8m8vCx>EAN2+V&qn~-?r9pX!1W|EI91f`JhLnIQ(6 z&@pO<*s&l9I0kYg9|)uagaf@2rPdPGzvoOCW`tItPc3j91Zb@hNK+|DKLf(3t4QK~ zJHVk@*6*;~VGnT;p<*JO=oz*UQv!80eTGSm$t03EZ}>aZ#y45^2TX=Jf}TU!_s9zl zA>%wehPb1$J#IPq%1<0{1;>#ZaS`-D9IuF+4Lq14m*NqeQo}c)+>I<+r$0IjD3wp+ z3I7O5l+llZ-orrOM)d9$90n^kXnhv69^qap3x~o{lsVfl__Iv%FuQ{rKvIXB;H)W0 z>f~VZha2JhnLo7eA%G0Bd~u~DajmZn)hjT#Ok{oboyRwfs)|W3CA76oPpnfdd%q6u zk*cmdS)=j+@>;-G0YH{wBM{=^F*aNRY^Y=zMJW}-<>V=)KqQfWbnkik+ybE3stNR_EK96f-?&qNU}@|V#b}J&t}^vch~v_I!jHQ zrxPF@7zYx<^8Lpp~B$IF{wn+R?4 z;frdZHegV1KuRB?vjcQw$~Z`{SgsdwY`~%U>v|pfE1HU8OesQuD&@@hAbYuUXuc=Y z7dC-?3lXCMTuCG|-e~F90AcooDgy(*wm*d>)5c46A<^(Yc>Rr(Qb>o`7+CY*LparE z{yV2Oc*3bw+)UMMOk6lWJNx?i>*wRjm8;X|uOx4{t@BAI`^jVt7ZhZO&Lck)DdT;Z zTz&fL%%#h3)Ze`N&c#j%jSYT*p@Bw#we}HxW)N6mtisiAQMl!OH8ZssEfD$3+Y0(F(4m6!9Q{ z%{mF&Pab*aK|Xs3Ip-_=k5H+BXXr;w;x#-W*;+rqWiE?g6Go#uD~vuzTqOcpaA^@i zDFwuyr=cw+zofFPgRf;Zg0E%XkEo8u2WGtnTpyR{Q@ddPHuNU1o1A}4ip79&@ z29$mvCJ*>}WJSFq005=hYtSZyr@_SK!gBP`p8OHd?8jx?=kZx#k zF;*-t0y-@M0zm_evb-Y*k~>S90y~=Qfy|8ifDYh7;*2qU8h{bG+=L|;vMyy{P{TXT z)a8=id{RFrj!6F%fR2d+vGkuJ4M;G)dKpJi@jK1AIu z>l1uMFsbAi5RB`4ayO(+A#6A8SL?K#H}5`EJjT5=Mo^^fuON8AaX z8l&@$7t7hBCCzdzWHDD?1sfe&GKmpIUODA|g-j9&BjycWjbh+;I8Jl4f-xHA4fsnC zduQFn)vMc?@LU9vCF1MLICos6!99nUQ3kUI%^_hg55HHDB5(2)p}QjdmbXWu3R}WJ zVoSSGN#*-JOU9({h8M)%>)Pn0)XhS82ArvK*WMme5QQmBg9MIvQ#ifXNkM?&21^^k zDy+A#mnB3`uN(CrXonk3t40{bN3vDkMG~~7;jrey#GINIX={x1CTzRVza((jzvIK_ z;;RAEp3%^C7o(NvsTv{ONbDqanA+br44cc3u`Fl$YsTS!@X*$C^V zc4_~?l{lmn#CdfW6Q$3L_W~0+@rJK&b^P@u08K0KpbMs(2NlZ$d^B%E zjWa6D4C9l{GK4h8xIdFXW4-<=C>x@iUq*_cyGSw}r-lvI-#}TX+=Fqqy3dGOh2)^+ zmho*vL@BWuFWbLlPRLRoah72e>c7hpA%1_0IZ`{^ir}?w;A5O`iGc!6IyTb(oL@_8 zn@Je8>9bE3NfG68Jh!8sV7u4=idabaI6fDTFixOsjprFBP{wuEafB#Wa$`B%EzFML zwxRxWRO1bEfB|mFLe7lGmRi9AZs0W5ar+WVvD{+*3slqphRMH0(f|#XABd5d5*X_+ zjVJsJ3Am))%BBSqm36q_4tBvohZd zo^@_}I!sN+Ldyg@VFYIE3<(D5b6;1ZEi@Iv%(T-WAY3NwNpiiVfCM9W&)XE~%)bMH z4{{|8bdY^%*#H$B*nkZ&D5xMs5)+0-%$h>HA8a3xSyOzI$VhyG*%G0MB)VqFL+T+R zXUe@O>Il~X@=C=GS_I%S(3?Y*0bsql17VK15e{Pu$l!3~+At(ef#yC#!>TL|R68A_ ziF^-UTNqFdqEB1;K|`<9&dE0_e5nbagOD_Xr{cyI1y+Wp&?yf#07q7|*#{bo15)hw zU4yU{w#BhUB>`En7VnxsYF8j}GeEMNG#OD5*R41o-ofgvs9MrL09uKG(NKneh}TpD zBxvCx74F8%*tpzD&wzq$@ebh&*PQo2VAJ7mvzsi=7ZJyV7C+n}@ZsKuIq*8+mO)(bZx+BDNr}{c;NWUj1;I%AKcQn#u@jv2BTNo4ImuE>KhHn8nVIXC zaCgL9CV_;^V1ndk$)&1wscK)xGc!|t*)03tvjZAV<2;=p?Iq)dD~a0~*F{44M-bv1 z{pX=3S&~rgxPX6^11eB75ZFc2rvzt72#@jERaiF4WQ++lZ`{GeLBMt`!Cm+_OFo>v zSf76L;`G~>XWoeSn^|Ccu*oDRID-fmhh}-}_u87@(EFv2>zL2`2pgm5ZlcK^X6_V| z4JOYaiL+pj`gOiuWI_+32|SnB^xJ&>9VBt_g8XAAxCO&7p*VjX!{g=mS%Gdru?34t zZbV`d_vH2qa4U9*-*Pwu=iHO7clnEmG_gq^ z$d;W$qeshQ&y9UxA2*j~aBb$xl^xEF% zH+$$(4X@qU_sfOy|FxfYzDmE_+44_MJTrFAKJGjqAo8*8@>lj0`^tYQ@5%T!uI?1` HWB30b`<>B! literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/click/_compat.py b/website/.venv/lib/python3.10/site-packages/click/_compat.py new file mode 100644 index 0000000..23f8866 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/_termui_impl.py b/website/.venv/lib/python3.10/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..f744657 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/_textwrap.py b/website/.venv/lib/python3.10/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/_winconsole.py b/website/.venv/lib/python3.10/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/core.py b/website/.venv/lib/python3.10/site-packages/click/core.py new file mode 100644 index 0000000..cc65e89 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/decorators.py b/website/.venv/lib/python3.10/site-packages/click/decorators.py new file mode 100644 index 0000000..d9bba95 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/exceptions.py b/website/.venv/lib/python3.10/site-packages/click/exceptions.py new file mode 100644 index 0000000..fe68a36 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/formatting.py b/website/.venv/lib/python3.10/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/globals.py b/website/.venv/lib/python3.10/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/parser.py b/website/.venv/lib/python3.10/site-packages/click/parser.py new file mode 100644 index 0000000..5fa7adf --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/py.typed b/website/.venv/lib/python3.10/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/website/.venv/lib/python3.10/site-packages/click/shell_completion.py b/website/.venv/lib/python3.10/site-packages/click/shell_completion.py new file mode 100644 index 0000000..dc9e00b --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/termui.py b/website/.venv/lib/python3.10/site-packages/click/termui.py new file mode 100644 index 0000000..db7a4b2 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/testing.py b/website/.venv/lib/python3.10/site-packages/click/testing.py new file mode 100644 index 0000000..e0df0d2 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/types.py b/website/.venv/lib/python3.10/site-packages/click/types.py new file mode 100644 index 0000000..2b1d179 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/click/utils.py b/website/.venv/lib/python3.10/site-packages/click/utils.py new file mode 100644 index 0000000..d536434 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/distutils-precedence.pth b/website/.venv/lib/python3.10/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..6de4198 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'stdlib') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/INSTALLER b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/LICENSE.rst b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.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/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/METADATA b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/METADATA new file mode 100644 index 0000000..71551b9 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/METADATA @@ -0,0 +1,116 @@ +Metadata-Version: 2.1 +Name: Flask +Version: 3.0.2 +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/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/RECORD b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/RECORD new file mode 100644 index 0000000..8c66241 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=2-u97GwcbJywdMfCCWRvm45WLh0rvCTdMyvWBdRmULQ,235 +flask-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.0.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.0.2.dist-info/METADATA,sha256=5SsBudAoun3E_3ZSRXJLB2V3NAdALovsQMKUvzqcJfM,3588 +flask-3.0.2.dist-info/RECORD,, +flask-3.0.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.0.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +flask-3.0.2.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=TQfhvSlv1QpaPHeeRz_Ke7JmiSFMMHT-rJR4tqsEHdc,59706 +flask/blueprints.py,sha256=H7u4HzNn--riGMTt5GkxUHpYRzCav-WDGSKNnBSEMcU,3160 +flask/cli.py,sha256=eegT_64cSOqaKOwI_Am3XwaCSJPZ9UEJ6EmSL0qg8xg,35833 +flask/config.py,sha256=QiL9KkQT8RWc0HU2AE26Yw5mdOkNsKv8TEFEbXkqhJk,13328 +flask/ctx.py,sha256=4atDhJJ_cpV1VMq4qsfU4E_61M1oN93jlS2H9gjrl58,15120 +flask/debughelpers.py,sha256=PGIDhStW_efRjpaa3zHIpo-htStJOR41Ip3OJWPYBwo,6080 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=tYrcQ_73GuSZVEgwFr-eMmV69UriFQDBmt8wZJIAqvg,23084 +flask/json/__init__.py,sha256=hLNR898paqoefdeAhraa5wyJy-bmRB2k2dV4EgVy2Z8,5602 +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=q6iB83lSiopy80DZPrU-9mGcWwrD0mvLjiv9fHrRZgc,7646 +flask/json/tag.py,sha256=aXslvQyO4QpxviWJqxhyOj0CCQKlYXq1r0H9DKqiEY8,9280 +flask/logging.py,sha256=8sM3WMTubi1cBb2c_lPkWpN0J8dMAqrgKRYLLi1dCVI,2377 +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=ZF0Yy610NKSpdJ1d6qtG4L2RkCmzngu0G9FFXZf4O_M,38209 +flask/sansio/blueprints.py,sha256=Tqe-7EkZ-tbWchm8iDoCfD848f0_3nLv6NNjeIPvHwM,24637 +flask/sansio/scaffold.py,sha256=9SSSC6A_zzXhcEVYf9wkrKx2r4uDqfIWsnRNYSvDclU,30879 +flask/sessions.py,sha256=bIpZRwiTfnYJn3ikVnCPcF2kNtyRz0dfpsuMADIpSJc,14518 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=2TcXLT85Asflm2W9WOSFxKCmYn5e49w_Jkg9-NaaJWo,7537 +flask/testing.py,sha256=3BFXb3bP7R5r-XLBuobhczbxDu8-1LWRzYuhbr-lwaE,10163 +flask/typing.py,sha256=ZavK-wV28Yv8CQB7u73qZp_jLalpbWdrXS37QR1ftN0,3190 +flask/views.py,sha256=B66bTvYBBcHMYk4dA1ScZD0oTRTBl0I5smp1lRm9riI,6939 +flask/wrappers.py,sha256=m1j5tIJxIu8_sPPgTAB_G4TTh52Q-HoDuw_qHV5J59g,5831 diff --git a/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/REQUESTED b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/WHEEL b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.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/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/entry_points.txt b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask-3.0.2.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/website/.venv/lib/python3.10/site-packages/flask/__init__.py b/website/.venv/lib/python3.10/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/flask/__main__.py b/website/.venv/lib/python3.10/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4055a5e03f92a37756a71e9c7c3c516645afe3a GIT binary patch literal 2286 zcmb`IxpNyg6vlU#$MO_)Qn$1^Datk}`A8Ed6URUaH< zpYrUHZ@o0y_uo-Pw9TyQ#c`rM6(q5I{tg8}X8yHIV*D1q4n27eD1RA_cq)Qep;3IA z#Dm}rH17=*7p@ux(iQx>5tr1z(NEGVw?7hs$7bm!=A=DanmGCxqsUn$)Prvr$#F7;S|nXKe?oBH+vitQ_!(b z2Ql6jdX~`aGp0Mn_|ui%D)^%}z2u2;yM8Xk+3@A6Ax+y@+QyJd_m$S0fR>FR0Fw z_^MAOJ^9d^uYkX&^!9rUxW?P>+!AZPk3-w`(IuSxzn1mTh50Xa{}r3xJJB>((@fJ z_MOWh44oc#1doynctPywJLf#;oOYaVBzFef!*)0xRH#I(zgN3v5hZV#_w0}3mr}%mQygN)H-j$y0 z54~<*K04`M@}3M7?_w|UMHjp4rdMj1#7M?TmwN7{*Z^JRuHIzVby2a(bvx-5odvEo zB^zxlAQvGelfHS&GOe6t7XPW)B};sUj&@!LC+>p9Jra7R{Yh4F-NA@5juWN4Wkq$B zA{UvdGDGCa$>Bl@s-vvZo4gmLDC)tu(s(xtTaW9jH=+a*WfJF0%E)3fZRip7ReFymo5diPO-JgJ0_uI>I0n;x>{N3ag_L@kbh41 TLcW63jFMHeYUcm literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/__main__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/__main__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b91a80a74c1f87493b9133c5aaf3f1f97fe189c2 GIT binary patch literal 211 zcmd1j<>g`k0_V@~Q{{m4V-N=!FabFZKwK;aBvKes7;_kM8KW2(8B!UW85kK-n1UHJ znO`yjB{dmuvE(LZ=J{zd-C|D8$t(hCUCB_y0;IsiFF*Z^{M=Oi;>6jTQl8pR3V?9FyeUOZ9L1J=tVtQ(^ep*gqakhSZJjjmt cc)fzkTO2mI`6;D2sdgaii$V7AFmN#e0J=~zvH$=8 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1838bdd9e9094892b0cfa66b67a658ff5e61ed23 GIT binary patch literal 49881 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 K;(MkC^Zze)USP!l literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/blueprints.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a582c1a2d20b9e3f151d70a84e428fe6d85bcf21 GIT binary patch literal 3422 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/config.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..338f852e1d999dd5429275fb85da82af8561a760 GIT binary patch literal 13420 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/helpers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba5b89861739e3419b568c700c3b96214ab871de GIT binary patch literal 21606 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 CveE1S literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/sessions.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eec64f98997e9074b765eafbbde76a005fd2d8d4 GIT binary patch literal 13288 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/signals.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54d0de278607802f2b794166b82bf523b578c5b5 GIT binary patch literal 809 zcmY+CJFn9)6oBodw~zF7FXAEb4?3i|2(clA#LQjTx>#;<+D1)mV>|be6^Y*gBY(*& z6AKJ%Oq{s&RqIIB=i}pJe|F?_nh9AO-3b@ejkyrga$8Daa5%c*H5kQnXs;~Ps^S(>4Wa-IMf-dW8>vGe4GHaB z!{-K!O^xN+V&Y{8Y)Vm@9Y&sphy|`ou}uqkC)#IQX|eoaG2G{%x`VVYxKg za*}^_GNBq@_$(xq!oB9GVE7i&O~t#Mo5iI|7~3?q(ZHC-MAZc?;q;tIBnz9_&tv*UMMe vSvQm7|FFmVG+9@1k1>B$OZDJ}Z);gJ6}+RkgL#SFgiNA-oJ0vd|7P?*nfD8E literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/templating.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b8c0c8a46231d8d81010a6842728b119f13cd01 GIT binary patch literal 7083 zcmdT}OLG+074FwO)EbS10P(U-V+?p=d4$1s5{ftwfo(8Wh*69gtTe5;JyMIF?$PZY z38`8s9H=sts(6!Cc2ZTcV3B{2pOC67vg>VDUS;8(s#4@T_jZqFWE4LtRjCZst#kXn z&-u=G&b@>qBc_7i^jH6MmtRzre^8a`+T)FJAy*;qZ|qkUS6@279gIBcA8b!FCPeL+f2e)9aahRv{3Gq7jiZp? zUbZ?V_dBqWQy&0c49NGI42*%Uhq>1C$fQffc?lJrv>Ad$ig>$k4B zEvM_pR=#vA+o;vyVbhJGkk>8iTCn6ctzEH;6eO4Cx-pjPB%D(eew%!eTH1N5Rc{2*R6JuSjG&G-Q+WtskJeC4UakD_w>=G0=? zcBdjIYA!lc&FHPOQ>*TLt{rhIRHs-8m4NfWz`f9$@~R;9xxEf!a$eEK(t_2 zX{bzTXiSB#53@2G0>TYuLg5uo?6CgV+abRnS-yAQwH%AP3tivg)^#sfa?V-UQI2kF zz8hPMPGm(;faNgekxMwfQ1ksDT=iYH;96nJS`1e$0kkubHSc%b4)=oCS{2hop%pJW zvE{{9(+OZ$w*%gYtr1Q4%6{5 z>?K&^Kf~A8`gSr$L1- z^S9ZvdOF2%CrRCgRQXQ=s>h8`>TJvG(&t;W! zP4bcaM>3gQ?1|O~idU9E?ne|}Nt8_ud(^f-=#ceXCLcL`^^==7E?=9mXRm$;VfLzh z zCm}O6cgDGhvH)mBufT8CPwb({ogM?5rZ7Q|*z^|=7L*M*|Av80f)cjWE6UvIPqmH0 zMsdBG6gO45@r_bqFr|xyC8Z7Hwh{~*h?8rlRfYbcf9Z}AsH;k%LsiA3kd#{b7RY6J zh^a`=kd|#A{YuJEaWT;n{gI9mji~bJ#JGjA677-t8?~m-@Df&qze zhq3wr(Zk7r-3pkXXSYiz^x10y_R=?u^`XSb?R6X8s=_&im5xa(-BFect36Hg*Dwfx z_cs3Q=&e@Rt(TJBuZdmzKab9L@kCX;#&r!eUcuhAXJu{u%(vJpfq(lzI8gjji`Y#_ETA>#KoJC0lc z+uby_6mn0h-7E;T929EVX*nrdL1A!s^eQHXaOhW-55=WKeWd1!Dua%Ze~J+O4(3gZ z-3~+IkXC7-J@1Y9PpMKzx|JGKlR=GA(+H`u^t4N8^E?LRS5Oh+i6-zOot4#UrahuT z=u=xiwTJ!&*D;f^w9F@Z;SO1bpx=|d71T)*^;3}0OIUg5>rd#bCRmyu3KTj~SJPOSU^Du~G<%Kj)1LB6b;CG)UpR!vT|Qrn{>iA9m& z(^7WE;Iza6@*rm+RutH{1R*C6HOmKq0}!kNP?he{`{oJM^I1MA-EYKKI-DgM}rUy=-|hRNpcH` zz0rV@fd|P4hfmq%*JvP*6`&qdEj}}K`Pb0-O`7dso;b)PF+{uo{@7W`$g2t?+FlWaTrdAB;O+WOD8CWfw6FsKur%x z!lq9R{tJx31vmut2(0Wv$f#U>uj_BooaISEdDE|;IpL5Uy?S4 zX-~G?Layls)&6HqPwdikHo_m!Q=X;JR??QN@Y${K1 zFC(ey3Cc_Q6YUAobfPL&{9O55{akD5%wUDb6$)Yqdq!;V6LBFi9;pak$S-T98Gaq3 zNw)qKq$Zw$AI%DKRwE+V&y**cocAiS+xL+{(82j@vs1Qk4b5vtT3&DiN@85WVEjXT z`xkIkH^Q9? zjU)QYvB(pVV03Wh38Eu^b*vT7T^;nn+{ymG$yIE-Ubj|o)S(M4#$0ycf_1KbPSj+) zyW{NqW3oM&l;5V;ZuXQK?6K!x&_+6QRX8&xncs+o#&faoJ&AJwBnW-q1t3BN{UFJ} z_U!=jzar`HY*IRnNt1s19FtD$GHFKBf1{>%=tZoU)60I6%g;+SWiX(6$)}WXf`~*! z{)oN`qM^iTpkBlgYWv*!Z#7d!d3(;3)$cizs6R=!gsm?AmjJhfoGzr&V!YM?5>hoz ziy{L#$8}mL<$2=viBn*bR|_S1BN~azcX{tl`Al{D(GjDflyN^n?u>u=Ur{P%B~u?89UC#Pn-y~u&!Ou6e*+L_ B)>Hrh literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/testing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e7a6c65894f02fd94d31561877cfd8898c0f1b6 GIT binary patch literal 9846 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 Hxr_e;Tq{Q; literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/typing.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/typing.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..579c828a8ead6e0639da57f432ca64888305c947 GIT binary patch literal 1833 zcmZ`&-*ekU5Y|but@u~c#7!NiNkjP=pjLt5jbTXKw8=EInZzxFUp!}P?I<}*;!a8$ z{s-RpC-|4{l_#Ef-~|{4vv-ngH#1nH^X`7%?tZ(H!dk6t;IH$??{HN$j9-tYL9 zV*;%#KlQAOZD?Unr4aAlgPc3Yo#o82ntj{LIGVRJ=b^O;%`_kFt(2Wd7izyVLm$rf zsH?q;NJXJK>%9$QOy=F^F|^)R@jga$p6+?8Dq?dj3)q694;05M;i;c#@55XEN14B? zRer2It$d-{*i4o7KGA5lbF??{Uf|(OIrCFQ@@bdxi8S*)V_f;_nPmIaeIMm~R665o z)o=6Ko_S{MR)169#4eE)8U$fXV?PYU3-p)2J9~Dt7e&k;>L7+nhd@2x0!`->M1)M> z1x#;q8&7WGA!|9(VN@t;VGt&Px9iGszduUighRj2@sl%TF}{iXU@S>2Yu)cp4*H$L zgU<7#7tdt9j}VA+@Y>g6?5CCQT?4=T5t4D+qcIgRPll?R(9LCYh6)-8KWrm1S11dw z0-Q`*n1+gOVi3|k_C+kMz2HWczNL|t;vB`mX&mzT9Iq)$Ko+`5#6VWk6{Ioe41P!; z7=o;3n@QuAAH;Gk-@_@O${4Swd)L&Dwb|Gkp}teqR>U(xYad1-ho?Rl@onsGiro&|PyAslx6aOiu}&Do@FqUt z;Shuf`K)ejp9(m5GXyPDu5^KNFT4(Bgq4O;>*YGH4KCwgWJA>;L2tGz>RL=^Dy|L{n=wzA&(+Dyrg3g z?g-!bOE-O~+Yvs(uO^|FF!-8aZSgZ6Rl_lhW|gSRwoIa~GO3#maftbsJ>99PXqBuI z^Iv;vmy}&4b;bL~p4Ka6(?+jB%qgPw4#Cq}B~9(OY#WhQhBe8ywpQ#F%-AM2d8pXs O6|$Z(3cAbGnf?be7x-xa literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..495addf5065e9b499577edb2270b31b0e03b9c8f GIT binary patch literal 5543 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 DKYsTk literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/__pycache__/wrappers.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6d69241fa66914b7ca81b7c8a39296193d08da1 GIT binary patch literal 5237 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 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: type[Request] = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class: type[Response] = 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[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | 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 # type: ignore[no-any-return] + + 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[misc] + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def update_template_context(self, context: dict[str, t.Any]) -> 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[str, t.Any]: + """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) # type: ignore[no-any-return] + + 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) # type: ignore[no-any-return] + + 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) # type: ignore[no-any-return] + + 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.Any]) -> t.Callable[..., t.Any]: + """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.Any, t.Any, t.Any]] + ) -> 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, cabc.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, # type: ignore[arg-type] + request.environ, + ) + 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 # type: ignore[no-any-return] + + 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[assignment] + ) -> 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[assignment] + ) -> 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: WSGIEnvironment) -> 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: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """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: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """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/website/.venv/lib/python3.10/site-packages/flask/blueprints.py b/website/.venv/lib/python3.10/site-packages/flask/blueprints.py new file mode 100644 index 0000000..52859b8 --- /dev/null +++ b/website/.venv/lib/python3.10/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 # type: ignore[no-any-return] + + 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/website/.venv/lib/python3.10/site-packages/flask/cli.py b/website/.venv/lib/python3.10/site-packages/flask/cli.py new file mode 100644 index 0000000..d4df280 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/cli.py @@ -0,0 +1,1111 @@ +from __future__ import annotations + +import ast +import collections.abc as cabc +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 +from types import ModuleType + +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: + import ssl + + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module: ModuleType) -> Flask: + """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: t.Callable[..., Flask]) -> bool: + """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: ModuleType, app_name: str) -> Flask: + """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 + if kw.arg is not None + } + 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: str) -> str: + """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]) + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[True] = True +) -> Flask: + ... + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[False] = ... +) -> Flask | None: + ... + + +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: bool = True +) -> Flask | None: + 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: # type: ignore[union-attr] + 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 None + + 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: click.Context, param: click.Parameter, value: t.Any) -> None: + 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: Flask | None = 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 is not None: + break + + if app is None: + 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) + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def with_appcontext(f: F) -> 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: click.Context, /, *args: t.Any, **kwargs: t.Any) -> t.Any: + 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) # type: ignore[return-value] + + +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( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Command]: + """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: t.Callable[..., t.Any]) -> click.Command: + if wrap_for_ctx: + f = with_appcontext(f) + return super(AppGroup, self).command(*args, **kwargs)(f) # type: ignore[no-any-return] + + return decorator + + def group( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Group]: + """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 super().group(*args, **kwargs) # type: ignore[no-any-return] + + +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) -> None: + 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: click.Context, name: str) -> click.Command | None: + 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: # type: ignore[attr-defined] + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + def list_commands(self, ctx: click.Context) -> list[str]: + 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: str, other: str) -> bool: + """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[str] | 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: bool, app_import_path: str | None) -> None: + """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) -> None: + self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) + + def convert( + self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + 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: click.Context, param: click.Parameter, value: t.Any) -> t.Any: + """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: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + items = self.split_envvar_value(value) + # can't call no-arg super() inside list comprehension until Python 3.12 + 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: ScriptInfo, + host: str, + port: int, + reload: bool, + debugger: bool, + with_threads: bool, + cert: ssl.SSLContext | tuple[str, str | None] | t.Literal["adhoc"] | None, + extra_files: list[str] | None, + exclude_patterns: list[str] | None, +) -> None: + """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: WSGIApplication = 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: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + 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[str, t.Any] = {} + + # 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/website/.venv/lib/python3.10/site-packages/flask/config.py b/website/.venv/lib/python3.10/site-packages/flask/config.py new file mode 100644 index 0000000..f2f4147 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/config.py @@ -0,0 +1,372 @@ +from __future__ import annotations + +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .sansio.app import App + + +T = t.TypeVar("T") + + +class ConfigAttribute(t.Generic[T]): + """Makes an attribute forward to the config""" + + def __init__( + self, name: str, get_converter: t.Callable[[t.Any], T] | None = None + ) -> None: + self.__name__ = name + self.get_converter = get_converter + + @t.overload + def __get__(self, obj: None, owner: None) -> te.Self: + ... + + @t.overload + def __get__(self, obj: App, owner: type[App]) -> T: + ... + + def __get__(self, obj: App | None, owner: type[App] | None = None) -> T | te.Self: + 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 # type: ignore[no-any-return] + + def __set__(self, obj: App, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): # type: ignore[type-arg] + """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[str], + defaults: dict[str, t.Any] | 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[str], 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[str], + load: t.Callable[[t.IO[t.Any]], t.Mapping[str, t.Any]], + 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/website/.venv/lib/python3.10/site-packages/flask/ctx.py b/website/.venv/lib/python3.10/site-packages/flask/ctx.py new file mode 100644 index 0000000..9b164d3 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/ctx.py @@ -0,0 +1,449 @@ +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 _typeshed.wsgi import WSGIEnvironment + + 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[t.Any], +) -> ft.AfterRequestCallable[t.Any]: + """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 + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def copy_current_request_context(f: F) -> F: + """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: t.Any, **kwargs: t.Any) -> t.Any: + with ctx: # type: ignore[union-attr] + return ctx.app.ensure_sync(f)(*args, **kwargs) # type: ignore[union-attr] + + return update_wrapper(wrapper, f) # type: ignore[return-value] + + +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[AppContext]] = [] + + 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: WSGIEnvironment, + 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[t.Any]] = [] + + self._cv_tokens: list[ + tuple[contextvars.Token[RequestContext], 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/website/.venv/lib/python3.10/site-packages/flask/debughelpers.py b/website/.venv/lib/python3.10/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..2c8c4c4 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/debughelpers.py @@ -0,0 +1,178 @@ +from __future__ import annotations + +import typing as t + +from jinja2.loaders import BaseLoader +from werkzeug.routing import RequestRedirect + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + +if t.TYPE_CHECKING: + from .sansio.scaffold import Scaffold + from .wrappers import Request + + +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: Request, key: str) -> None: + 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) -> str: + 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: Request) -> None: + exc = request.routing_exception + assert isinstance(exc, RequestRedirect) + 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: Request) -> None: + """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): # type: ignore[valid-type, misc] + def __getitem__(self, key: str) -> t.Any: + 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: BaseLoader) -> t.Iterator[str]: + 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: str, + attempts: list[ + tuple[ + BaseLoader, + Scaffold, + tuple[str, str | None, t.Callable[[], bool] | None] | None, + ] + ], +) -> 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/website/.venv/lib/python3.10/site-packages/flask/globals.py b/website/.venv/lib/python3.10/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/flask/helpers.py b/website/.venv/lib/python3.10/site-packages/flask/helpers.py new file mode 100644 index 0000000..359a842 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/helpers.py @@ -0,0 +1,621 @@ +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 werkzeug.wrappers import Response as BaseResponse + +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 .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[arg-type] + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore[operator] + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore[arg-type] + + def generator() -> t.Iterator[t.AnyStr | None]: + 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 # type: ignore[return-value] + + +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) + + +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[t.AnyStr] | 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] | str, + path: os.PathLike[str] | 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)) # type: ignore[no-any-return] + + +@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/website/.venv/lib/python3.10/site-packages/flask/json/__init__.py b/website/.venv/lib/python3.10/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..c0941d0 --- /dev/null +++ b/website/.venv/lib/python3.10/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) # type: ignore[return-value] diff --git a/website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49358564dc029733ec3b1a619a574d394200cdb6 GIT binary patch literal 5993 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 NO4n+x{Nc%^e*qLL5(@wT literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/tag.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/json/__pycache__/tag.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a5dbf0509532740d505c8a5f97ea713b6aafd3d GIT binary patch literal 11643 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/json/provider.py b/website/.venv/lib/python3.10/site-packages/flask/json/provider.py new file mode 100644 index 0000000..f9b2e8f --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/json/provider.py @@ -0,0 +1,215 @@ +from __future__ import annotations + +import dataclasses +import decimal +import json +import typing as t +import uuid +import weakref +from datetime import date + +from werkzeug.http import http_date + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.sansio.response import Response + + from ..sansio.app import App + + +class JSONProvider: + """A standard set of JSON operations for an application. Subclasses + of this can be used to customize JSON behavior or use different + JSON libraries. + + To implement a provider for a specific library, subclass this base + class and implement at least :meth:`dumps` and :meth:`loads`. All + other methods have default implementations. + + To use a different provider, either subclass ``Flask`` and set + :attr:`~flask.Flask.json_provider_class` to a provider class, or set + :attr:`app.json ` 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: 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/website/.venv/lib/python3.10/site-packages/flask/json/tag.py b/website/.venv/lib/python3.10/site-packages/flask/json/tag.py new file mode 100644 index 0000000..2bb986b --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/json/tag.py @@ -0,0 +1,326 @@ +""" +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 empty, this tag is + #: only used as an intermediate step during tagging. + key: str = "" + + 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) -> dict[str, 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: + 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) -> 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 _untag_scan(self, value: t.Any) -> t.Any: + if isinstance(value, dict): + # untag each item recursively + value = {k: self._untag_scan(v) for k, v in value.items()} + # untag the dict itself + value = self.untag(value) + elif isinstance(value, list): + # untag each item recursively + value = [self._untag_scan(item) for item in value] + + return value + + 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 self._untag_scan(loads(value)) diff --git a/website/.venv/lib/python3.10/site-packages/flask/logging.py b/website/.venv/lib/python3.10/site-packages/flask/logging.py new file mode 100644 index 0000000..0cb8f43 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/logging.py @@ -0,0 +1,79 @@ +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``. + """ + if request: + return request.environ["wsgi.errors"] # type: ignore[no-any-return] + + return 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/website/.venv/lib/python3.10/site-packages/flask/py.typed b/website/.venv/lib/python3.10/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/website/.venv/lib/python3.10/site-packages/flask/sansio/README.md b/website/.venv/lib/python3.10/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f823161ace7025e3e048e46890ecb35d313ae25c GIT binary patch literal 28610 zcmd6QX>c6bec#*|3=V?#u~+Y*CBY?!$LfT*s|7)Dm%Ch$BCxyKSyMBE=>{<1UVz7mMvSdY|FB&gp{2`YuQPhJ8@#iNhMAyapKsiRJlJSAEY>z^C6W|oGMdg zZGON1JGy58a3z&p30Qb|-TmI{_ul_LUb8haQb^!u>f8U*oBZiS;v2k(|739STq2PS z@~K3^O}NQMVkKEhCRtB4Ql*sqO_$R0H&e>U-)t#|zv;%nO1_krwwcD@N}*JcdbTmN zGF%##dJgrG(umXtP#-OgN4?-1qCQ?4NBxld zK;!7jQ>CY*{vhhdO2?%B5bDQE$EE%->cvtqnecMUC;Z>W?hQ3gVs)qRbku#MaeC$H z($i9RP=9afz0&K^#`{*@UwXgv`hfeGcWC*8?&F_Ll|F<~KHxrq>j}C3uw1_f*JtGV z8M%HE*U!rJN96i2uAh_ZN%y3C%su{ArgZlCgj;k^yp?cIc*k$2OH*!YHZgwcTf~v^ zWH?l9He2m#yWVOBGq@gX*H=8(YqYDl$kvvs^(HCm}{@E)|-p0O|_Z}b=G#M+GM-!*XKKJ4mDbyTwR@N-+aE&ny)qj+}T?W zRvYzpdA`x{R{eUjU0$uWm)LaCYnNSbzOz_fXjD1g?sMKkwbN+7ID2X4vfsK6vEE#+UTjrW*P-d=jk@1zu6WJ%w~}fl z2g+X4U2SnD3w~>*e53BIl@~hA8fGxOP;X)%suXLJCnfBmWv*PgJTsc_s8jW(T)ogn=u?2ps<^_R(DLdcl zG~KW;S8jV%-)*fm!=0?JtTwpHg?a-Z@42-on;Y(kwQ2(q!t9MIUU_eyMINW?V3{aq zT1_v^`B;G8yf+qq&L=hQjQL?bjo&G9D+iS>cvL4547O2gCvT_xp>ARpHQY~rHVG_F z5n~4e4~uhy@l;r-2lZyqt~P6)&ymKH{!#pSJK>+ipL>^2EVWj=6G1fqUZ1E1?>l*7 z&6^MEZSO?!hS$7tqEVkevAT|JZa!T+b@BwC9M>QTP5@PcYv|kz>a7#i)z#wadbp#! zQoZJt?XupB*918fyONn?A?2S&wT9oGpRBq{1}_4`y+kSLCQ7MSu%=Sl%apQSt~B7~ zOM_maG~^9?BL~5!ZzoHmsP9-F^LBc>-1I{FU;_6uxW60s_n@Bj_PRN6j(r|Dr#s*s zbn|BtgNb^gbjTgVRpCs+d!Y27_fY9!H(h$f9m2igGvM(h#~nd^6m_=Sfxlz;yA!?B zgS+s%8~^sm-?aNYOKaP>L& zxLcH~_u%UD;76zA>Pgg3yHBIfVfQE9FSze_Kk!zzbj1BB_e1Uk?v7)e54&ejJL>+l z`>gvB)ShyG#+`J}qIS$X?tamoa?iQUv^9G8*=Bp`p#c*Kkk<0&inM8J8spTmpkv* zcka5b>&cxD=sRC^7u_Yf^Fe**7u;p{n%w!2chdbucg1bW%qDR4SKU?jx?FwO{cG-; zdlU0KC|N~#ZFybt<@V1&Vf^?nh7|*w^$F_{<^c!@?|K_j%?E*+Z3U7Oy2*> zm5Yv#83ef0{L2AXfVAlN(Hd7ewIyez<$J|~jK*z>ufoh7>+HxXTbM!6YTWSTZ^sAg zbjZ5F+ycl5zFGz{9kG7SkbK)yRlPA7ksKJ(6q{FXI>nE=Fg&u{2>=GCQeg+xV_a|8dGz4^VFW;AMei)cNZW3Z(|`!X!j3tC=V1zf z(?kW*y;pl(1iW>k1~wZ^R79v%I8$Ng+%vSp+p&darWz-3 zgPXqXYJsBC)c~nczedQ_gNX@+21Ij#sv;TC3X~m3W*}S1=fGj-8FlYSxlE)fm&aB2 zV$rF(D=q9Xl&Fab2f7mWgHt+R_pz0i4J@O#&EX;Nr)tP&K^jIt2f6^ zx&!sWqws6W>#$2ulssTE^r%Gu+>X?P8{{lNiFTaqxSz8vQ2pV6j0u}vg|5JL2`+G4 zO}Am0~>v-s0cq{qP&<{oo^>IyPI9I%nbT6GbN&o%8{5G2QX>k64Q zxXMDOfnHNEL&#!c$WAhl&R|TPl~s{C&U}>uLJ^G}Msp4$Qu=|4;p1Q@VhVL1pZ(~? z$p#Fem32FmeZSflE{sA@V>2+$FvR#4a%UZwM6^yk*N%nx;|&gMHb_$R6Otv-XzJob z;!_8VU=uo^Ll|XX&@eyjSe;dYL_4;Vae7DBMk{DzrAOjRB@6^DTg^ta#?^Z58enB7 zSBG@P^eTNQSHu!4qN89|b|RZvQ7s6H;NviKnr;7I6>_o8JCG(^1}T1e|)e zdXv59doaWx1ZcfMm8n49YqdbV%Z&7HuRL|iw3K)Ht(LNdV*@&CRJ`sx^;5-@J;PL% z0BION%KU|5AjFfSjZX5DN6>dK+}1 z27`dm(4LTqX;KnNG$HhA_yOrGPOe(S$b@y@K4hHek-=bj!KzoQFRViZy7h$xpc@1y zy&8r$n8lObZu(J!iwYQM)&-QE2eE4RhwKt($r;~wD6RGzU~7`lN@#J56{!{z!u3^M zarmA&3I75M2|WJ>fE3enD&|d=Oe;m_iY5o1SAz+=+N`f>ESh!oh$Y% zzEU}?W^@?p?-t7-Rx6;g#uvj-fa(H)1>&J{!infb`OpJlY8W`gH<`{4F5r3xzAje{ zpfrz4FIhb^=XbnHv;q-}RL<2q3^S@&YlpmtZ`26YL!%R9<><>zT&b=WdmfU2jX!Pc zNuP&bO|QqGt06i|p1@crh)~~@sIv46L9KWh_RQ|cR)i*dX=zusFzAKR=4te?W(6RP zWr9=M_EO5AX{|I7tuWa+8ED1-#+2YbJnN;M`wjxsvTp`<8G{W1k7E*B6(uXuy6;di zCej0JD>%p!V2A)I>B4J@5P@g~&d~UdGmJPxil81}ysDpFr#?y_sZ3XIF4km5<&v7v zS~M}6n2|CVg|nNNbRMqH^5+h8_9-a1#TeY4Ai@nXDz%kCb&l}j)>@G&6by|Idh_8npSo~l)Y@@{ zw9|%Aht@^=AC3aLWuSg=V+9Vt5Mrq~lJuLyfw}3~xeGJT&xD29>8UHzbLE$&Uk?vm zp1$(($Ub9a6CcRElxJquZAPb^zN5iO8eh9AR~$LuKe&RIpEi{Y}y;s0pGxL!iiE{5D^{5pTFN2v}gwKQjU^rGiLD1sI(Ke z6U)hNvYYOvx&z$;A_duGqMK(V!QazO+)3R{+{!l#?eucyPPUuBn+zUq=jdVoWU`y@ zCdvb7lkX1RMU zImVuD4&`1qgK{69?8onc@_rYQjPdNuc-Ei9to>;gQ!HL$F@s{`H8?(?t(Yy*3;`}! zg{U7@cIBxY2aqB9wB6d`Wv^>ieufxt_Oh>E;`@z0MR46{K8CSI5~F2Zns6{LyC z4`NZ~y$Uj^RuE=5V3@53cw1O_l_4LA@%a}qTsS155XB6`oc=p3H>)ao7!K%)|3P-h zko3X>M83(FqEhh>=gZUg>_@SurGmBG<4p2V-{PYl8X+XS^REgS7a-5SwBIHGkP zO)mrb(tnXN*;QVIMI=r*cqt{e8D_|d!Zav(d??HWUSmN)N`NHbdLCV6CuI-?IPQf1 zG7Ez6ZNyW{>W$^H#Gw3Be0CWHBHD?7`;Z$+CC$Iwck=l{a#*f2@8t5s*+PCeg{KEI z-^~?rxm-RsG`cgF%4J3~8^eI5s17K~opoqDHfUavcd$YD&FwTuJM&LUDXM1d}VeSk0kIBH|P zSa_L!oS;KX8%-6DgWKPQXAZ9ZmXCTYIN-HwMX>;tZb3nXHT7w6BD-Ds$mTr=AqZvg zVk+}6?Z#97Jhm$wokZZnr}Ia}wNt)_+x`*@Mi(RSBJd1fPVHJ*_K(C=2fDg<32^3W zbvYlE^yGcd~-SqABEr8Qa zlh?V3khU|+**iHY2fE3-_~&L0g7dIH`A@Zs*AUc1cH@lhfubYg9txWAfQo9SJml(lM8iQtQV1%TqrAwGH~+p~9*5jjJQ!ux zs7#g1Gd{sPo)?x94nR$z=>;LZ9)ttRn;rO9(8Qlb5$46C3T_tW>38J511*VvVQQh- zhkkwy_kV@RHjGN4uq&BIF#13;m)yt`-PrryC{q}K;l+!R%Fu&toEkBX*!Jx_DvZD1 zX1qOF{k3!=F-iMYg^Vssu-pc1-s~NfHjXj_fl|lB-nRfE4g^Fx!8|~7f;%u#;iU-> z5g#tZ-Ia7bdf-0vZvv@wm%g_a8}J`DD#A(Z>%dJ2Ucgb?oVL@s>9emq-}6R6NU|6F zg4r2)6tl3wvaB_vA1lT+AJK#IrNOm?$dubc4D5v79JMR`Q8evB;*ukDQaDGa<*8!K z`^H8f39}PU8yr!Yw%hKg1J;NL1SvAYY7WB)#&Lu&$n7eX#}=66K!@vN^ncjx+j>eT zBZnY|a?W~7)f;tyoH|D!ja7&kJ+hmA}~JaucP@PycH|Ml8WN@hMDRi>BwQuMiIei7%*h~z*JZycu&tji~=7M zab&n!o2?m}iN$YwMlT}erDqI_Kg1{BTLF8)m}E3ngIjiaf;6;MoA(*RNK~a_K@b{m zGnXDgO2!g@_tSPh{(g}2+esz5`lMD)(bcb$bCCS=2R91j7wWeE0B+r%O+ZCX+@)Aa zZu}mxQxc-!B(-@^Dv}5qr1fm$^f2)3{Maqt0bn;d0zhA_HxP0_WIR(5iZ-K4c8F?? z`Ax*SDeOFXoZ%BaCLEky3kEpxUpl$a1c2DygBivK_WYdn4`I7NU77>k^PbS|^GR*ZP;a!lBe90+!>v>|>BC@JPToqjQ}_%0@m9K> zxt-`j9XW$GFt1YG^j)SKrm8Mx^a?cqic-m<6JD-xIC4BXh%*z?N`6!EYx|uVw7Lim z#F5ITS;ry`q$ZuF0_U35IAViYn8Mqk-gE>nCA%k2+G2EVg;vIeZeblUa|UdnzF>#q zto3TNa|ANS?CI9d9W5NK>(7q0*$ES)k*z4)#*~~eD*|miCkBYJ%rbOm_|E`v{vH(J zu$rebOvW>c8{Fb!8ZBX7`yPTmg!W&>(?1|)QL)GkW}s3O@NYP|v4c1kv;TZ*tDA7! zC>8!qJcTmxD#n_Ma6zXk0YTtKt1rSY3Tdsh0&O?K=Rd~~r)p`pi(Eq4A;2D;aiRqo z4bKV(@~d??>R*_fyX=UW2`hmt7^c+;52bE_2f*w|!tB^Z zbL38@n{rd6e0>Fz1Z}ghGc#XF-A#+>fpqZ1oX?mqz|&}vpoH`dX={JS0;M?>3L1sh z^?@!RIJ@2$ZEs=4II^`cBcSUGtA`S;e2>JNS_grNXeiRL@rv54D$N%x+o?ppZVB>B zR+6Mv>6|1A3^kHCF=GgHfAXCP^Je{F`bO2?7(8ySLDCOn*OeC{vJEoJNGKMae>|;B zg50W)%#oYnu=b#e1E-&sKZ>DJAjp6U{%Ag*9EFLn@c=Pk8yApIuR#w+0D#s|@H@Bw zP2aIJtu#`KdWczL2)sx)>gl+Q2Uw;+J0L!ta%X|6?J&=ggf#A^9*l&0&GVQQE}INr zD6IOX)|Lg%ha-gmMq-V5GmA?2*inUgji-Q}l&f8|LF3+5mS8V(Owb`RQBfjX%?K*J zPDd1P9i42wI*rPkHuI<1%BVR|f8J}adGO6etAnDeQYx!af~MUPuAEINf#9%aCSc_6 zioJ6yB(qr$j(-ra+KMBDhqRuc=39=haR-rw96Ud?@i5V3`=(*uL{xgz2zDkD5eBjk z70oi>eT7FNc?Y@3cWGs2syGpnxFRXzK@_fmR!q$Ff?8D|A4yr{L^4y(;Fx$j?Uosj zv&eRMrKnq5-BVeg;NsHf800nc)bUaY5pB7lkxdq7xTN>V`0OwyQVVp7fJ?Q;gwHrl z7+1lKMQ{-vTd}j<3UKeUPiN-Fvm4psQhTMbk>MYdH&M?OZ|Zv(6}&%>1ekyh8SN$T ze+0YT#{t6q@M%K9)j+me>pe(7lhNlP;R~84Y}0mIb|8)}uzYx_=x>4o_*KC4wIz@a zxIvVFL|skiWE7Df21+nda1r2i6JeLY?cs7jP9}QW&2VWLws0&0DG-t{fM|^fVMt1i z5h^zkFH~F~J^-YQK_vtPI!$GlMHXlzZN|a5Ody5qwNB0m-5280h4u{lxOntv#F5UaK<)(4P-5w^^aB4)03HE?*N8A%88umX;kaQ2 zg`tf>G6T6Qhb^`z`6Cz;ff+#x+6O?66x@~!%<8+`y1H!o-+`f{j6V9{cD+c>l+6@BN%OMP4B_ni_@^HXO7J z)PJ0#4d@u(y{v@(dX_`(MMDTNnq)vTiCn9j=t9-OX)ZaDQoV@=S0rs6co*d}zo`^b zdorg2IU}q*#^#F-&QKu(GQ!EKzt~Y(`zG(6dJkwuJLLthV-k(ARteHGhlZ|-9*VIm zjp5T26lW!=?NfTzl#J`2bW!EwLlZR<5F^@>B(r0En+0PBBr1}cVoQy@ceYg!S8sKG ziG8S|)%H>}dcDb!WvDwzbW>EI3FoXi357^Fl5uo=0m_Ebkx0tSGv%Ic8pp;jw;M*X zRMaK|B)0jcfjA)pm+i)48WHvgrI8cjWtO10-Cs%>IsIVqV$-`c_9FQM=}4q}s0d&- z#40#64K~pgWihH}c$0sxL2q|FDB7)@Wmsqy9&0#i>7qmMMijW7af};=u-_h=h%QK7 z0uIh2+8_4>MS?Ica8DL(CL{Mk9E26+GX_D4wWKFww8^;N{s@46+-91XSjL{}bR-{^wZGb)yPKA;Vp!WpqOF8N=7d z4sGlsU*Fv1-u`w`LchVQNVt8&V#U>W*9Gn*wR>>s0%bJGk-SUdcy{Zc6Dt=GPy^3E z6YDCk)=cGH-JMaks{?WHaV|Bdh-piSwgad9{Ade;*UcUjvKza(2Yt`O3=bNKjwNR~ z!$Fdyoa4N=f1zExLPkTj%1l#}Tyaoau4T$9NqsT7B=?4xEuq`h=r=Jxj1}@)qzw*3 zL(Yh>%){`evn>VpT2@?b**i%@{}Ojow{l&a+lD}W7%sUq@7+$XKIEov<=W{k;($0q zdAOZ*aYhfJ-mIH@E78rJLu?1nbJAnL&EMwO16`a0$2iZ)-9e6XE2HmSaSPqtjii6s z9m2hVI|FXvZZer@rrcp%=eh%z5|~F~Ip0k#U|!u^J=x9vV)Dn6xANUgH_xn!<-(l- z=3XE(BaQbY{mT}(oKCi@fDS&L07_1H-&SG zMp+o0@qZQ@h0vLtk>%mv^z+km8?R52SV6z~zGKrRoCauwmKOYrP?i`ohEk{xWK1~E zK~xn*VjL+Ji^oj=XWn@1@}=3i$F7d|AUhC7)B?onk^wzzOHc}~<`{~lNBk#K*J0oY z;bCIg&MHzaa9A}}JQ-$yTPyu^Id}%L8^=smpS@{NaZh67aiSuKUJ})bfyFa)nlyrE zi?)3@#+W)YO3Ql1YV0q|=3Kfwhy1A7x$_(6NV<{D3awQvD)2ng^(!#KTcCG|pVRq&O?T z%I2e%f+(?qFpYqyzl-t@C=4|oW2us?BCeo z`1Vz}w~VFd2lI%K4kz>3F_=5d#K^oeni)&yGbuPYGw{qfB#= zjwBE2aH{z+r-ciDjXqVmtKA<~8cH8ybLsCv>}L5 zU}fMP3C1Vv3n(TXZLd4Q8xs@9PhE{H9IXj*7AhH7=?2h+WMbOGvgKO(-k{!N(O&iM zS(xn*CKvp}#7Cy!^e_m(Mi|6y0uje^6Q52lgGGEAHp6FOIq+2b+dRvz+<1uf5RdwH z1yQ?SMbEcW(nyho2y~IEMjlPj0#$h|nAPT_Iqxq{EU+}ip zBWis94_L@+|2}K-?pRWv!0*eXEY4tTER#_pv~LFTu6qX|Ea!B#;(6(5D5VB$w?C}& zcZ!>*+(r-pO!7;uLc}an5Qyou@y#od-L(yx;}9B7n9<6HivSLOeHJuQQ(FY#)KXxKylp^@gei*ZnqLIX><@ z<(%5|W)388e-B2&3{Gw}gV-#@1JpMSwd?`|@1>Z?nnYAucAvojuHz^YQ;49}7dX991~oe*)V2{}2y1p6KDD z>~udaYG>q2O$Pl(d`BPW9IYU8{2 zVT`ht@0%^M*Vat&|3fsfEHle#2mY@U6u)8N5yAX7aW4cEzK!3+zTu6%oA@IK*jA@g zQIlT&sPDZihy0E2Re!5)(%^J($q>x<%r5)-{h4u2N10C+x7B-kxTixe7jm>ZFp;<5 zo>s9t?HqNQ5sUe=!L9qR+cK9QkQ>p<{e5twUR6&`ZCieH&+?;Qy-szzA4jsY@};&d zM~ZYgHRc~$p0sO|E~i@bsBzEB_o2R5zEs@{q`wbqQZKN&Hv&Z8pYEpm|9P^hz8UtB z&<~DEmSYX5H{6G3{TA?z`mz5n@plW2P7UBciKjhGh%C;k)nmAzQhf(53-QXRY~QcN zVj0Z0HY|qjcepoeaB|T(%CH@+!0HweYh-5d+=k?2wcz>C*`Tqe42hX0IOU`hGvHJ} zW4nVUS&u$dIiF#BiQk3^ozZaui4)RgK?l#&#S3;6e!Bx9ba;E9XQ?5p(YdwN4%77Q zz>J~Blzs3X2KCf=OoW~`lqNd6SHNO?EX?m^(h>(%&xJf}fZ49lq;uGXNEgO~5lQoy(_p_XK=hjHUoYZ- z@~x&DtvWvGgA6xu)kS$@%ys~pYi=LRxt0LYa z0T3r~;)yg{N&gSo8Nt>6L*Qaz4wwhhg`dR3rLqu2+*vg*+-+VNJ6JXfUMR}<@FQ@W zh+(`%EB^_Mxh)&@|1F*(`}tKP)5tUBq?#ohgaMeI4Ae5bG=|n&EwDG3ag|H@cPxIJ zMc=yiZ*wZ{q+MGcYm*$WZCZv&FC3gU2qdwSdxLb9%h}I+55r?4UfmY}W}MNR>Wy;r zxNU|oL7Oi48C)2Aaf@<=+wsm)sjp83Q$&vgr_ zL=yRF>UTDA{rL5VuOAXuQM!t6yh8I}vX5{#6)^+zS7fh=T4Dm?1=pFFw9F;^F0rY| zu(rV~o6t|G1lY^hI_fncA!L={8)7{}_cgG%yv=y@$D5f*O5+wo#@g87bX$=mJQzqJ z0)~c&b-gV?Dl;jF7BZg&(tcz{%=mu+;2Y0|`^!8}jX5X>ei=vrDd&1&hNqLmU9x%R z{3brW>ea#loPF|JIQ;l^4l$%?@^?^Iak)V|SeTKKvb6StFj*5XXE>y1#;;ZIEGAAz z={xetyFMw)**gW9xUS|I&%!)R!*t*rD+MCnS2nPNqWcB496};^K@OQd*KXaFmK^I6QujEDzkfi!&|!bYJ#o>G0AAqu(CHmY(@b~&-*Y~*@AW(MWKVN9_W6g?U2`Q5_Xm?+I z$ipUMSm*ZF-#Wa%san$LY~JwHHqrGKBD4@u;An4d2Pv94EM$oCMA(WvO;kF zMOcBPfe=!D$fCyH88WO*`~hc8nBX28E%*X)fI;NU0P{QcNq$EGiXpza@rlfzDxR@L zKR=H?HBQ|85G{z0f*K7}0AK?5@U6@S^PI>X_&tW~Yl-Hb3@o4ZN0Z2lN+$3WsX?zL zUMDi;-ppOcaY_DNORgoD&js7%Xg5o{1vX0>+GFZY`mUr(L#ur6C&70AxN&I@Qb-N``28lXp;#HQ07XbzEX*89ma=l2euVl zt1A!ZC6J&b$3zGI=*v?>t371aaO|*hqEi`Uc~Wy)AMZ#f<+T=m9AuZ{Uwmj^9EJDU&cA`L)>b zftXZ}==r~}QOdvJi-Fk7!NYxObwbTCH24|``Vcx6cBYV&HJThtXS_8Ses^Xp2hPl5Brj+ zCu1e$D-+c%QpKX^;~vdo{NDI_tVJk-U)~GgWJRZPqrTuVNxS^O4@f6wASu=uYmzQN)TSWvn3{}+q@jUpV;pB$_4 z|NYUQ9XrXV3oK5tcp3#)7yJ^6LL!sQEM>BpvCPo$@PT}8km_;nyTjm~!+SEhOl~+g zoX^95mcpIhe`9}~_~Al6H4OD>48MnllZCO#DEpr@O7PWPJmH z!t)%5p!OGz**03CQnF4Ei1-v9unp9I8-(K&$`}+&CLFbop^o9jf?ER2|H0n;xKmsC zI)p@a@@5+Jqo`?s&LHH)ivFxV>@dPF>J{}-17G1hm0kY;yB2gt2FOazaw}rZ<2*%O(m!1(qIYiK~QTb2=1cZ34H={W~(Vh0`P6i>4t8N{pxArjI@m_MUf-m~x&B!Uu(;RFdlWr`0Y2OPh>|2E%= aJp* literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/blueprints.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e4d57c73977e7fe6957ae31eb020a4d3cb4a9ec GIT binary patch literal 22932 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 JN`C6C{|9?%xorRd literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/flask/sansio/__pycache__/scaffold.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e01263e881cdf240c3a5c87f94603d0f0638459b GIT binary patch literal 24084 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/flask/sansio/app.py b/website/.venv/lib/python3.10/site-packages/flask/sansio/app.py new file mode 100644 index 0000000..21a79ba --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/sansio/app.py @@ -0,0 +1,968 @@ +from __future__ import annotations + +import logging +import os +import sys +import typing as t +from datetime import timedelta +from itertools import chain + +from werkzeug.exceptions import Aborter +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.routing import BuildError +from werkzeug.routing import Map +from werkzeug.routing import Rule +from werkzeug.sansio.response import Response +from werkzeug.utils import cached_property +from werkzeug.utils import redirect as _wz_redirect + +from .. import typing as ft +from ..config import Config +from ..config import ConfigAttribute +from ..ctx import _AppCtxGlobals +from ..helpers import _split_blueprint_path +from ..helpers import get_debug_flag +from ..json.provider import DefaultJSONProvider +from ..json.provider import JSONProvider +from ..logging import create_logger +from ..templating import DispatchingJinjaLoader +from ..templating import Environment +from .scaffold import _endpoint_from_view_func +from .scaffold import find_package +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.wrappers import Response as BaseResponse + + from ..testing import FlaskClient + from ..testing import FlaskCliRunner + from .blueprints import Blueprint + +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 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[bool]("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[t.Union[str, bytes, None]]("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[timedelta]( + "PERMANENT_SESSION_LIFETIME", + get_converter=_make_timedelta, # type: ignore[arg-type] + ) + + 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[str, t.Any] = {} + + #: 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[str, t.Any] + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | 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[str, t.Any] = {} + + #: 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: str | None = 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"] # type: ignore[no-any-return] + + @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_obj = self.url_rule_class(rule, methods=methods, **options) + rule_obj.provide_automatic_options = provide_automatic_options # type: ignore[attr-defined] + + self.url_map.add(rule_obj) + 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[str, t.Any]) -> 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/website/.venv/lib/python3.10/site-packages/flask/sansio/blueprints.py b/website/.venv/lib/python3.10/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..4f912cc --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,632 @@ +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"], None] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any]) +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: ft.RouteCallable | 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[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore[assignment] + ): + 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[str, t.Any]]] = [] + + 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: DeferredSetupFunction) -> 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: DeferredSetupFunction) -> 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[str, t.Any], 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[str, t.Any]) -> 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: dict[ft.AppOrBlueprintKey, list[t.Any]], + parent_dict: dict[ft.AppOrBlueprintKey, list[t.Any]], + ) -> None: + 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: + def from_blueprint(state: BlueprintSetupState) -> None: + state.app.errorhandler(code)(f) + + self.record_once(from_blueprint) + 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/website/.venv/lib/python3.10/site-packages/flask/sansio/scaffold.py b/website/.venv/lib/python3.10/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..5355700 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,805 @@ +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 + +import click +from jinja2 import BaseLoader +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.Any]) +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: Scaffold, *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[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | 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: click.Group = 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, ft.RouteCallable] = {} + + #: 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[t.Any]] + ] = 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[str] | 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) -> BaseLoader | 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[str, t.Any], + ) -> 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: ft.RouteCallable) -> 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: str) -> str: + """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.submodule_search_locations: + if root_spec.origin is None or root_spec.origin == "namespace": + # 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) + else: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) # type: ignore[type-var, return-value] + + +def find_package(import_name: str) -> tuple[str | None, 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/website/.venv/lib/python3.10/site-packages/flask/sessions.py b/website/.venv/lib/python3.10/site-packages/flask/sessions.py new file mode 100644 index 0000000..bb753eb --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/sessions.py @@ -0,0 +1,371 @@ +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 + import typing_extensions as te + + from .app import Flask + from .wrappers import Request + from .wrappers import Response + + +# TODO generic when Python > 3.8 +class SessionMixin(MutableMapping): # type: ignore[type-arg] + """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 + + +# TODO generic when Python > 3.8 +class SecureCookieSession(CallbackDict, SessionMixin): # type: ignore[type-arg] + """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: te.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"] # type: ignore[no-any-return] + + 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``. + """ + return app.config["SESSION_COOKIE_DOMAIN"] # type: ignore[no-any-return] + + 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"] # type: ignore[no-any-return] + + 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"] # type: ignore[no-any-return] + + 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"] # type: ignore[no-any-return] + + def get_cookie_samesite(self, app: Flask) -> str | None: + """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"] # type: ignore[no-any-return] + + 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/website/.venv/lib/python3.10/site-packages/flask/signals.py b/website/.venv/lib/python3.10/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/flask/templating.py b/website/.venv/lib/python3.10/site-packages/flask/templating.py new file mode 100644 index 0000000..618a3b3 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/templating.py @@ -0,0 +1,219 @@ +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( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | 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: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | 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: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | 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.Iterator[tuple[Scaffold, BaseLoader]]: + 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/website/.venv/lib/python3.10/site-packages/flask/testing.py b/website/.venv/lib/python3.10/site-packages/flask/testing.py new file mode 100644 index 0000000..a27b7c8 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/testing.py @@ -0,0 +1,298 @@ +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 _typeshed.wsgi import WSGIEnvironment + 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.Iterator[SessionMixin]: + """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: WSGIEnvironment) -> WSGIEnvironment: + 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: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> BaseRequest: + 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 {}) # type: ignore[arg-type] + 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 + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/website/.venv/lib/python3.10/site-packages/flask/typing.py b/website/.venv/lib/python3.10/site-packages/flask/typing.py new file mode 100644 index 0000000..cf6d4ae --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/typing.py @@ -0,0 +1,90 @@ +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, t.Dict[str, t.Any]], None] +URLValuePreprocessorCallable = t.Callable[ + [t.Optional[str], t.Optional[t.Dict[str, t.Any]]], 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/website/.venv/lib/python3.10/site-packages/flask/views.py b/website/.venv/lib/python3.10/site-packages/flask/views.py new file mode 100644 index 0000000..794fdc0 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/views.py @@ -0,0 +1,191 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +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[[F], F]]] = [] + + #: 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) # type: ignore[no-any-return] + + else: + self = cls(*class_args, **class_kwargs) + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return] + + 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) # type: ignore[no-any-return] diff --git a/website/.venv/lib/python3.10/site-packages/flask/wrappers.py b/website/.venv/lib/python3.10/site-packages/flask/wrappers.py new file mode 100644 index 0000000..c1eca80 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/flask/wrappers.py @@ -0,0 +1,174 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import HTTPException +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: HTTPException | None = None + + @property + def max_content_length(self) -> int | None: # type: ignore[override] + """Read-only view of the ``MAX_CONTENT_LENGTH`` config key.""" + if current_app: + return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] + 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"] # type: ignore[no-any-return] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA new file mode 100644 index 0000000..1d935ed --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD new file mode 100644 index 0000000..2a39531 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..e163955 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +itsdangerous diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/__init__.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..fdb2dfd --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e87af21d419d9f47651b39a40da749f11d9be551 GIT binary patch literal 864 zcmaKqy^qr{7{-&PNz*jx=UqX}EFEa>j*kf;jsxiiI3da{UM#mZt%Z|Rw%fbjf5iX8 z)Rl>efsKjxwN6#bK%zYQJaxy zl@)E$cANrtNXKyo+$CMdZPhFKr0=)`JRk$dU3F9(lVis{;2{|T_sIi3n0TY3pFSLI zq0@x7OpExom8 zKSK*%{2G3YclG4SgSVcX$%?Gvz)a>}X683<>YbfF0XqEoLw}`&d_!ZCI2Z@O_AUrT z6kU)J?Y?ZpUlPR>za)xZuu-7s5y^t@kVl3E%1!ElaR6-Jg3w)!5mR);b)c9I=aKH| zc*5>LEwHvGfeKW38C=j&A2K5Jsa_|!?oA>UtF11&t@_Y)+b80%UN*9Dua4df&mMg+ zvT3wQrK#IWrE^9SVsLZ@yfU22^v8=IcaN~bOSrU$;)$kn2j%11`K)>H+o;}4;Z zt2hLs%>66t7J9RfW+oqmqD{K5fqMrEd$YKXS5O`@88h@O>fH4-0xC#K%@Hen)yjsJcM6b<&l^Qp1Lo zXTtgLeO1D1aX14Xj#qF4oUoA<~8aSJB5$*Rwyv`|4oFB&NIk7q~{2!3rro@-O+ysV5G5+XKsco>rTJknqU%o9E~E@q5oNt<@?7#`cRp#V-Xy z{=lEfQHGySU@8L(C!EHllkc=c?LX@(AUyb%Ha^XMj@^^r-%vz&ib$@Y&y-@eFTV z($1`4;|8AtYEH}@&36`rJ6`1TK;OA!oh7~?majE0@;jhsg)fORaF)T=GG77CDyNT0 zbL|S^BRf|V)+RN@M^h>S;rjDT$<)@+j#WPe_?cWjrZ#CX=3n zDy|38F3fG1Y6TWe&WNTLOirDVF*~DY?2?@W4{Xz&rei9RiV~&6q$i96)<8Sj5lu&W za9tL0DZ%nPku}&}?zIooW6@Tj>K%sdp1Qx$J{4URY0++-h~%UlN8R>ds1MWRgVw!` zHlC~x!rl*IU#NDZ6%UiXkZGpcHxac4LsK~o6CHGiTBs>7qtJN8sZy88X&`eXl70_? zx*14gz&6+=ATZbqdJX|YsN|B49ZoM1W;Xi%QK-b$rk_XWhdv^k^!@a}w?_R``dU2I zEr0h=_)@4W)_9&DhEh~~7%DsvzE1s22|r5wy|2GeEqm|+eRX1sV# zf261Mlr&4DFR$U_0*eFSgV5J48vg@FKT;MXi)D_NDM0;1k@2E_l1kBJuM17iLMT@l z_GtC<NQ*gH~wiC-zFd0nCxJ9z2kXNU?`sjqV1zwH?NB*p0=L zCpO^y_kCdQW&_|viQeBgPLdtp%H*v=#zM#oc}#E0cgNNjxNK?x=m>P0KNaJ}H|6vu zT>EDr)k)cVAfT{j>Qvr^%@nPBTK>xwXvld{VF98m=m>|#aY4DWjIG1nxx$_xeO%Cc z>zUPuzJXa&kVl!)Q0H%>47QGmIiqWC@s}1%%gSMa2DOa0srO8T>t<8 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/exc.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..471b58e2e8a403894f0f259af810fc1c72c26a9f GIT binary patch literal 3407 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 bWR#J*Et&eSiWF{z6F3*Yr_57@HRpc;go$eS literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/signer.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/signer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b7b2d31ae409f66fc86f15ffbeeb203c50bb8f0 GIT binary patch literal 8459 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 a5nPto4UsD%C$w%>?3I<3g{y0;rT+&Q{djNy literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/timed.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5419e3767bf79e7c3a4d6bcc5c694ed238c1dd65 GIT binary patch literal 6473 zcmdT|%X8bt8OMtt2tGtnvTP@If;P>AorH4I*Hm@WB#xc9N#xX$>xQWZg1AeWGDt8B zP_|Gg?bx2?u-~3-sD$3uea_})wc?JLQa}-Qrs;{)Ox7t=^U2SW4Yrfvs+qz2M zbkIiI0Bx{>U+9}{Q_?2rV!J5mB512^N!kKkYL_Hk0&TZ#N!xz8Uujn)T?SokS0!Bm zU2E4QUG?Ys^>$s-HGjU}Xg5@aYugKakss-5$CdUHYDf7JsAG~k4(c&bj|*R}|3v%b z8w#6a_1g-o^TsW`{RHastbuxi*HM3xscTAe;ZsOJS#7GR#k`0|y*?+J-f=MCpQ`wZ zhU%sl^6!4zWxNwG;>a8LVBApI+>LnXMuFQKL|~}kMK#%sx_#Y4Ltd-A=CQTj*1(HK zf`+T3zK%H$wM{B#Zwz~aGa6-$i=OBAVlGfKiGzy{ZQrCTD zS7SOeZX4|aD{uoXX4haQE25>yEN-Etgq9Ms(PH!RcBND#kU%-l29d&CB<2| zrM7Eht_Akk0j@=G&286t2{Yixx)wVE@k{>M5&692Z5-ssDrB#Zl&;E_(6idEvBxLl zYkaSJp#Fyf@f#ya97M-oV-9&M4%}i2{eq zQ*wwy9&6Zg)~{xrSNc4MeJ|@0?n`&Nste#Ftw;e6X|Z_coV@yO7)9 zTdfyQEz_45hF<5Ix5dNdUKBEKfZ2jkxJ<*d)^IniZgH4kzUr^hUNsaIBR;vFw`Pam zI>ec3QP?5Q{2`iLrW98lM5Ju1i5h9!I#cgx5SivVkm;FVu)_r;1vQ(@>vToXcg7lU zXdWEz0D5ykX5MvAKpUiHZsh)`l@rA8Tv|WVvL`}rwH(YC;us({2!O4uI4`wMO}>-d zp@auk1O3R(3L4~vjwe5nt9v1vd}A{2#>Syxvbi1MVRr&sgz|gN!0YXB=U^WU8jf%P zWDzh9xm;QWJvekNikpTYfu>aw%tTB=r#5{Qb()%304vb^FUogyRvP7(i1h& zk1C0FRM~?*NLsmDNYs7xs3Hw%h4d>kqb*2k;DnLL-G}rwUKDwqs~jxQNStps5Pgr# zs?{__35yUW6&4jsC{jJ-!%VX$js^mi0y{z9OOySIlhkQOfClw?5g$TA2$oh?ZMC8{ z)Oc}LZp65HF0Ig;GgrzhE%v<|E=(@1XG%0Ruejkxy!AHBQh5IR=dd|`r91Q2bZ%hM*m|q z;u|#A(~}9GnNV_mQanK_c9w|eP#oG<4Gknq(%TMdth@&dwr7554hq@(x_VuS45%5x>xDBFu?VmPa_|8^wdvAU`38 z&0M>5&}Ev%6yebCMWRRy1!^gsz0u)AiUi_us@p%MfOS@gK%~VBYZ+0!fau@#gX>vU zhvvyBAqdkoYgt%0>{AI3h9f^pOW2c(g<(9EXR$&C5Gx9^G$l1b5nwCe&7xEXNKJL@ z`<|MXTvzI~>rR8S+~O)G4!2Qg^@?h#HPuj;RO?sTL));525J?puF+dV=&8{AkyWr% z4V;UrrsK;aP17Et#}|#FWnc^)e@#>C;IUNm3(M3HvNGB*F}~Iz&znC)Q?NXPe@F)y z+wh_YADaz?IeSxE#YC&?GQc&Dq?YRrygql`)OOu|z(zjN71#Y>KfH*-QVg|bHq3@?lr=+B zjn7GUG+p}wwa>Le<$+;+xxIpRtvt)URH!|0ekN%A4*rK8GEsWMKcL9-=}QRNZJi^J z=H_;h8^;yOolh$z9r>}rOUSOxZJXM=hRk6p$F8=^CB0;UXP%XKh1tlb%e*$>pX=JJ z!m7w=>)_K_W5Sh>IL~VscW#_f*Vr6*8#4c0K$u&|@?SQ+CWtRw3IQ*3Z$G0Ylv0Ed z_gEf881H)U4pN)*K6!>bPAF?*p3EtVRU~qr9|_8f4&iA+Xaru#BttsJ2%v}oO9LDM zIq$3cGILsuPqj%!yk}N>+n$LQZ<~y&ki}_{2?8nzjQ3W1CeJ3fItPn6acY(^>yXS z%AOgY1hmtn%fVgC9UZ`|xJOV%Pl|w6r9>CcB&EdaYL^uaU0HOTCmZ#L z;l}gG;Be&tjmYjC4qik-8>aUSl(0?x*w~xEROR&p?lyo|JRp;CLXZKKp$K+*3}Lhv zIRru`PLU5nTy#myG#wKTaS%jK;IllTL{^#IGZ6L|M^(%;y;Oh_e8niiD55CMp3gV6 zmiyo7MM^kXi`+kJIj;gFd14F6>VP~nmIn*~h(zm0@|yc`E}otC9gFhA87-Ya#_VQi zdgrma4(*)eGfgXt`=phbJFJkGbaOC5PCdg2r1Ihdie@PU6et*ZjAvvH$Gd}T^YaTOZQBhw#w~83K z+FTSbqm%d%6|Ye7DistI#5+`Eu4sLC$kRF3^#;&inXQKiq4jaBo5n^f_i93(_-i!6 zIV#ShNcC3-yW%oc-=v~V#amQNH#UuXZ{x$C@ef}|VI%G}44|b)8sR6c_K@Nkj_$$X z_@_NEO#3tKx!G7(D>NPm8nNk!23~>&m3zy=JbCQYl2_XZ=Ms-**APYGlXnsFYU2A; zm6(=1qXeC)9ZqhjMU`6Dsi;x$V=7*vf^u27rA8ziE%y8hm~XWcVz zo;~x{`PDbl`3zb>+avfAxS=rBk>O`YLt8l@wW&^6r!#=_G9mM@g~C!Sz{m>ypxd** Snq~uBnwq87b>)|fNB;xty@V40 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/itsdangerous/__pycache__/url_safe.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..086aff3a1f91eca049e7f602c2641d97d4664762 GIT binary patch literal 2692 zcmbVOOOG2x5bmD$&f4C*$ctA?C?qS0osfVaAe0a#2oyFbn<$bmv*YRZ?(B|dOm{mQ zTV90NpqxPb01g|3kn%6MaN`%ul~Ya}_7*~*s_l)fWWyn2bxn0uPj&ZKUst=RRzm{M z#qGaDYle_Nu`~U+&^ZrH{Rn~+PBYS^=4~}CZgD%aJ5JM~1av2JJ6_W>x(mAB^o{Oi zL1(5pV{|_YJG0GMqX$`~Q*Bl$`IPV(9^N556tkOlvj+WHUV(l^)WG62=fG0sHL%pc zQU%K%P8Z4i+yht@S$IG}&eO6IT`W4?IMJUkUR{8GwG}Jz-r0zYq~K!8Ao8&x{3PaI z#{H~_Ik>|`A=5ZZ2SP$`?t0o0d}2y)uIXoX+)-^%guw+cp-o#jO&78GiE>AH+!g+6 zz&(&Ns2w5PH=g`kinAxbW$kA z^on3g%QRm`eKKGrdMq zGIV~SKOmulh0EKx{<_57TpxURvFK%-<%MQrWJg>!$c`}q5RAFkWtG0E`&><^#x!j-^(}GU>o7%b80% zQ%Vo}4#qCSN$}EDy{?dD1D%Y9t5 z<6fqtse0nJ`dX;cigamT$opk*)f|~PGb}KxEvsYBB_hipmf4FDW@~0waAOiAtzsYo z0{d|-&wFH9)?){#5<1o+u>9?KwTFyJ9R18Cf~WmFwCz10rY{k0LEh|g?=yTF{C2aD zYl>wlROWN$Se#p`Pp*R{*6L}7uqmhqoFVfR+zU|5O@%cD7D>NT<&z>;snU4Tp@d-h z?{(q0jz3-(GJ$K9!C8}VwSs*#$b^Zr?n>Men#GE(15Wr}S~?ybUs`$_m6M>DIH1=- zA6NJLjywk2m2aXrj^YH03B(iPoC3!sXxmt70uoS(mgmAK8{h@lc5cb1?(o6yyJ7d# zp#KBV>>5&HF0dB|(1byxUl2ff8n(GBUT45@1)cApz~21c($oDeq*uO$HgnG12#f3J zfCT2YMn7U~&U|UZHDapys51NDC|!+zh$P;vhRY@sW{TZbQU)K5j_1cnafQ_t(^r9l Ny7Sv(@B84O{~rw7$jATy literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/_json.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/_json.py new file mode 100644 index 0000000..c70d37a --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/encoding.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..edb04d1 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/exc.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..c38a6af --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/py.typed b/website/.venv/lib/python3.10/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/website/.venv/lib/python3.10/site-packages/itsdangerous/serializer.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..9f4a84a --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/signer.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..aa12005 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/timed.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..cad8da3 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/itsdangerous/url_safe.py b/website/.venv/lib/python3.10/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..d5a9b0c --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/jinja2/__init__.py b/website/.venv/lib/python3.10/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..af5d428 --- /dev/null +++ b/website/.venv/lib/python3.10/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.3" diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..28f70a9514e8c8ca6aa72b0394bbea06111a6a9a GIT binary patch literal 1600 zcmbW1O>f&a7{}$rj%`_fckH}JN!krL)aq93HVj+R2H4Pa!Lk7bF9I#GHd~1lNZPe~ z+HGH9UtwR#*PV9SVYi+3Jj`T!Jx+%I`0>w&I2FEX@*Xn9szR3+BI9+!!W&F8pk&n18o06DfxNx5m$uobi~!C|5}F z3#FvOrSqQLXywK$X>R0H#1PcWy&tB+@Ra4T?cCQJ!QI@vw}+L-HhvN@djkg*=ZGQ~HjDi5x@Cj6*n-hn+xd^WG>(bThcR+3=!-Q5D)Z zrg58G|7X0HQLV#B3d80G`dhZWQ6=EDAG{e&HUit4B`h)_of^q>L^JlG^lbRq@Y$=& zPnYE|jAayt%kn6)ODnvS)HX^HWLeu-L6y+nLEB~Xh}ojm3T`$>RZyxZc;%@Yiic7M zS(X#~_OxoC)kJBbv{5=JU6dZmF37U19tueH(Hfxaq3oj^fGkT>!xOCz(KtdmMma$_ zMe#wFwJ@A9g`Zj&{^qDl>_GYZ`(Pqd7HF!Y2@N9s#na$D8)Fr2}bgM^QQ%zol< xR!;-$d6GR8i4NZ4HSu{6hFowHhQn;JtbCc;lKKk2RDA_fbiATh`2WAk);|imy;}eP literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/_identifier.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/_identifier.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..339509f4ecf57b3cc994ed22035366125a16130f GIT binary patch literal 2075 zcmYk7&2JmW8OABQMT`Qu_J0V9G1C@BFGW$H_a53?nxarFwpMCOf~6$LZTU@$+K4OJ zq$r8xip#Iv|dH{qI`ryWU%yz4hMCNG~$d%cP$n7^F85+N7HZ z4qcQPU7V3|%*ePP!(h}%QsWvSpvIh0^N^YvLW!DnY8upvGioKN6;KP+c8c0rYUik( z$3&%eiQ08)8`Pdt2hL8CIstXyG!tZI$;^=nr>T;uk=Y}&Pv(#;IISdE0aR>`iDZIF$g>;-k@gn2#GLKggbRMrGG0O@<7$ncA2ELZf}al%d|o-?m1ABR@QTN)KI64xUaN3D&$zDgdYacW zyl(P_&UnM-jUK|3cS?+R&baxKakI)z)XadJ3vQuo&3IQ~yqn@(tmdS+gN7ZCUm|&# z;FlK&4tHCOyB_Z~81Id_S76*b;@%5{4)+}Hp*PRx-WcJEkMZajVT!O=DvM=YS;k*1 zlLfX+o-dOZ%VZO(w@jTZQf&eob|+6U+4*;XM~;?y1|6r7Ij6`rhKc zPYRh-TM9qa(rEy1+6%RetY%Qnco10yJeT4i)N);j+!)M5EnmYVZ-v@{eBdAnrXT=w zB-9khf*i=pgbGTa4h+ze$u5w6spz6GgwW82Rt>cynLWm;MHiwt1oA{B^iw(ql~6m8 zmNF8jHpD6VIGSa}YOyKxa*~fGg z7HxE2wEeKym7fVHCq^GX>Gyf2ZRc^-j;afB4Y{_ut%m7JKvFqwS|Vn@=Ei*7x>e&$i6Sv+v`- z^?$>^e;a+g{WKQcUEh85cs=@P_h%nQzleRZySW#OKKwkk^?CHk<|omeFZUjAZ~gS) zk3Wpc3fozK^q2KN$9AKiZfvb-gRfj zNfS9zqXs2C6vP)miNvK}fh!+@+gv&I#DQB6E$_`HvE8ZyCo}uz?VGpre((3*#KmHc z!0-A$e~X{9g#3kz{vYVbXE4<7Fmb|Zlhl$Ytua`$rqgn3E=8RKa;laB+2yHbx|OMA zteghft9g_Nc97+nLt4vmk7svDEiVe9D2Bwa7!jkQB*r*>OxL{HIL`^zI0a*ZXQl|x ztT34K@N{{B7kAy-JK3S^a5kSE;ivd0FM(!~=lC$s!=5SJ1D0ca9Q3C-T_EL&=Wu>9 zU#4d4&h5Edw{G0_=N1-jel`Eyjrqj|P^UIz&{oeWSi#EkZv{%t$yJa?+aUU4J!ty% zIMU*wHgu_uhQ~h!f^#&~2nc&*g>uT-uD4CQ_<3i3U_%OQ(lEwgs9#~y5wO^OEqb*4v|xwYNz3Hrc)4;!`)r?35{|C+Ek+D>20RdI-|YE^dQ@1hk)j`qjURC z*WsC`3?$NJi2YM%kL=Msw&#G)9MA8<4zP9infylQyDrMS&~<$naQx!DaRa%kOj-)v zkwye|NLQ{l<9g6k*D74pV;SgJ z_Eg8Ge0$*I;1jdh3%ucC=o0IzoRWEX$O2A9m`omG2xT0#M5OJ(TC;n7Eg&NdXCEq z)MZ0-h;3c^|A{>Evsf-llWZd%O<%UG&+AJAoF4|18l+vAcQy51HEinZq$HSEs zAw^Ud5|NWw#b(U%E#a|$L?=l3X?*9|?g1c}kzV+IptV#Ge=pcXCEtTRPzvwDqwH7@ z2|K1iAuSZy6M7<%6k6t}M{{g~ji=m938Vs@pl;ryY39k_Uw=pjiOxFUY;riFO)wfS$?vKENiV?{5v9 z;s{5_WYz+O{OrL74dfEW>cYO(TVO($cu;%)u}3*)5=fbT4$%O-@6HV=4EQbl2zF8y4OPg=I?ucCmo4gD!Ud? zIg4AdY~*FsPRon%Fliui7_BDFD2ts?!&Rwl2eMtqr0kt$J6O_zGK;|dr9j%+NQ%-4 zBW+SE%{b6WGjo)d#>Hri%fq^sXYj)x;&cH&o3iXR*^{!e1h+97_gmOzkKPw)uT;FN m$)$7+)2gtCc*LUx{IliaIg=O8IxNp9d&OApWg>ZO=;go34s-qh literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/bccache.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20ff14c27133afcbfb7642996b5422a6fd335803 GIT binary patch literal 13946 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/compiler.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..001f5c38840cb1b49a8e3ce85e2423c65a25e45b GIT binary patch literal 54549 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/constants.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/constants.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..681552657d13477e37ebd1f8b1887cadc869514d GIT binary patch literal 1536 zcmYk6&8i(m5Xa9A2$z8@e1qO*VNO)sh=`yr1Y<%jBDe`XJ$25hYky4oW8^-HkKik1 zn+I^=&XvEKa}kG`s_LHVs(=5hy35n2(}CyPzyFdyJ~|ve*x>)q4TEp^+AU%^{CZe! z?henM_%Ctx&IjHwQuEpQg;!T?LG#&p$zqdH-wmIxTDtSeMDF7J+9hMxFr4p`AEB4( z{5TJBv(A#2k=z`8UbMRqeQPe1l*&@jOeR+2fo&^LO+uGGq)z*Qw5%(6%<4^VK1L-* z^#~@TOtF`Yid)tmI(5tWC?B=YF~45 zmexsy?oOiUi5*QCkGLhWEy;wC3Q(y9UqYLAx12I~wXtD$@&UL_|1%m^k~W=S%}}}% z;Y`-Y=qDLxCG4qE3ysmc(`Z55x%y2P?=H4w%J68kCRky*fU!yi+2w&qUI3*&3=6J{ z)3i!m6o{I6gRI>gsODMfuB#PI*EZ60KUyy?0zJbt8ko_SDlCtb%7%girLLyV1C)?b zDyqz-c9KG@q$$!HxF;_GP-dL7-z6@|M`^>esYH*M?6xxbQBBbiNOh^;)>S49+fFLL zHdSYS;*;T=;DH4dqnCHIm6bHh)v`cY=L>>TAfn49PkbY#2kh2?o`_#5r z#u*?`vGb*FtzO!mi%3d&)~X2t)>^3II^w3F!l(q_&+0qtUlX?PdMTOGO;zdsVE~}j zRd&vAC)`GS(#EO)sT(I z@4$Jw8VZgF`|87+Srbj%6<}hhMVLzPL&`xPfJZ`sT6N3arBkr zxQ)1uPT78XcJuz@A78!s{^i>rUf=!v^6f9L-h6lW=b=8~mfgiauaB3KUENjP)m6VL7mJH6 z3*Y^J{!M(oX<2`z!PSqr-$yI|f{t6<&aD0V*WPCsv&suM4rp)R1MPAz^9POn zhN1l|7&P~rhHijv?YC@8u>OMF!O9?O4;J?q!M)C#nC*zA8y0Vg<(|tIc>6PNe}ylK zW!^D754@Yir{Y z_pu&q**dsiaItqf6rdOPWSod@oE*`_rHv(+UE33bVHPX#@HAKP^Ia(mNsH5537N-P zlt2O|8iTYf)BJ$Q`vsWKmG;YGBom>1Dbz^j35lG2O%NX1eYDaCM_Cj5!ur%1+haC% z6q`88t=I({Gedio1KLr3#Z=>*$=em{2jy*US1bxD3w^U$fW(k{gvfxn4C$bM6`1A-a}VYbw9T**H)em3wY~X#Kh|cB-IqqE6+E zgJ;Kd@+!EXxAEfVFvhRMiA9)B4y?pN8G6NRFnP?ha!a55ii|-S9_+#L72# z+S8{ujp{^(SZ-W%mc<_CH;iu!5ZkE7YmqiAbWJLPGq14xb1yjN&jX*Y>Wr5Aq~mtuGJNYa60 z>sE@GC{>&%LXx-Z78K?s#S@nl0=h$oisr}AonCw-u8e~o-Y>^HXg^DHkr%q5x=~Ky z6@ci$j9~Rl7)qZcHha-QR&?X6)XsrWdJ`SkaH4Wp?O(iuUU`qP&a42%F11XM$ zECt_c*5|V$-K4u7$Jt0|rn=h0eUc++pSqO1PFfrFxw~=$qd!~noA~+HM>~hbK?DGI9QcK%4vb?@O4yu4RkC?o} zTjNIFse(y^FI?Dim$$)LWO>F!|Dj#g}hb{V)606YHUMVr{L&H<@L9A`3nuhzfIY@-ooEqT3gVLL5#pr>sFI zRX~p`aAP8R=411?M=*()heglC@f_X=)wWI8&%)&8h0~M*82c=SK)cK69{Xv->XPB5261HPB;K0 zN^wiZDdLX~lt=-fFuDopNZTu>oT6ThrKTE+5!&?~uE}Orz$%ooExhXoUf5S_{ z(JgjK5PlgDjiM$g%t-U^|JV&G>50x)lE#nKTCxSM*Cpe(rAE3yd2D)Rd+~2DoZuZ60|+b3l(?Grk)f6 z8*2%P$TAwpTXau?Nx4WJH()C=8pRflH_KP9Ib=Z76r?caC{Kto>7?$yMMBrn zeS}u-p$nGUPRDi`a~MG0|2OkjZTE%i2drfWNCqu?6%gOC8FTIb{bMiZ{=wE)ksMZS z_QGh;3kbk$`kJp)uk@b*WdoB5z5r2K6JR51LmMbgmF03}Q$0Ij7uJ}WJV3d?!8+%{ zLIwE#r)=z^x^yQlN3|%wQF+Q6A#Xn0JX^x7Pya_;Fx12TxG{EBqiP_#1dpw}3H%LC zKdABdiS=yr1eNB*s$A}0Ae-E<#?7i(1xFTgK~Q-;s#M*3Scg@$?rWqQ&8O!W__kQj9VVNHg#f zAIE7%*cpOj*fr|Dh6yzokh>ZPeV|zu$q?q1-$l1&U%tR6k$A1GmV6sOa2Vn=%zh|=K0w9cHPW?9#n-bkfc zX$r#H5Q}?HKG}`#|77?6&wu*h$GS0nLrL(agOANW7IB8+R>?YeO-1w=+&UB*zd(hE z18C<5`Kfk4OcP~}c;(7e@<|F$9o!or_h$l5ip$?b7g&M0Y#Y~X+dlfY9QFa?^+kY2 MzoxO)f3|=2U!KKv+5i9m literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/defaults.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cc88a3e51b5eaa58f6cd1deac8f0c4d0be178e5 GIT binary patch literal 1336 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 Z|Kx15e#zNx{i3tO{srp}_Ho~T_&-_;o`3)V literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/idtracking.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..637f66a9b17b7cfeadbc5280b9653c0664ecbea6 GIT binary patch literal 11087 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/lexer.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2325384c25af71dcd8dca627f1bdbb27e9e6a707 GIT binary patch literal 20437 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/loaders.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76658fda40ae8f4d85fc40ae5ea3323baacca930 GIT binary patch literal 20493 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/nativetypes.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c94c9a24cb607c52667f375e770cd3591c7f773f GIT binary patch literal 5011 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/parser.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/parser.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eab231e4129fd717246e6c07ab46c2a6d6964a43 GIT binary patch literal 27730 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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/runtime.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9b121bf3f1a21f43e287509b3fb3112dfc89873 GIT binary patch literal 32145 zcmd6Q3v?XUdEU=TP60D|C~98r`=P!ve&ZRkY`A|+WAq=>W>ucIy&I|E>si(T-} zE=g=an-Z1UIVX1O=FyzGN=e6!qb8?G+cZs@HnE#DO_RRzXp>IcG;Pw;I!&9Ns;y(n z7W;kwotd2l7FJ!KrU5y3@7%d_AOHRDfB)CL(;6PmC-67(&L6rTeIt?hUEak1#&B~I zm$xsONH~d7!Z94PVU!H{HA|-aCQBB6la17Jx|BAU$7*Djv!$%WQ;pnmzLb}E8u6jh zki;{H7fJ=hvreutyj(05C7wroOKFS5hZ-Zxqoq-a7Z4vSjY)hM@vWt;5-&E!m$#L+ zNqkFVVtIRMyTnHj-%;8j@lnKgmUc>f4Dns1T@v4l`0mnfiH{?`r?f}n+YsMd+G`|S z>&8B3;-*pB?^^YJ&US>hvjgEB3+B#*v-6W?=>YETR6it;I9NI;zju}HMz3}?4lN%p z9X1lrB%IyOo;MTD9{2A06oXVN+1+=I98bC2Quqln$_9z$q5 z_bwXveSqoggY<*-+!y7MzTvH7?t{+p;K@VscKGB(kos_6D#~6Maqe^Oe=}8j1bu$M zc@TYm@VZ(0fb)=h0KGVXUOenPg0@b(>H5R{MfSO&3$wDXMfEZRDQcb{`Uh<88eo0>*O|Fz9P?aa@}=&h=a*btb(-zkvTHANn$>o#)%5I2)3LpFrR~}s&voqi zRlC|+Ua2(@Z@bGY4LtFtzQk!aJ8AgI%6t_+sp?Xt)(3uEW4Sa9Y^3MK%5dKGiNwCAVIQjxhV{K(n&a$n|4xeW+CgO zoeYLO>tr!(dB1qJ)mnMkMbFh444NWL{fu&}1gAgJz*97qkINiXKjpY9?Il00+;&Gb zs}{0{e~k0>8C)K3oWwbd&+OZYNz1o9x3QphBUSBTu$O@y2DfI9Ewz^2V_wC>&>yRM z4<0{u*`4>$h+|Wi+~%cYjoSRNmDToAt9k#_iQ~ukpLF5ihNJQIPH?r!hz>r|Krm?!<7%<;V@#;jcS^X2k#%jq;2FO?X#N!LugqgCwnl;V$%%u4>(=xwm zri$-Mp2?y=#AXIq=Z{9n>Mpn#h^p(SUZ_-ou_+c?V8De+5#avNvdofly;W;sqO?^I zt2w}(T6}%1cUb)z z#(UD}o_$$x!?SB`%zw4mA>vNiAM)IVPQzYkDZA>bHYT{;Ucx*i1#IBmuRrbPLtaq0236z?$%?!~@lvSn#pf|h3ySxj6t+KINYmbh+SHP_6i z6R+*Knp`t(m}|+KhLLC|*OHEL-Bfq9EeC}8Myj1&GuF)O=1s#ykIyA8=GvJx~6*+v}$*D=V0JerBoSRoXxSu-nnJ$kad~{tGV?~($m8D*!@Qj}6`%IOjYCV=3EYZ^5N2(YP?Me;-TTkgK*3#( zajZii@a&^UV37Lbwg;Z6$)q$}J%R$&5d;`pc3^#Dk0I?9Tr##rQ}OgeOfO4_Xny)mFfNc1!W>7}>M?~knba(|3 zqCqF2(zOK8!%{pEEvXT+OVd)f95<#k0(HxxZoD1a7`o z_%`!u_G)e|*ETzbx_2$NmRZX_mbiGwTB4p@LvAA0TFOa&G6iI^x_3PnEGG7n+gNdx zo-VpCc2&88V^gyNEkN!xT1n#S)T(Vih0$O3gc|t6fI9nMt~Rj3Oy<>-$f-^;IK_Z{ zRGd3fggS$mpI!lsNXRa@t9}Y=QU~=jiv*l;{!r7s9IjL!L4rr3kj-0$Wu%R96Tiu< zF#^QO8s;?%$d$gWUO<*AuD(Aa)=6C6V+g`!%P~qxXIK^}3tV;9O>x<(XTUe*oILoZ zEbdd_Y=)cy?s5)cR#Zn(M0W?-k2x+fb3#ud-onoWpioaCpHQ*cs)=a$$2cz;cH#hr zBvF>dOYO%kmg3#z4OAFwhlcPZ=mc`9Sq63#96*dSyVk6=%jIv!onUg_=*1U7qX;!5m{xZ{o+%c z5-*3#2PUAj_glgY>l-~(E-$)REZpUC`J>1rOL+mK+TA;-SjIp8PiF=C3ru3%XsXTVc#;IAU2ajQU}>S=>=Q*wxL^XGgX2Rz~rRLwW0s`*L!6}LWfwe*(+4XPnF%WnwMR1CPTVj)k+>;xrju*~ zQVZ6{6AO?moz$BJ&=-*58&*5DX51w2ou1XOi8|F+I>|Uo-pbO+E_?#xa3gUOV{tAK zB6tR)SO&kOK8y^2^=tTvfjPCnhaYDNY;3{o?k~rB!-rFkX^Q&9l;oXE`#BK;S}jo9 z)MZs!@dS+O+faaSRV!Hiwj+w^BbCh|u4^naMsWHg>nr)wNcFfjW{q7&A*mchtGN39 zxKy3Q<^3|c9w#jj4etRj3?M=rO1Wu-84&;(%erZB%9-d%&Pj-V>@@eX+c2Uh89!cClq2e0d55+ftK9q97NkE-0kj;`cCBEDY0FM?ULAT#C8je z3ho}{zstEBt=QYwn?ufFr0qkS)93*NdED(65%Z`J@XGH4nMvzGpG0~jf5DZ`UTQTQ zupxMaCBH`I+_PH?b|uO=W!ulS!F9D1o`ejiEOVYsIgBD{OA3g}CjSC9L8p>7>k6Xh z?v<4mxH-+L&dBoIT*UeVi5HwY_&*Q)Uk!CB+v}__FDhw*1BNh6X1GEo`H-hqcGnS( zm(uJq)_KY=U>e)fomR)A7!6^EePSnjZD1EP?Q+auC z9%Y1}Lo;j3%bhlX1}MGIa%u~xUrX>{1C- zW*Yb|*|0fqir^L-jn-v=VL`Q)?M1gqjy33d)F+D4cB|P~MQhH71HDjdfW6f!1D>g~cua_2D_Raqg(pJO?h!n>%XHX$)md z_`4v2-s;C>`TMe{Ae$~FwwUux&9*@H^2+78NkI3Mpg7){d){3Y)ybSa-)W);s~K0a`s#xWdTh&S+*Y|5gnx{KIA~VsPay)%8jKvc^h6m9 z6G9WB9XOA*g_c#5tv!d!+kt=;zm|mnU_iZR(% zFaH>^gUYfeeiB*V;ljHk(LFe$$z8-V_7>jW3zI_{STlG>1CWcNpVf+{_7w`rZGTu( zFV`t^atdVqLLeZOiC*eizJChAWLmQrB1H@shjon?*69cFo`{<1Y#P!*5i&s^?Mx+j{7#L7Pm`~vbK53>CAI7jjdmZH3GxWcEWDcnPypmt0VDu3u{sg}GXfm6KEDdZ(FMD+0$7FX zFIOBcnn!J{c$ymEX;39~BV5OTXrMSkA*cYtq5^sVFa*mK)20FZ$})3K+g!Gy@>w|7 z?1rvdlZ@CKK~>>f5NMe@Xh~oF@p@SR{~-8fLy8tkO@x{vi@y&3eiD@X7m+TkznRGc z?vR0RcZWi#08K5=SKnHpq@BmoB=iQ~srCLj2kfHTa&@@Ib z^{*l2mMRBS9xD;Y8R|dJ){DwiG_d4!IG&xAs2mX_#F_xMNiRS8tynRwru$7{jA{e= z5I)C(6))CWtzQ+=cbS<20a_-IsWuR9D9>fh{56g#=TSbNHH(I2cDIDM5aj3+^obU{ z1Qn>#(4ze%C}2Y(hvBEVZy;@)znqijK-_>5#y5fz_S{@J5OcN%vId(+BZBt(Bg2cq zK*tAg9aiWOjF2NXGyD09qamXqjE``T0oKGB7qZJzS=7i7Yo2bA2_e1hYm8Ha1)~l2 zQS)P*&EGf?!9a5`^ioP4d#LIWB4G281SFA)8lK<9CG$U@hhh~9R*dgGt3K`l z6Iv)il4X#Fi@;CTBl`(xc*uB=<>=n?47k_|CgNqyJqqhZIvOtK5q0#Y`YIr9aRJ@R z3VQ6xRbUY-ATGt&6X+J%cl3AxKWdQybpx>;*Kqq~Ce;yi4~PB4K$gR{4CGA=wamAA zrAdrH1oshp`F|os)D7cicYILkecdDc$bGTZo=hKf%1d*aVA>$`3J7Jo@J^JsxTpG- z)2I70+GqhRqGUj|HcXb)K(vHxAgp?=S#5M2DD5R%*vkkh!*$66UwsBkUTX!$&{{WO z?!oqZw1{e|S6f^X2`XHT0w$T53i$-aCRDz%YD4s-1PA7W;-U<8hsH&SjlDV5hp5j0 z05Ra&ycG;3!}Jwgf}!aYc{1p1jUH7Z@G+76;c@`&avAG`Z&AJPr!QRQZy(7b!%YH5 zEuHrV2y$?LxN1Ss2fT&-WNVu?6{8NTij(XZYAfSVUP&s}II!4lqi$i9dlcLol)X0% zHHj4v47mgD4LQJzAw7lk2ZMCjGbJ7Bur(8$p4r?krDRabGZ@)yls+WsIi$ag^jw&Z z67voe?l(PZndyFMM$;V*P@_TNS&tBL zD3l_#xC++ga!Wxx4Xj~3erH9sE@91tWgHR{%$Oisf?Vr_RA5ug^g+FW2&)n5g$0LP zRn#EZj_iTba7#rm$DhY)nd@QLc`aZsC8MRVKb1F)?M zBD~`l;-+(Tfp2o1_LD2E6@R#|4kc@M+AsF7TTId)<4e~Vyv{er%H_6#!G0dLt-WG(adh?zD){mp!`2nz`LaE9av3ueJE%@M@X zhG}HMmv;*xWn)odhv}PQNt7G$;!op-T6C=ZkYXub-bmgQuOt{FGhi7Lb!*KmOl)4Oe0kaT(d%os!hJO2L?Vu!$@Ny3I^5#VTcw`a40cU94vKvfQ@G( zcpY7SZ77tw0WMf87tB{6`&~3CwudTjt5Jgr+Ql2|M>Y2twNh7B)DzPjTCOVQwS9^1 zfpDk-u*6ok@P)~&n7g#hEvgDqU5%Kh5cAWW6$k1rk*q^T@(i;Ga@&kaAQbyMaC?GH zpxWL{O&HegY;q55Z9SSDG^Gz`xYF~Q!6mFj$Vsl`LjExXgW2P7Aa&n?7qo)KW=sM$ zg#Hg4IIT81#TK!AtR2z19M90#7$Pt)Y0N%EHb^+bv|?R1-T?KLm3U=y!A6tUxw((L zHV4La6)n1=WlK^OyAom2Tu&1PYhYZ?94O}{g?rO%{wkUn4vcX47S(C%P(;i?PZJKp z-&uT3W}fw=w`pYF2#+c@@p!U5ol( z^(vyUWqm7?S&kAk6NKyWRW=`R{KR1OVmNFEjkp3v+r{*xu-BQw6ivL^_+>o}Wt2L? zdokc-Ulej(Y53WhVC@T>V(5KPd_n7yUw~d1%!;Uk{M3hB7P^9AODg*M(>Z1&# z3!{vE7Xu={au|@K@hvQ&;6k*fQ>Kq^&BM5)KFuuW8Ek5ndkRlKh07xZVU{z^oz^WA z-Zw>f-+*F&bzjPScRZcHWo|PevyY2IME<=!#eIeG(OqM^EOW@jtTS(iSJ5oIclXhJ zf$kGyH1Q2pQF7m39(N~kd2b+yTcO~W1&%|kP^o&_O~K+~!P1nXRYhBxU{6WAIVa;} z1Iv$x)tC)6^L`rMe5eAy;#}6J^^$h{MHIfyV@xA9O|-87vESi5OlQc^!ot42 z-{KvqN)??tHcUuzu`(e)hzKSgCgpbV4yt42xR6piI2r4(c!}9M9oHK|_|D)dr3|fD z4&Dy5ha=~x`xAC9rZ-d&^8p6}rj9K<}`T=h14 zF~Xn+0O6lM&os_z^}`J8C}3}e5x>MB!NR%afx6R~1=G4xtd= zI!i|Eds+JTF_>h)i4DG6(KrUT#qVdD$3PYcY5bkMwfh5U<2j_AV;k>AgkBgR^?|D; zNI6_B&38=_`@)1_W=9M&KW+$dtRj2g-w^Ij;_@uBN5ema=>az-6Antr60G3$jGNt= z0KK*zOSt(GJOkLq^DSIVlAL}Z&;8XDiz|(_p?jJ=Bqv-2VIM7?AyPPR0XT;ryv}4Y3 zq}>f?`V-E5h#ivF9F`n`FNbr#^8lVqx<~q8cn{uw(0NFDbrf&igC1y?{d=7x$lIgp z9^gaQJ!R9Qg~XlaSCRbb*XpdoB2lYCzlyuLIqI=jyrY_Htu>KGyMC)Fd};;m-CERV zF425SS(jiO_uwK|=&!C`6x^UZ`r4v;-gc^h}>~fGh zve>}`M)TzeT)>T>U+QmSz(P*yZy>J6|0fvZqZs8BqDg}LX%bDc5a}({P=J?$=JhO^ z*pq9tpJLylMKl9_ltoMUFzx6UikOB^35pg_X@!lPx^AiVZ{haytd=EY&F+rA>S7)4 zt5P!K1z9H>h;Su@udbo8jGaq#^K|bf14oQ~Ri2COGP(MoR_N(YgeFp>BcaQ4vl{m5K*6H z@RJDq+ywP*0M#q zWu4G&0I-zEd>X`;bCb&#(d2j7jC`^?8gH@?g-si*{vKXIGw+?zo)H?AxHyDZ*TBRa z*rKd>R8y5wTRiugZ7rLa`-!$VP^@xm%ZW^r~B&U;)HC}E+2 z(R)w{M${a836N0}`$0&QFSAEwX8IjKQEM{O@Y6CuTPNa^rI&HTn1$q3#6fCyZ*tT$ zY546yC`C54M=AO+s%NU7q18xxSVkj)<*wpfqE{`}Lac;S_Bpp_ItVOS%-yEP`P8Cn zbyntAHPEpivm@mR$eI8f%I`t#JYXFZ(0fgMP3_91R!y9WLGPuM-di9;|Ag4jm2==M zwb<7`AZQ7tLbf{+2Pz+K0B1A>xWp34$(5Pa)wtJlwZsMs5(X$9=XA9zDR$d| z0Lorg+v#wd8RtTTC+jA5uT$Nf$ky{|BOwVnXeh=15xe@+4E`E}L0AQm9q(X*{4aK# zD||YIT|n#j$S_kM00^ZB0Q+#G@rfED@q`-2J@&Z>D727~Lmlg3AtXSsMg*yWaIgvd z2pGN0e-bcIwzA$ExH`ws_Kevp!{|{JM`gY23R^S0G*yXW*&$2Ky@R-$NYH5soXzI~!cBicdget;!y-f| z=%(Rq0Q$OGZD{PpgkD^-=PNWg1|l>CC3G5|XyQB?l3Ts@gJXz>I1u?*pNx*=q!AoItq=}djKa1WfS*JgX*koWryT(*I3JxHK zE$ysegy7|@u+mvr4*Iz-$)V2T=?2K+H4Rxh?vOC785fdp3={E&BDd_2NOpfNfa%=a zdDU^}#P}6b2drUwz0mpySa)j+qVwkt0}Ma}t;0Px7g>3Nx7dF|TN4j%^Pk)ZVkv1; z7{jlII{*M~7Q|U7P3nRB{28#*e;s`cK}l$=2W2KubL=KCsa?)v*}~RC7~tX*HptZn zOAw4m{!kCF?EO&%1IZb7=3z}Kmk*&X;o@O@?VAx{hQ4YzToEZdgBuQ+uruO>L>Cyc zG0l`_YqS(eTQqIU^4yEGu{MEDs=Xu#;m{Y?{% zS`*tzbOrRrVVN-;Jx`=VNw#cX5ow!vI5!uSh#4cw9KG*WJhgzVaNW7k!_nF9%q9gL zipn_@7K69Ne@pzqqsL%hfajDBK|}sFel#Irg8DfIb`%_7>`nv^al|Oa<})x-!nQDO ztsg5+R2brkU1~M$t=U?LOuQ2!w1L22+ z3H)cg6(hy3GWHt`{yBqx!QeL$_^I<9I29_N31Y+$3kXMcbHg>2&DSx6o`XmpmJBO3 z2BnMs2QMSTdY6YtWCJsHWZ9Uo4Kq1n6vr5vR&ZtTi)+L(3y9_R$ThZQd?;Vol{5>x zjIm)EiYhAW`{ROj5|{V;2tr%-hZ1tWNU{!(JnUjLVAIIRnIl=G=iEF}lh`MTU+VUq zq~zwECEHlJpRnK#BfSV6JI^Fx%9bbv$0A9}NR*Oyh9qTF%HlR~v4WSzB*#|Vhc@tW zNlC(@j@CINfo*|S6TORZhqjQECZwe8k}I?e=pB|job4c3JJo&YuqLje6eG57m|jG4 zPA~N{3}ijwqNM&V13L;1Fh=xx9xuq;$XeaK>yO-+iYs~hs$w-P_vdkW^q+WLs4Vs@ z8MF?*kJj@st@Vs7yH?MdOY7kc?j`10V?`R!v}iyx?d$*z=(?RxVbgvctx`Y8ptq`i zj<uc<;`j$;o?HB{v9ISotxIOp^^ygK8P1}7loM#(GHSX-J~mG*zrD< zyR~{SP`MMqVv2NWE=&|XUWVfc%LXXBFe&~RJvgPE&(UH;iEbbaNrM+Tq#OebDL5I^ z95>Qd;cMV(O!I5q-5YxQK3WZ#X5o-huc7;uo35umqisG5wg-U~zo z3jgqeFpW|(*(yT1S92r>kFJ-4XVtGEx02cS!;INcaDXwcMwbYkJR;^baC%y@+lT?7 zc((xq*v=W2^#Ft3>>k83bNn>Z{4v7dxA4XQl#Vj>)zt@sS-cs;Hewl1?h!0%($Evb zITEq=XQ0);M3H^mvrvwI&rS)a(c>Bh0h0ONKodRk8XC=T+DVUf-Z*h1RGtla9j+)? zSPrtvyBKh!wU6C!4AWam{Or`f=F{J1@cj%9GoW(Fk7Wj@tIavWw}|`17ntvt7zno_ zJc_U^f|^7K^?MBdEd%Mk%~&ruz+1NUS@!n`BKZWE2Gb0V3o5*4rf@%u3oOP+(i~!J zkCD&rOUipyywdkan4QGseE~tpM9`H2$1?2h9m~Mu0fb@5fT`d?1Na5|kc0C>9@h{q z9*cl`uo5FUEv5)p2)M_&1vp6Xh=maeM^TDCOaV(i7>i<17IL7pag?HS=;eOPCQr4S z1RUw)Famv?!l;Pad(^$?MtA$GJlMjnfZfNDT+w!P9MJP59_tf|EE<=!SDl{={q#M* zfc^E=rLx{uf%AIg?h-aS%5Dphxs^W_>|iYOPyp?aRL!B}@Q?8%F3wG_fgmu^Q%g>L z3p$TjpMic2&O;C^;j@M<&+uO32In>F5`?&NZY?WYpii`+S*Qv|-KgQ*IdR#dp96tF-wO44KHm!OK-sJs1IA=dJ1q;e|09d~76t=~SAW0< zb`%JLzl7UAM+D!4NP39QgL+$xb|fU7gdrRrPTiuMxz_U}yvBlFXRv`MB$eg3yok&D z6e#DKp|;7M7;Lek1w(D)ZqA*cUp#fpfmix>fJ44&0K%|wTus6>Z8#LFQ%r|)z=De% zM)E3ltz1oW{OT!ae_q9JMnBOd;J7LKYNnf6GjC+qG8{APejc(C?cC~f!3vzen*DI1 zXci^NTH3qB(!jANZkjyCO7P<%o)+s{ zz_nXW=95fk2|3wbkf@KSkI6muVjGF(zBN<5o$h3o7VHX`>i&2w$z%JT0CSz zD;+MkLiJ&&8S_?fY$A7V>5@Xkr)@_Y)s|b(cr|JlTxc#T*zvPC)!l8kD;LE6&;8AP zn}qD{w&-D7>npJ{qG@*v(LSQX-sI$VKVQR^Fvzknj;JDlDV6)Z#K#)qJu?0l3fOg&tnmZgcS9fRw zYnMWPY3Ol8*ia!S8OLZ+?!-Mcp$?BVLkv40sF~t4w&aws)GXG|W~;fn44YJMOGK!j zB9i(R)l0E`5q}nm>zmJg0wZib;f4b#j2=qFcSDS=XVN~xvJNr$UIs@P{0IZ#tiFda zE+|^NvyHKDV{j(}fhys)xw3~0#h)PxJb;L}tqxgVrsHZMI3qMGj;rP^Gh==QJp3PJ zbNMfudrf1XvG44@?AVa7BvriJ_cw&QleoMez)}?FyR-`{&e%(WyMa>1h5xXd19yaD zV(WSEVc~rSG4NM-k`?z;p2e3caq9u{L+v7`@rm*V{FuC3lrZaT0S^{#Ll|{OWLra) z&rshO4!Q!7hx%sJN|d(Z8ppK_$4BvgJFXqLcH-zL-tR8$k>9E~QMr11C`P z_s-Hm`MnGAyKx;V9hUn^#E+EVE{flyI9GaHx6GYF3pDR{tS?P-e8`vKe$dioHoX>l(- zBvN5z2_r=nbHMM!c2x3Yyl@v@|@39}aFL)Ac!L$#{nhDLh_)36ci`i&$TC&;p z)Rb1t>l1*dqJ5;^RAc~`=1<$wJ~~ZAaFZh5w!orBN!am;12BuR1nz*2XJB9b@mPka z%30r%x0BqkD#R#>XM^2pG0n9+{T3oxo_-gx&|i}_Dh2K-Sb4Eic>@t6rMU-0Ox;AJ zI~MgeVp02uFAC_%38a4{wu*cb_;`en6|helng!W*X1s+pLmVV=4AOPeJ0Kht`7(WU zBetf!g|#C}jW(rBDYEC{^tQ{e+mOu)Mwa{F zdC*qezok3eH-Oy{9B4+@NjvoU>5hddJh7~XJ=LxadH<{EvHBVV;dtI->>UO|!^asL zq{$eI4Rg?yhXHbL7hd27`aBp8Z0Q9n0(RqeA+3MAdt!qT^%n;}3M_hj(ygJkJ2l(V z7TdnjLLD+%B0+GC#ab?-bQ8QReA3*P^?t`qW~%lViXAIPn=5P{U{jZagVta;=l(BR zzoHiE5$V~vps~13$RvS0FjL*Z_%#NvGq9t8EP=nP%!9zne z2V�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 literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/tests.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/tests.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aca8d98d0a16e51b85e0365a4b16177176ff7d2d GIT binary patch literal 6690 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 Pg#H74T-U;X&-ecWB6Cc* literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..900102772abcd6409db6873cd5b51d04e25736b0 GIT binary patch literal 24509 zcmc(HdvF{_df(3M>|(Ka5CkEzprOzcLDGol}Z_?neFN6$Jbwf{k{6@X$%eJQ}{dc;di|COR3Z!@S*!} z2oI-l`A?@)saI1frL0rOGwl=stG&>~ezS{8ej@ccO&ecYich2sVv{f6O9rZFxyYvgv)7b1C zc-pP{ao?lzxbK~}_odXp7wy@7-hMTxhSadyp+??GRjupk>#5m0S;jk{b{aKTE>Mk#}bl>&#?4hnQcdL6)=CE?vKiZx^+aFWo$eUF6BJY0Y1M)kRg*OM)eR%VL zDyu{4Fj7-$PEC48)cxKB>T;A>^?;gsCo@}66;;5Sqqz9yD6V7sQh0w%J&5-YCOsZO zyAP>{(b_{jd5@?^k@v8dzVV29%u6plitDkbQycc|YM>2Z>o!cGE6! zKN;m+X?jRxD~pY4g{gjBt}9#%d~jZDR4(H;cc!7d3u`OP8@bYK1YU7oHkKa6!A-!kXTrW^Q(F%r z^L;C{u1QL6H(xxu*jVXu3df`wqVAjr z3{*THBd8ce$HPW<9Bn6Ga8N20r0!%I4w>qm zcnk;SeN^Wz(gw*qH{@9Q01~$)A-xB0K{h}8gUF^1iu4O-F$>X*{Qo5!;_$o&>eb%- zbcxe>BpMhHC7AkuqN=WO6tIeWNZ|()R#)L4pA#%Y*TXMvj880e~f`^gwFlhJAHDa?RKpIkqd<;OT5xO)Dwcshm4=gmt|=bW{n znK&D%*-Z4Cjeh&QoU*)rWqbLh0R@>2ohPlFcO2*lgDL}QkTu|@8*@vVQl~<}5&tor z#zjHmkKq=i+Lp4e+d9{_mLR?r1&Tc*1Dv$OzQwX%4gwuNrz)eaE*mJ#2H24WLob+eW*i9ao`m7 zP*}EG%7bxLmU)AKlA#aUpqyh!2bwYf%#~LOT+%DVG{h?uD{sD9_f)}kFDxQMH6YIFjbM>Nez~DN)GOCzt*>}` zzM+>z`qwdFKPcBLo?DR)$_r)YB#OwZal<8dt{J$sMgvHzLle|S1WIR>E}a2QyOpLN zG?rt9!9|X!3j`r>SIhN)%8K^N7(&E<68PP#WnC@L)gZoH_gU2Ru9cymcy2jv6$33d zYeCdH^qRUr<<_c~jcS20`_t1#?m#esug&vfr3th?6+fIfe0XwNFv3#&19q!^F@c4p zH2&%bybSYI=)z_OCT+7incuYnL{1EL z!&O89LtKM-TR+NXa?oTo(YA%cNM*t?sI<0I&!jHd>(&+9=+mu7pda|qA$_PhZrp~u zTE*hTY^#PL5@^g!FdKymGXfpJeT-dO#m&G{6Jnz)crENCXWN!@OMe{C6ClDjSPR4gLRQ9yTI=Y)Y{$4p10CjydVltv+t4?yEs1w zsoa`(4Z5JL6VC@-X+t%l@cPuDL8GQouA%zjz+Eg~#quG=RzS3Yce^%SsMs>^l%}G# zyY38D8nV~iwMG;8>~5}tuH7<>BCG;-%Jl^bWWgAyWv}cvMNeP$u!z@OgIVE~QgFGv zmMo}B&BG+JZ!>(eK=p&bD`@b}1urQ2D^N(vb+6Hc*4>eFcs*DYycDJC3 z!i>Dp(@YP@`y#v2VMcyH2P`JKrBCAF*>Iq`ywcEt z2$eAF!#=48J%TTTViXiY#%!hafC4+e3PTKpAw;ubU$ocl^>lqyrRB|?cmo33ur8*N z@8C^_EcLqeI)r49M%q@6a@y$y>pJe&ZRR_vzzH(*_S&=sA|tu^kAFV(hLGDT3GUB= z;GP#~Wx+&jc&;27OJ&y&I9o9jCS&%!`DQJi*NFECk>HJMMh-q6ETTalgr!!n<^rEQ z(}yi<7M@>SuGY#L&7Q_8mHwp;nV+-;gUw&@D%JTa#DRxp>S-``&|5%55MrP#hTuf0 zbZxm-@XObD8AI3eE9DihRGO5A(5BrPY3g5A1!P7nlIqIjfA z?^kqn1xlFkLSjGe%b*%;M+$n^s<7v$3=NQcR;wV-l9`pr+MStnLc8II4#_plR(;kC zoyLk+2M>4=u<4h0+k}>37ARKdi>8mSqKF8ELB|0`^f^3l5n9xoWVI7VZLIKSN@o?6 zp*F^k^q@*(>pPK3e>J5t@3ACuk0J z7#bn`QjzY#6-ch%Sg2Q9o)YZPbyf2MNH`(ptxZrJGjvMT46@xTLo1trE+h40eTK3r zB6{&KoUPTWD}L24O&Y#E6FOWHVJ?0V=H{9(HPK?LFQR+>G|)5Y=nMD>9RjWoBdHHD zJJKc&GGo(}jF@FpWDW7Y{dpAfsVL_%4oDT3od<&+v-Ru9+%i3h%%&BR$ZX1KnG))( ztpWzT4Dy0Via1DczsO>)z|aW9X3>!2ecPJ4Gkn zytsPbkxLJt)B}@GNx|lvYAi!Z?i5N=Z2ishk=CWRADVjX;dK^=Y^YY;pk|1N1=>Bu zuhownVIQpW=o3<>dY%esfwi|i@ z&-0Bogo=#47sjrB5=3>OD1p9%P>yN>K&eY_KREU9`sBpLLg(RaWDvgRU%C27Qn%BG z)V=s7YnPAAUwZr4)FbQDlW#w?-kbB(B$|F~{Zic2V@Xp6Ip#j`)bw=J^P}r#x~N%5 zS-gAm=u`Jzx_JKn=nc5olnd{+UNbJud0k#eyr~DJQfut3i{~FWb#WC_R5)_!{)>f+ zs}CH+QiCrx9EPY^E;eAPfbmL5@dfX%1?Zhx1h<=qsxR+k@y~xIL^Z?cp1J8>#hy_8?NZ4Z!}VumQ1-5;ywQ(1xYksF7F0 zNsV??W2ij{wQcyuz(&f{P&;6aJc?d-tdF4fV0*`gwZ5~xQ_>?F)@4h7>B?t|jnX(jK{P?Mbcg0z^aTVHaC}oDdDQcSX<*UHLh*wDU$5P+9sv zqK8q1y8f?8YA5o3Q;oIA7hu($T`av+hbDq>^9>xtze8_wyxaY9>DmK(;oV2>b-P3 z+wMP}y7IKj-xzCWH@Hc3SNTbhGYm)g)C2d`b1%~Hf`xw#=1U!BQl(bKjtXp1nB?`# zvF;|00-7t(MmsXq6k&alwb+npimD3x>{TD`q#DDEz=RX7EzbGpp64S8IKiV0QNNMN&*6{(c3H|Pa|rdukJ+d(LlN>kB; zpFBY(6ihxie=TTC^MPX9xWw+R_A-D#`3A9oe!Sl?CpTO06l?sql0`QE<-^ zb~l0B7@^fV%Nvt;5gkL{hfz^ez#**Fp1D)*1eKUbp)tB+sT3h7YW7t0wt$g7RjHh) zG*;HS^I&(xx;@5SUKTQ%c3;-jg(|#(hN@un1`xO$u236jjFe^cr0J+$4=#69Hrfc2cWmi`jJF3S3_y3U(hP*24FQ&T)ykp;@2On&V8~;7#Qj=8ar{#I zP%U^8s&@9KHF?uIDF)6>YbvzzH=RQZ!IQ0>6K_tQEKFUjqbQyyA2>Lfp0saT6I!7~ zrjBb*QZ0vV=|y&w6HONEyww+R`Bwk&vb%`=$`j*KzU3T0T0Ys@ndEkAL?rP+A6v4= zPu{dnwH!(WeVREVNtLMJ zmBlc#pc~DVFbyA2n8VE{VZt8slr8nO&8fyu1K(9 z(uH{`Z`$ZD${Jv{vjq3jNC3@}4TCA>7d z{)6P!D=*B;I7PVcw&Tch@fH3%xs!KsqZ#Hm3iZw=eFy*E8-jo8DM{r!A) z%(~llZjENLaJ)FT+{^(hpN5rtE04O)t+6zJcUuQ6=X1MZ_v$aAqYtRDU-*Dz`T;u* ztvbdVEZ204PwD0IwTgpO{Kpl|oik3j{|rb!F^e6T#m)^IDsyHbwVtKFMpW4K^*)te z&nd@AiQ1i6A5c&PQDz8U$TSpln|{gbQ0}45Jp(m)c)hPb6=d5Pcs&N%P{1#z_2X?Q z>2>SMR6D0nwFiu9uCnX7_Hd9&oNo`PJbnkH)PNe4 zQhAh`Zx0)IP-2KB2qRSOTzi0GpK*2{FBk-&K88w1-M4=1@ZValOFdjzLu6I)H>@&d62L7RH zjzr;q34;REvCQ3+taw+wA>GF;jd-q^LhapJ*<$mNEtpavgn@xi@r3t zj%{DrV+7d3p3|>^V`7&@_U~Hh<0~i0U{+4fz>(2FHNAq{`*vs-ju~OF$wSkBd;!Aq z+KN8;lb|JGy7uSXRO>LaDN~DriK1Yl!@iSR*rx60UICo_fv^8Gdn9G*HQui9#!+Ze zaF~Y!xEespwZNXrD^M(z{w&`%c_Xx8mRfalWpYISH1mFjH?9Nyv%E?3pF@iAPd>KU z%<3M&00Q{_$(|qnkuaIJO-I zUL%rb(8QpV!-gw2UFpT*|NgX%G@oqn0w=@NsJw?u7VDnRgWv~w8xC4Lp{|{08SYs9 zBAUFJX$JF0K92YvurnW~eHMgQyy90#OYtAENo30Me+3DO?f}-Rze`d!Qp08gVjXX8 zq}!krq-+iQ5H>otE&^EcT=44-au0!JWEdO(tJ`VQb(twYia~ygp>=LK+Gmg@Ao~c= z0Y$+zJ~pn31z1Rk`Z6&0>e%qdK|zM7heC}tBr$qa9VKqB;J%FNSXuB58l@j}L`x4U zbhKGZ9mY7hx&G?dwcwUFUq@}-77Esk)a3}WY4@zuHk$sH7NDdjL+Gk(W?-)sf1oG@?y&UO(=6i4?U}zslpyfEwt1 zLqb9eh&RSt_|EZmXx?V*F`kDJcRQkXBDF(3tVY?I+9h|E%Oh5IOx=N4(vjP|Wejp= zb|>I6vB#rP8)}A}_g<>VD)N*p$ntWoPy- z$-SGcNZBK*fZTgF_^X`5NP$U z;|E&cGT1m)w@&jh3!?OzUf5q;Y53Sbs0MJZJHA(&m*Shr7*Q@PQ!M@xshEoaY7-fw z)!G>kun?E&5sqA83DjI(2)RjOU6BIBMKC#}GDu~EJ{d<&a{7^z?~G(Xf1RNBtu%nN zdBg_+c9TjY5juRNv{`Ok^};@AwoGU$U>NQyteMODhBQz#0u46N-@@~zvFg8xyuZR> zQU}Omk#e~XTdmQ~Kx3S38EL}qxzITVT$m;7MOiK|=i zOYbA-|C8RD?307gg<}3CNAnxJZ5mP<#Qo1XBCazV>kI)PmVK)=n2ZSpZa;|ow;RM* zJO~c%I8>>w!CXD>1szc1r~+V&&R{w*>9EGA%-9emXEwYOZw_3p@GrwzKF&*)>LEXwx`#sGaEF=^?!R zADl}Let)l^k51?CP5eg=lLTaGJa8JnG-YU!oMv61Qb@HeI4KUb`eK{M0vD?HGtg?y zjp?y&t)d0+TqCFuie+P5G5relKGZ|K#;X3xb6DgiY;iNYD!4B}A21Obh*?^OUlLu-bKCGhf?(eo{=S_ZzuAM)q*4!;B!5armwylmiJ^dJ z<(*uBjT6!?9gEcVB56r{q+5Gpy$2gpU;&Wpgvc*!X`C#07cQSHcmWf3sh^FZX;H4` z?Vq-VK+h<_O>0m80rDnd zWR0a-_a?{^-r;w-K@;Sn(QmV<4*CT-f|snRb|`Lg)NbwA)Z`Ydplru_F;ZAmgU7eU z1=JWu@?sMm-m$qgYy^VBusKh~q3Pq$DfaF3f4Cid4y)fELzlC=EC9aQ0voCS46Y9u z>5teT@@m;Wi0vyFd=a^*FcUOkPv2I%qiG1bz_Hu{01yodW^s@GFK=%Pg#G|Pz^u6N zJj!wRl=iu3nu3%b{hPMMl-sBwT9x7%t1sd1SRwRM%5m2YTjClZbo#%dliQC0nqWNM zV)4Nkk;6`pCfF$frIH+oE_(iI#uOUEblj*f8&x>fsK9PcBjQE>D)Z?|&{OjA zrO5jtUd8n3`kMZAzWgVAnYkc%|EJ9O7rgy8Z~vM%D%7Df*J#xAzvc7q@J7u{|9jqk zkGJ2)EzAi{5ny9z`#j)Oe45F z97QBEKvM|!g`vwcw|=+_Q5ah?MF!vl?mYZ{6gvr))(wAq~To5sy@Wj8IO9d%&@%YaY7TJ zx7bw(a7qKxI?@{90;?hb#i%8a3Ovdtd$*)VL`-5uBWehWqR?s*RUJhWgNV(c>gYHY z3>eyu49r=E50KvSRm4KU-wjJ-zPiwiLJ4|$i4KFPhM27Jxv5oXs8mMdLss$OHJlrP zAgIkpdh7G%BuQM$%nFrXQL(_NV-R6l$*C3`7^lf^W`b>w%KDltVbMOR#TOQ6V1;u3CornsYPjOFRcOW_MJJBh0VoSB& zXwUrw z*yWiCSS7?5&h6tw$F+*L0(L8v~{B7tcWoI4$R1@v%83ftOYxZ2PQ!5nQOj6nV5oQu{|xo4}4OdvvwS#GgE zt&8*o1K7(#m=&>z9^kPu=QtTCV$53OzoMi5_FM`~2mFjoCT3F!H;cQC&*wjjW$t@$ zYS8)xJMhi<2DA_#wssM5NI_0d42)s8JjvYy>@seN*pe7Ad}QIF!V@xr9wh-{IN3q} zkb3%0P?a9y4mvb*xTiO)8`cJboZhpeJ#^^l5Y11c=nQtuv)C`jkrtdvYarrFZ>K1} zhoW=n=R@k8_UFb^t%F*(B)9u4~g_L zJ0*(eTC(qAutv?6ZDQ+Pglp@abk`x*dKV6Ay_Z1+@6u1KvYb2*qcP?!%mr*>;?4`E!+k#ho1OaD zjS}^23Sj6Xyip(0e}o%e{V~%Y@kTHW!1(G?r1ayvOi=*P&MkdS6E6C)O zI0_E64I97Mca>i#4)U8*{TrACU_W2}CK^7EP~I{_CumSd2VJn>l2s4x^}_j=XG{QR z^qG<+tgeE9TQU*`%d?JECm$hkKXKuu7mqaS++~)%Z=8~bg=ZRg6(_H;)$W=gGHlNy z1ew8QvdqX^O#Fo_l|@h|AC&3DpcPCoN4)eUFdGZKd=>Fq61Gj{Jkno~Z8VossU0*3 zc&P+!oF9UTmi-0vI^W=y2pKRp>mz^>5E;R#rrlEMxQU-WX?_lwpTqo6g814I=rAPk#L8u1Gyl#Ru;lR#b$ zjnX<&zEq>hsCC)GS5L<0C>d2?4t<$7REUFsDjYObQF(k2nAS=6+P4dOa=ED6XlCRm~VJcSd<`9uNGDs2*Iy<{+r_+ zQY*&w$1f50_zn;v<|9$m)5KOH?Saj#FNAIId<#%#zCgql5Rc2R7&QPy1T$QC9!|qh zQ~uFlG>sF&EkY&QiZS2r5ma-$#H#7e)0p^9tTLt>G=uYf5|+||Xmcd=W?5zY=dJ9; z=CNZBLoo)oh#tI~)*+L8=&_sD;VAj|WClT%SQmPbJWFD`Hc(0bRovj&9cNlzF&?(d z1`~F>i#jQ3yvQbsf;LV5MyE^eKo$Wb!?HspaZ2CQ_|9Caf>%9%lyawV`LE%&Ie27A zqKIJmnDCLT8j8Y4_%RX$Wh~*ivk4o)M@agU9E1cSxFPT55lq71hT$-KW(_+!y8H~7 zo+Pmb5U{$i7h?KzS}AJ>(Pxtp1p-LF&SigE=9T4PHVLBqOI!FF~ORwd3eW!Dc?T z@UIS|c~B}E-;Fq&Dp=LYA6CBv(L9G={{U_Xmd(=Zaozen{G|w!f&T+{TfX*_o@pJ# zGQ&15eb-oX9FW=HLNFeVNa)5@5WO15{YlrXv{UZbdaif=?Ybat*k4kIn{&P6n6uDXAZBzjpqJzja-?n3p zITei05o&DqZ|}s-fT?)F*8!i|N*#>glI$MD63ImF8CxRpFo{!%&yf*R9>iFM^~nDR%4Aw;6rJ zy36XSd?aX^y3=$i>J^$+$F?MQl0nPNbrA9(06L@M5E<9{Xf~@;3k)>{zJAUw#NTrid3ubK%Zd_YXGJzdNlwp>^afL3ped47w1dx$xOpLIN9+Z z)4YVl3A_m#l+_3OniD-ki}3();LyboFMQ@~nh8PSZ=g8|@iL3v!1yC9dcsDk<2Nee zrBC`J1DLrWr+?7(UF=o5-fn+}pWA{Xrda%K0zvM>Kt#mDf%_zYm=fR+ccLxq@g71k z^AUszri3cQ?i7N!yLXsEdQ`+TKcn}}xEq;rd(@HKEmKXhJcY|wxb;jmVs)u*$(<9P z6?ZeIIOp|o(xGfQQH*X*@&>xfn&{kql zf}DuD<7u2(P&+baQ+ysAK5B2ljjbQ*jMKL6&CZIfCJu_^G%J151e&AGV-FFKJuYcBX9&8BfN>w>SZ88w!a^f?QUxf(VR&e3FU&# z0HZx#0#xY)SWOdla7%oUpOMs9Ldyx2eE+uS1kGo+~Os9FLO7I?LOpvn`7e^A3vdFBj{id z@))sn`@2Vp(2wpOzJ=lyPEP#CG_Nzbq%j;el8x-+@W4g;h3{Ji^e8+<;Q1EHZwBi3 zkoO$`rT;q;tvkBGfM}*Pz(NM#$sf}_os&l_r4YnqzsJZ~C^ZAelV+fQqr66J#I_oM z?2vso>Aq*KP3Y3(z_wgrldKRXLHwGHwjuV}!M>z~Q{00hzso6L7CFWK^q8}^e>AQ6 z#t0|tSuiAen-GtMKS;ly!ovk~$mq+=xAkAd&$D=Q6Ti~Yg=fuX<8ykFS%}e0=^3W# zxZ%4JYZB2-sPPppI9#x8!p$|Bi>WBkn_p&bEX%1LIo}iZ!$vcw$4zW>Mox9;J~lFl z;|e$8ad3J!9>kBv^@*2@ z{kEGPLuxcVx)c9HqeEla{X4O9JLK*i%a4sZeYTa~=X^VVz|P><6aJm=;eHDr;`=C< zw*NSXfU)6>{XILIziGFeTYT4Z+4+y|emuJeMEF^I59_0a?=xhVE!b$mMhjz^{P*l9 YoLe|rb!!wCe{p!~qv46+$3}<$FYr<5f&c&j literal 0 HcmV?d00001 diff --git a/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc b/website/.venv/lib/python3.10/site-packages/jinja2/__pycache__/visitor.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..41d8593e3851b3972b3f74684d54f0689377a85d GIT binary patch literal 3975 zcma)9TaVku6(%WC;&LzXx`DGc;$Yeau+@t;P1A=0Y2n2-O^p_c;a#|>l9b|dMk}r< zQl6o9y{Z-{uY%gzpQoEFw&4dM*K^s6X0!426zipfZ28F99Yfu@sqtr4@EE6qR`Q)(k97{ zMbTGc@8D2mxm2bl9u9`78mO#LQXHN0Y@82wi@Rk~zq=|=k4l=Y`))vs2?NN2GF?bD0mN;Z9h+t7=&4y-Ti_7_&uEnTD1 zp7t=R>m(W^C{HZ@+urTx1GQ@+6ZfOt*!<|d-7|FrE7Wf5RAr~TX>znXJTLlr_QTc> z-rJ>_?+>H+X>_d2?n#oJMDOpOlG(X#4bMwI3}e_Ih8x(zkd>}IzP036Yr3S}Y|#2F z8mKTVgD@QAa+K2ZMi@RDMQJsoYtT~KMOoX+&NT{a!T!n<+Dnt;>$o`rzV)unBd^cT z5!TN0)8YJ3A@tay|$*--Tp6dcPMNo0*m&h7ZGonMz5m|v5d$m&+PPIbZ&$aQoV zA^CNbJ~do%(UC!g#)UBFSrI))xhh4~Cn$#EDy*V6%D4axm$X7bp9caLl?R4KnQRGh zi1J?jU=W>)s$#@xl#Y}UXZ-s^V7cUeuGM#czAtjK$;h?c|tgIq+Sd#KNUo@8+T zyj!`)-_If-&hk+zSC1pOaJ8D0cxJ3Fo%%n?4FNFV~MAynud zt0KJer#ssVx*qmm#7b0!dY+h~N=C$1vZnisaTeWno~dq=J%s*D=_Ic9=*|?v(2;>v zNoEQaA<&f6s#OU^#sCqqJ>DE;)wA~Jlw)c(|D)ZhEK%??CiO#rQhJ+UwC6X(y? zUmWRN)=-PJ@!uaae7rJ)6=3#Z6&DtwS2-b)#W1juWavT^is?rbvkc0k0+Bb0x4Ck@ z@_H6sk(imL)gX}mvR=jWGE^MUAo2jQ0Xl=*>p5@dljx3o@s)Da(yA8Z)1RQ zXvZ7B)t+}^YhleC8J7Y}K_ygSTz!CtiS@#o*e~r1cj8KWWa~F4?!-Q}C(d8($5vuZ zYJao;WFKJN34*^m-gL$l#G}-??A!3-EhsKGmrA7RE%-J=?b7befxB|l;}Crt8VprT z;P}ohd&e1XFFML=RvaVe*s<^6VPe0qURpo1KHq|CWW0Obc-wjgmr+B`_{T(0RJL3e z>iIBD;-r{W^%SiZ3uNwYc>@HZ!?>TMGNc$7eFp}-#^YeV?waeG3Y{p{P<%F=JGT43 z@$E&omm=D323$4z4XoBTAj(D<$~+E3rWekF-loZ$B*-S-Vqse@GNzhuV3u?k8uGz# zH`hhu-8D_)G47>n4Q~%{o5v8VgrmHZx^!83$_2ULFaYvsFuBy0X1x<%xwkE>0R=I^ z1W3qw`3AXtsH4mPf(J@R|HNtFYmf}mn4cK|)=hdz91+qOLS;_N73>qO00x%ycPsih z1C4Qq)2WI`3w_M*OF&qmJoh>mB4A}&A>hCq>@-ZH7;K>NH~>1ciaeE7hcE~eNLNZL zJ;Y>F`nawXz%s=x`iy*;vfb4N6@T<}KH#l}T7fD?Mx=Qa1CirHeU`wRq_}6M7D}io z`U?)uZDHD(nphF7Am#=0kPW#`j)~MNW0LHOgBc;SoYh=KfzG3%h@OH!IVy{kFv9^& zt-jRHRAMyE{rnF+%=-DapE(!qg$FM13g^<%d&kyAed3|h?_V@9+9+xm{Qy1hP8!#H z{-QByNNZ&2=CkeTTJyoA{=%CyUfMu}Z9LcK&l6AL==n$ILtq8(NV<<$x3{9(pZKi% zv!XEp-ds9_FojRg6CCvEZ34W}K zP?;?2(Qrt=4XIM5j)ti?q`CG=aP?SsxrWLM`KVL|nL4W;P3cubJ`GVxEx-aJ0-@1Q zaGU!OH|)T6Z69(6(!p;4xnXZzjcnK(j`Mq*i|<}*EO64oL18JyOI$>_hp-~eD`BO; zyOe4JZaO9|a)A-{_;-8gwmC$g>*ps!ilD(ML>T-Ps0xpcr)Z?=1jrRilzerXV!lS} zstkC8){O*d5D~Qs{W+;RpsHQ^tXZq@RKRTgO^DZ^y`xXB#kCB$y+hJ}fDf7FcHF?J z+paUdb3J_X#jAL)@6zry5_6cRw3Y6!sDdb_3%k$3{vAxbkDK=LY4j_ofmnWr~HS7 lNrctE%9_&uu= 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 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/website/.venv/lib/python3.10/site-packages/jinja2/bccache.py b/website/.venv/lib/python3.10/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..d0ddf56 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/jinja2/compiler.py b/website/.venv/lib/python3.10/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..ff95c80 --- /dev/null +++ b/website/.venv/lib/python3.10/site-packages/jinja2/compiler.py @@ -0,0 +1,1956 @@ +"""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: # noqa: F811 + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + 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/website/.venv/lib/python3.10/site-packages/jinja2/constants.py b/website/.venv/lib/python3.10/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/jinja2/debug.py b/website/.venv/lib/python3.10/site-packages/jinja2/debug.py new file mode 100644 index 0000000..7ed7e92 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/jinja2/defaults.py b/website/.venv/lib/python3.10/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/website/.venv/lib/python3.10/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/website/.venv/lib/python3.10/site-packages/jinja2/environment.py b/website/.venv/lib/python3.10/site-packages/jinja2/environment.py new file mode 100644 index 0000000..185d332 --- /dev/null +++ b/website/.venv/lib/python3.10/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") + + @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 = "