#
tokens: 49649/50000 2/808 files (page 98/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 98 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .DS_Store
├── .venv
│   ├── __pycache__
│   │   └── hello.cpython-312.pyc
│   ├── bin
│   │   ├── activate
│   │   ├── activate.csh
│   │   ├── activate.fish
│   │   ├── Activate.ps1
│   │   ├── flask
│   │   ├── normalizer
│   │   ├── pip
│   │   ├── pip3
│   │   ├── pip3.12
│   │   ├── python
│   │   ├── python3
│   │   └── python3.12
│   ├── hello.py
│   ├── lib
│   │   └── python3.12
│   │       └── site-packages
│   │           ├── beautifulsoup4-4.12.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   ├── AUTHORS
│   │           │   │   └── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   └── WHEEL
│   │           ├── blinker
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _utilities.cpython-312.pyc
│   │           │   │   └── base.cpython-312.pyc
│   │           │   ├── _utilities.py
│   │           │   ├── base.py
│   │           │   └── py.typed
│   │           ├── blinker-1.8.2.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── bs4
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── css.cpython-312.pyc
│   │           │   │   ├── dammit.cpython-312.pyc
│   │           │   │   ├── diagnose.cpython-312.pyc
│   │           │   │   ├── element.cpython-312.pyc
│   │           │   │   └── formatter.cpython-312.pyc
│   │           │   ├── builder
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── _html5lib.cpython-312.pyc
│   │           │   │   │   ├── _htmlparser.cpython-312.pyc
│   │           │   │   │   └── _lxml.cpython-312.pyc
│   │           │   │   ├── _html5lib.py
│   │           │   │   ├── _htmlparser.py
│   │           │   │   └── _lxml.py
│   │           │   ├── css.py
│   │           │   ├── dammit.py
│   │           │   ├── diagnose.py
│   │           │   ├── element.py
│   │           │   ├── formatter.py
│   │           │   └── tests
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   ├── __init__.cpython-312.pyc
│   │           │       │   ├── test_builder_registry.cpython-312.pyc
│   │           │       │   ├── test_builder.cpython-312.pyc
│   │           │       │   ├── test_css.cpython-312.pyc
│   │           │       │   ├── test_dammit.cpython-312.pyc
│   │           │       │   ├── test_docs.cpython-312.pyc
│   │           │       │   ├── test_element.cpython-312.pyc
│   │           │       │   ├── test_formatter.cpython-312.pyc
│   │           │       │   ├── test_fuzz.cpython-312.pyc
│   │           │       │   ├── test_html5lib.cpython-312.pyc
│   │           │       │   ├── test_htmlparser.cpython-312.pyc
│   │           │       │   ├── test_lxml.cpython-312.pyc
│   │           │       │   ├── test_navigablestring.cpython-312.pyc
│   │           │       │   ├── test_pageelement.cpython-312.pyc
│   │           │       │   ├── test_soup.cpython-312.pyc
│   │           │       │   ├── test_tag.cpython-312.pyc
│   │           │       │   └── test_tree.cpython-312.pyc
│   │           │       ├── fuzz
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│   │           │       │   ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│   │           │       │   └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│   │           │       ├── test_builder_registry.py
│   │           │       ├── test_builder.py
│   │           │       ├── test_css.py
│   │           │       ├── test_dammit.py
│   │           │       ├── test_docs.py
│   │           │       ├── test_element.py
│   │           │       ├── test_formatter.py
│   │           │       ├── test_fuzz.py
│   │           │       ├── test_html5lib.py
│   │           │       ├── test_htmlparser.py
│   │           │       ├── test_lxml.py
│   │           │       ├── test_navigablestring.py
│   │           │       ├── test_pageelement.py
│   │           │       ├── test_soup.py
│   │           │       ├── test_tag.py
│   │           │       └── test_tree.py
│   │           ├── certifi
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   └── core.cpython-312.pyc
│   │           │   ├── cacert.pem
│   │           │   ├── core.py
│   │           │   └── py.typed
│   │           ├── certifi-2024.8.30.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── charset_normalizer
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   ├── api.cpython-312.pyc
│   │           │   │   ├── cd.cpython-312.pyc
│   │           │   │   ├── constant.cpython-312.pyc
│   │           │   │   ├── legacy.cpython-312.pyc
│   │           │   │   ├── md.cpython-312.pyc
│   │           │   │   ├── models.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── version.cpython-312.pyc
│   │           │   ├── api.py
│   │           │   ├── cd.py
│   │           │   ├── cli
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __main__.py
│   │           │   │   └── __pycache__
│   │           │   │       ├── __init__.cpython-312.pyc
│   │           │   │       └── __main__.cpython-312.pyc
│   │           │   ├── constant.py
│   │           │   ├── legacy.py
│   │           │   ├── md__mypyc.cpython-312-darwin.so
│   │           │   ├── md.cpython-312-darwin.so
│   │           │   ├── md.py
│   │           │   ├── models.py
│   │           │   ├── py.typed
│   │           │   ├── utils.py
│   │           │   └── version.py
│   │           ├── charset_normalizer-3.4.0.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── click
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _compat.cpython-312.pyc
│   │           │   │   ├── _termui_impl.cpython-312.pyc
│   │           │   │   ├── _textwrap.cpython-312.pyc
│   │           │   │   ├── _winconsole.cpython-312.pyc
│   │           │   │   ├── core.cpython-312.pyc
│   │           │   │   ├── decorators.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── formatting.cpython-312.pyc
│   │           │   │   ├── globals.cpython-312.pyc
│   │           │   │   ├── parser.cpython-312.pyc
│   │           │   │   ├── shell_completion.cpython-312.pyc
│   │           │   │   ├── termui.cpython-312.pyc
│   │           │   │   ├── testing.cpython-312.pyc
│   │           │   │   ├── types.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── _compat.py
│   │           │   ├── _termui_impl.py
│   │           │   ├── _textwrap.py
│   │           │   ├── _winconsole.py
│   │           │   ├── core.py
│   │           │   ├── decorators.py
│   │           │   ├── exceptions.py
│   │           │   ├── formatting.py
│   │           │   ├── globals.py
│   │           │   ├── parser.py
│   │           │   ├── py.typed
│   │           │   ├── shell_completion.py
│   │           │   ├── termui.py
│   │           │   ├── testing.py
│   │           │   ├── types.py
│   │           │   └── utils.py
│   │           ├── click-8.1.7.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.rst
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── fake_useragent
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── errors.cpython-312.pyc
│   │           │   │   ├── fake.cpython-312.pyc
│   │           │   │   ├── log.cpython-312.pyc
│   │           │   │   ├── settings.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── data
│   │           │   │   └── browsers.json
│   │           │   ├── errors.py
│   │           │   ├── fake.py
│   │           │   ├── log.py
│   │           │   ├── settings.py
│   │           │   └── utils.py
│   │           ├── fake_useragent-1.5.1.dist-info
│   │           │   ├── AUTHORS
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── flask
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   ├── app.cpython-312.pyc
│   │           │   │   ├── blueprints.cpython-312.pyc
│   │           │   │   ├── cli.cpython-312.pyc
│   │           │   │   ├── config.cpython-312.pyc
│   │           │   │   ├── ctx.cpython-312.pyc
│   │           │   │   ├── debughelpers.cpython-312.pyc
│   │           │   │   ├── globals.cpython-312.pyc
│   │           │   │   ├── helpers.cpython-312.pyc
│   │           │   │   ├── logging.cpython-312.pyc
│   │           │   │   ├── sessions.cpython-312.pyc
│   │           │   │   ├── signals.cpython-312.pyc
│   │           │   │   ├── templating.cpython-312.pyc
│   │           │   │   ├── testing.cpython-312.pyc
│   │           │   │   ├── typing.cpython-312.pyc
│   │           │   │   ├── views.cpython-312.pyc
│   │           │   │   └── wrappers.cpython-312.pyc
│   │           │   ├── app.py
│   │           │   ├── blueprints.py
│   │           │   ├── cli.py
│   │           │   ├── config.py
│   │           │   ├── ctx.py
│   │           │   ├── debughelpers.py
│   │           │   ├── globals.py
│   │           │   ├── helpers.py
│   │           │   ├── json
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── provider.cpython-312.pyc
│   │           │   │   │   └── tag.cpython-312.pyc
│   │           │   │   ├── provider.py
│   │           │   │   └── tag.py
│   │           │   ├── logging.py
│   │           │   ├── py.typed
│   │           │   ├── sansio
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── app.cpython-312.pyc
│   │           │   │   │   ├── blueprints.cpython-312.pyc
│   │           │   │   │   └── scaffold.cpython-312.pyc
│   │           │   │   ├── app.py
│   │           │   │   ├── blueprints.py
│   │           │   │   ├── README.md
│   │           │   │   └── scaffold.py
│   │           │   ├── sessions.py
│   │           │   ├── signals.py
│   │           │   ├── templating.py
│   │           │   ├── testing.py
│   │           │   ├── typing.py
│   │           │   ├── views.py
│   │           │   └── wrappers.py
│   │           ├── flask-3.0.3.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   └── WHEEL
│   │           ├── idna
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── codec.cpython-312.pyc
│   │           │   │   ├── compat.cpython-312.pyc
│   │           │   │   ├── core.cpython-312.pyc
│   │           │   │   ├── idnadata.cpython-312.pyc
│   │           │   │   ├── intranges.cpython-312.pyc
│   │           │   │   ├── package_data.cpython-312.pyc
│   │           │   │   └── uts46data.cpython-312.pyc
│   │           │   ├── codec.py
│   │           │   ├── compat.py
│   │           │   ├── core.py
│   │           │   ├── idnadata.py
│   │           │   ├── intranges.py
│   │           │   ├── package_data.py
│   │           │   ├── py.typed
│   │           │   └── uts46data.py
│   │           ├── idna-3.10.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.md
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── itsdangerous
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _json.cpython-312.pyc
│   │           │   │   ├── encoding.cpython-312.pyc
│   │           │   │   ├── exc.cpython-312.pyc
│   │           │   │   ├── serializer.cpython-312.pyc
│   │           │   │   ├── signer.cpython-312.pyc
│   │           │   │   ├── timed.cpython-312.pyc
│   │           │   │   └── url_safe.cpython-312.pyc
│   │           │   ├── _json.py
│   │           │   ├── encoding.py
│   │           │   ├── exc.py
│   │           │   ├── py.typed
│   │           │   ├── serializer.py
│   │           │   ├── signer.py
│   │           │   ├── timed.py
│   │           │   └── url_safe.py
│   │           ├── itsdangerous-2.2.0.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── jinja2
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _identifier.cpython-312.pyc
│   │           │   │   ├── async_utils.cpython-312.pyc
│   │           │   │   ├── bccache.cpython-312.pyc
│   │           │   │   ├── compiler.cpython-312.pyc
│   │           │   │   ├── constants.cpython-312.pyc
│   │           │   │   ├── debug.cpython-312.pyc
│   │           │   │   ├── defaults.cpython-312.pyc
│   │           │   │   ├── environment.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── ext.cpython-312.pyc
│   │           │   │   ├── filters.cpython-312.pyc
│   │           │   │   ├── idtracking.cpython-312.pyc
│   │           │   │   ├── lexer.cpython-312.pyc
│   │           │   │   ├── loaders.cpython-312.pyc
│   │           │   │   ├── meta.cpython-312.pyc
│   │           │   │   ├── nativetypes.cpython-312.pyc
│   │           │   │   ├── nodes.cpython-312.pyc
│   │           │   │   ├── optimizer.cpython-312.pyc
│   │           │   │   ├── parser.cpython-312.pyc
│   │           │   │   ├── runtime.cpython-312.pyc
│   │           │   │   ├── sandbox.cpython-312.pyc
│   │           │   │   ├── tests.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── visitor.cpython-312.pyc
│   │           │   ├── _identifier.py
│   │           │   ├── async_utils.py
│   │           │   ├── bccache.py
│   │           │   ├── compiler.py
│   │           │   ├── constants.py
│   │           │   ├── debug.py
│   │           │   ├── defaults.py
│   │           │   ├── environment.py
│   │           │   ├── exceptions.py
│   │           │   ├── ext.py
│   │           │   ├── filters.py
│   │           │   ├── idtracking.py
│   │           │   ├── lexer.py
│   │           │   ├── loaders.py
│   │           │   ├── meta.py
│   │           │   ├── nativetypes.py
│   │           │   ├── nodes.py
│   │           │   ├── optimizer.py
│   │           │   ├── parser.py
│   │           │   ├── py.typed
│   │           │   ├── runtime.py
│   │           │   ├── sandbox.py
│   │           │   ├── tests.py
│   │           │   ├── utils.py
│   │           │   └── visitor.py
│   │           ├── jinja2-3.1.4.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── lxml
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _elementpath.cpython-312.pyc
│   │           │   │   ├── builder.cpython-312.pyc
│   │           │   │   ├── cssselect.cpython-312.pyc
│   │           │   │   ├── doctestcompare.cpython-312.pyc
│   │           │   │   ├── ElementInclude.cpython-312.pyc
│   │           │   │   ├── pyclasslookup.cpython-312.pyc
│   │           │   │   ├── sax.cpython-312.pyc
│   │           │   │   └── usedoctest.cpython-312.pyc
│   │           │   ├── _elementpath.cpython-312-darwin.so
│   │           │   ├── _elementpath.py
│   │           │   ├── apihelpers.pxi
│   │           │   ├── builder.cpython-312-darwin.so
│   │           │   ├── builder.py
│   │           │   ├── classlookup.pxi
│   │           │   ├── cleanup.pxi
│   │           │   ├── cssselect.py
│   │           │   ├── debug.pxi
│   │           │   ├── docloader.pxi
│   │           │   ├── doctestcompare.py
│   │           │   ├── dtd.pxi
│   │           │   ├── ElementInclude.py
│   │           │   ├── etree_api.h
│   │           │   ├── etree.cpython-312-darwin.so
│   │           │   ├── etree.h
│   │           │   ├── etree.pyx
│   │           │   ├── extensions.pxi
│   │           │   ├── html
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── _diffcommand.cpython-312.pyc
│   │           │   │   │   ├── _html5builder.cpython-312.pyc
│   │           │   │   │   ├── _setmixin.cpython-312.pyc
│   │           │   │   │   ├── builder.cpython-312.pyc
│   │           │   │   │   ├── clean.cpython-312.pyc
│   │           │   │   │   ├── defs.cpython-312.pyc
│   │           │   │   │   ├── diff.cpython-312.pyc
│   │           │   │   │   ├── ElementSoup.cpython-312.pyc
│   │           │   │   │   ├── formfill.cpython-312.pyc
│   │           │   │   │   ├── html5parser.cpython-312.pyc
│   │           │   │   │   ├── soupparser.cpython-312.pyc
│   │           │   │   │   └── usedoctest.cpython-312.pyc
│   │           │   │   ├── _diffcommand.py
│   │           │   │   ├── _html5builder.py
│   │           │   │   ├── _setmixin.py
│   │           │   │   ├── builder.py
│   │           │   │   ├── clean.py
│   │           │   │   ├── defs.py
│   │           │   │   ├── diff.cpython-312-darwin.so
│   │           │   │   ├── diff.py
│   │           │   │   ├── ElementSoup.py
│   │           │   │   ├── formfill.py
│   │           │   │   ├── html5parser.py
│   │           │   │   ├── soupparser.py
│   │           │   │   └── usedoctest.py
│   │           │   ├── includes
│   │           │   │   ├── __init__.pxd
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   ├── c14n.pxd
│   │           │   │   ├── config.pxd
│   │           │   │   ├── dtdvalid.pxd
│   │           │   │   ├── etree_defs.h
│   │           │   │   ├── etreepublic.pxd
│   │           │   │   ├── extlibs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── libcharset.h
│   │           │   │   │   ├── localcharset.h
│   │           │   │   │   ├── zconf.h
│   │           │   │   │   └── zlib.h
│   │           │   │   ├── htmlparser.pxd
│   │           │   │   ├── libexslt
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── exslt.h
│   │           │   │   │   ├── exsltconfig.h
│   │           │   │   │   └── exsltexports.h
│   │           │   │   ├── libxml
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── c14n.h
│   │           │   │   │   ├── catalog.h
│   │           │   │   │   ├── chvalid.h
│   │           │   │   │   ├── debugXML.h
│   │           │   │   │   ├── dict.h
│   │           │   │   │   ├── encoding.h
│   │           │   │   │   ├── entities.h
│   │           │   │   │   ├── globals.h
│   │           │   │   │   ├── hash.h
│   │           │   │   │   ├── HTMLparser.h
│   │           │   │   │   ├── HTMLtree.h
│   │           │   │   │   ├── list.h
│   │           │   │   │   ├── nanoftp.h
│   │           │   │   │   ├── nanohttp.h
│   │           │   │   │   ├── parser.h
│   │           │   │   │   ├── parserInternals.h
│   │           │   │   │   ├── relaxng.h
│   │           │   │   │   ├── SAX.h
│   │           │   │   │   ├── SAX2.h
│   │           │   │   │   ├── schemasInternals.h
│   │           │   │   │   ├── schematron.h
│   │           │   │   │   ├── threads.h
│   │           │   │   │   ├── tree.h
│   │           │   │   │   ├── uri.h
│   │           │   │   │   ├── valid.h
│   │           │   │   │   ├── xinclude.h
│   │           │   │   │   ├── xlink.h
│   │           │   │   │   ├── xmlautomata.h
│   │           │   │   │   ├── xmlerror.h
│   │           │   │   │   ├── xmlexports.h
│   │           │   │   │   ├── xmlIO.h
│   │           │   │   │   ├── xmlmemory.h
│   │           │   │   │   ├── xmlmodule.h
│   │           │   │   │   ├── xmlreader.h
│   │           │   │   │   ├── xmlregexp.h
│   │           │   │   │   ├── xmlsave.h
│   │           │   │   │   ├── xmlschemas.h
│   │           │   │   │   ├── xmlschemastypes.h
│   │           │   │   │   ├── xmlstring.h
│   │           │   │   │   ├── xmlunicode.h
│   │           │   │   │   ├── xmlversion.h
│   │           │   │   │   ├── xmlwriter.h
│   │           │   │   │   ├── xpath.h
│   │           │   │   │   ├── xpathInternals.h
│   │           │   │   │   └── xpointer.h
│   │           │   │   ├── libxslt
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── attributes.h
│   │           │   │   │   ├── documents.h
│   │           │   │   │   ├── extensions.h
│   │           │   │   │   ├── extra.h
│   │           │   │   │   ├── functions.h
│   │           │   │   │   ├── imports.h
│   │           │   │   │   ├── keys.h
│   │           │   │   │   ├── namespaces.h
│   │           │   │   │   ├── numbersInternals.h
│   │           │   │   │   ├── pattern.h
│   │           │   │   │   ├── preproc.h
│   │           │   │   │   ├── security.h
│   │           │   │   │   ├── templates.h
│   │           │   │   │   ├── transform.h
│   │           │   │   │   ├── variables.h
│   │           │   │   │   ├── xslt.h
│   │           │   │   │   ├── xsltconfig.h
│   │           │   │   │   ├── xsltexports.h
│   │           │   │   │   ├── xsltInternals.h
│   │           │   │   │   ├── xsltlocale.h
│   │           │   │   │   └── xsltutils.h
│   │           │   │   ├── lxml-version.h
│   │           │   │   ├── relaxng.pxd
│   │           │   │   ├── schematron.pxd
│   │           │   │   ├── tree.pxd
│   │           │   │   ├── uri.pxd
│   │           │   │   ├── xinclude.pxd
│   │           │   │   ├── xmlerror.pxd
│   │           │   │   ├── xmlparser.pxd
│   │           │   │   ├── xmlschema.pxd
│   │           │   │   ├── xpath.pxd
│   │           │   │   └── xslt.pxd
│   │           │   ├── isoschematron
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   └── resources
│   │           │   │       ├── rng
│   │           │   │       │   └── iso-schematron.rng
│   │           │   │       └── xsl
│   │           │   │           ├── iso-schematron-xslt1
│   │           │   │           │   ├── iso_abstract_expand.xsl
│   │           │   │           │   ├── iso_dsdl_include.xsl
│   │           │   │           │   ├── iso_schematron_message.xsl
│   │           │   │           │   ├── iso_schematron_skeleton_for_xslt1.xsl
│   │           │   │           │   ├── iso_svrl_for_xslt1.xsl
│   │           │   │           │   └── readme.txt
│   │           │   │           ├── RNG2Schtrn.xsl
│   │           │   │           └── XSD2Schtrn.xsl
│   │           │   ├── iterparse.pxi
│   │           │   ├── lxml.etree_api.h
│   │           │   ├── lxml.etree.h
│   │           │   ├── nsclasses.pxi
│   │           │   ├── objectify.cpython-312-darwin.so
│   │           │   ├── objectify.pyx
│   │           │   ├── objectpath.pxi
│   │           │   ├── parser.pxi
│   │           │   ├── parsertarget.pxi
│   │           │   ├── proxy.pxi
│   │           │   ├── public-api.pxi
│   │           │   ├── pyclasslookup.py
│   │           │   ├── readonlytree.pxi
│   │           │   ├── relaxng.pxi
│   │           │   ├── sax.cpython-312-darwin.so
│   │           │   ├── sax.py
│   │           │   ├── saxparser.pxi
│   │           │   ├── schematron.pxi
│   │           │   ├── serializer.pxi
│   │           │   ├── usedoctest.py
│   │           │   ├── xinclude.pxi
│   │           │   ├── xmlerror.pxi
│   │           │   ├── xmlid.pxi
│   │           │   ├── xmlschema.pxi
│   │           │   ├── xpath.pxi
│   │           │   ├── xslt.pxi
│   │           │   └── xsltext.pxi
│   │           ├── lxml-5.3.0.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── LICENSES.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── markupsafe
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   └── _native.cpython-312.pyc
│   │           │   ├── _native.py
│   │           │   ├── _speedups.c
│   │           │   ├── _speedups.cpython-312-darwin.so
│   │           │   ├── _speedups.pyi
│   │           │   └── py.typed
│   │           ├── MarkupSafe-3.0.1.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── pip
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pip-runner__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   └── __pip-runner__.cpython-312.pyc
│   │           │   ├── _internal
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── build_env.cpython-312.pyc
│   │           │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   ├── configuration.cpython-312.pyc
│   │           │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   ├── main.cpython-312.pyc
│   │           │   │   │   ├── pyproject.cpython-312.pyc
│   │           │   │   │   ├── self_outdated_check.cpython-312.pyc
│   │           │   │   │   └── wheel_builder.cpython-312.pyc
│   │           │   │   ├── build_env.py
│   │           │   │   ├── cache.py
│   │           │   │   ├── cli
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── autocompletion.cpython-312.pyc
│   │           │   │   │   │   ├── base_command.cpython-312.pyc
│   │           │   │   │   │   ├── cmdoptions.cpython-312.pyc
│   │           │   │   │   │   ├── command_context.cpython-312.pyc
│   │           │   │   │   │   ├── index_command.cpython-312.pyc
│   │           │   │   │   │   ├── main_parser.cpython-312.pyc
│   │           │   │   │   │   ├── main.cpython-312.pyc
│   │           │   │   │   │   ├── parser.cpython-312.pyc
│   │           │   │   │   │   ├── progress_bars.cpython-312.pyc
│   │           │   │   │   │   ├── req_command.cpython-312.pyc
│   │           │   │   │   │   ├── spinners.cpython-312.pyc
│   │           │   │   │   │   └── status_codes.cpython-312.pyc
│   │           │   │   │   ├── autocompletion.py
│   │           │   │   │   ├── base_command.py
│   │           │   │   │   ├── cmdoptions.py
│   │           │   │   │   ├── command_context.py
│   │           │   │   │   ├── index_command.py
│   │           │   │   │   ├── main_parser.py
│   │           │   │   │   ├── main.py
│   │           │   │   │   ├── parser.py
│   │           │   │   │   ├── progress_bars.py
│   │           │   │   │   ├── req_command.py
│   │           │   │   │   ├── spinners.py
│   │           │   │   │   └── status_codes.py
│   │           │   │   ├── commands
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── check.cpython-312.pyc
│   │           │   │   │   │   ├── completion.cpython-312.pyc
│   │           │   │   │   │   ├── configuration.cpython-312.pyc
│   │           │   │   │   │   ├── debug.cpython-312.pyc
│   │           │   │   │   │   ├── download.cpython-312.pyc
│   │           │   │   │   │   ├── freeze.cpython-312.pyc
│   │           │   │   │   │   ├── hash.cpython-312.pyc
│   │           │   │   │   │   ├── help.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── inspect.cpython-312.pyc
│   │           │   │   │   │   ├── install.cpython-312.pyc
│   │           │   │   │   │   ├── list.cpython-312.pyc
│   │           │   │   │   │   ├── search.cpython-312.pyc
│   │           │   │   │   │   ├── show.cpython-312.pyc
│   │           │   │   │   │   ├── uninstall.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── check.py
│   │           │   │   │   ├── completion.py
│   │           │   │   │   ├── configuration.py
│   │           │   │   │   ├── debug.py
│   │           │   │   │   ├── download.py
│   │           │   │   │   ├── freeze.py
│   │           │   │   │   ├── hash.py
│   │           │   │   │   ├── help.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── inspect.py
│   │           │   │   │   ├── install.py
│   │           │   │   │   ├── list.py
│   │           │   │   │   ├── search.py
│   │           │   │   │   ├── show.py
│   │           │   │   │   ├── uninstall.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── configuration.py
│   │           │   │   ├── distributions
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── base.cpython-312.pyc
│   │           │   │   │   │   ├── installed.cpython-312.pyc
│   │           │   │   │   │   ├── sdist.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── installed.py
│   │           │   │   │   ├── sdist.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── exceptions.py
│   │           │   │   ├── index
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── collector.cpython-312.pyc
│   │           │   │   │   │   ├── package_finder.cpython-312.pyc
│   │           │   │   │   │   └── sources.cpython-312.pyc
│   │           │   │   │   ├── collector.py
│   │           │   │   │   ├── package_finder.py
│   │           │   │   │   └── sources.py
│   │           │   │   ├── locations
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _distutils.cpython-312.pyc
│   │           │   │   │   │   ├── _sysconfig.cpython-312.pyc
│   │           │   │   │   │   └── base.cpython-312.pyc
│   │           │   │   │   ├── _distutils.py
│   │           │   │   │   ├── _sysconfig.py
│   │           │   │   │   └── base.py
│   │           │   │   ├── main.py
│   │           │   │   ├── metadata
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _json.cpython-312.pyc
│   │           │   │   │   │   ├── base.cpython-312.pyc
│   │           │   │   │   │   └── pkg_resources.cpython-312.pyc
│   │           │   │   │   ├── _json.py
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── importlib
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _compat.cpython-312.pyc
│   │           │   │   │   │   │   ├── _dists.cpython-312.pyc
│   │           │   │   │   │   │   └── _envs.cpython-312.pyc
│   │           │   │   │   │   ├── _compat.py
│   │           │   │   │   │   ├── _dists.py
│   │           │   │   │   │   └── _envs.py
│   │           │   │   │   └── pkg_resources.py
│   │           │   │   ├── models
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── candidate.cpython-312.pyc
│   │           │   │   │   │   ├── direct_url.cpython-312.pyc
│   │           │   │   │   │   ├── format_control.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── installation_report.cpython-312.pyc
│   │           │   │   │   │   ├── link.cpython-312.pyc
│   │           │   │   │   │   ├── scheme.cpython-312.pyc
│   │           │   │   │   │   ├── search_scope.cpython-312.pyc
│   │           │   │   │   │   ├── selection_prefs.cpython-312.pyc
│   │           │   │   │   │   ├── target_python.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── candidate.py
│   │           │   │   │   ├── direct_url.py
│   │           │   │   │   ├── format_control.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── installation_report.py
│   │           │   │   │   ├── link.py
│   │           │   │   │   ├── scheme.py
│   │           │   │   │   ├── search_scope.py
│   │           │   │   │   ├── selection_prefs.py
│   │           │   │   │   ├── target_python.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── network
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── download.cpython-312.pyc
│   │           │   │   │   │   ├── lazy_wheel.cpython-312.pyc
│   │           │   │   │   │   ├── session.cpython-312.pyc
│   │           │   │   │   │   ├── utils.cpython-312.pyc
│   │           │   │   │   │   └── xmlrpc.cpython-312.pyc
│   │           │   │   │   ├── auth.py
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── download.py
│   │           │   │   │   ├── lazy_wheel.py
│   │           │   │   │   ├── session.py
│   │           │   │   │   ├── utils.py
│   │           │   │   │   └── xmlrpc.py
│   │           │   │   ├── operations
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── check.cpython-312.pyc
│   │           │   │   │   │   ├── freeze.cpython-312.pyc
│   │           │   │   │   │   └── prepare.cpython-312.pyc
│   │           │   │   │   ├── build
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── build_tracker.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata_editable.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata_legacy.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   │   ├── wheel_editable.cpython-312.pyc
│   │           │   │   │   │   │   ├── wheel_legacy.cpython-312.pyc
│   │           │   │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   │   ├── build_tracker.py
│   │           │   │   │   │   ├── metadata_editable.py
│   │           │   │   │   │   ├── metadata_legacy.py
│   │           │   │   │   │   ├── metadata.py
│   │           │   │   │   │   ├── wheel_editable.py
│   │           │   │   │   │   ├── wheel_legacy.py
│   │           │   │   │   │   └── wheel.py
│   │           │   │   │   ├── check.py
│   │           │   │   │   ├── freeze.py
│   │           │   │   │   ├── install
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── editable_legacy.cpython-312.pyc
│   │           │   │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   │   ├── editable_legacy.py
│   │           │   │   │   │   └── wheel.py
│   │           │   │   │   └── prepare.py
│   │           │   │   ├── pyproject.py
│   │           │   │   ├── req
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── constructors.cpython-312.pyc
│   │           │   │   │   │   ├── req_file.cpython-312.pyc
│   │           │   │   │   │   ├── req_install.cpython-312.pyc
│   │           │   │   │   │   ├── req_set.cpython-312.pyc
│   │           │   │   │   │   └── req_uninstall.cpython-312.pyc
│   │           │   │   │   ├── constructors.py
│   │           │   │   │   ├── req_file.py
│   │           │   │   │   ├── req_install.py
│   │           │   │   │   ├── req_set.py
│   │           │   │   │   └── req_uninstall.py
│   │           │   │   ├── resolution
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   └── base.cpython-312.pyc
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── legacy
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── resolver.cpython-312.pyc
│   │           │   │   │   │   └── resolver.py
│   │           │   │   │   └── resolvelib
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   ├── base.cpython-312.pyc
│   │           │   │   │       │   ├── candidates.cpython-312.pyc
│   │           │   │   │       │   ├── factory.cpython-312.pyc
│   │           │   │   │       │   ├── found_candidates.cpython-312.pyc
│   │           │   │   │       │   ├── provider.cpython-312.pyc
│   │           │   │   │       │   ├── reporter.cpython-312.pyc
│   │           │   │   │       │   ├── requirements.cpython-312.pyc
│   │           │   │   │       │   └── resolver.cpython-312.pyc
│   │           │   │   │       ├── base.py
│   │           │   │   │       ├── candidates.py
│   │           │   │   │       ├── factory.py
│   │           │   │   │       ├── found_candidates.py
│   │           │   │   │       ├── provider.py
│   │           │   │   │       ├── reporter.py
│   │           │   │   │       ├── requirements.py
│   │           │   │   │       └── resolver.py
│   │           │   │   ├── self_outdated_check.py
│   │           │   │   ├── utils
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _jaraco_text.cpython-312.pyc
│   │           │   │   │   │   ├── _log.cpython-312.pyc
│   │           │   │   │   │   ├── appdirs.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── compatibility_tags.cpython-312.pyc
│   │           │   │   │   │   ├── datetime.cpython-312.pyc
│   │           │   │   │   │   ├── deprecation.cpython-312.pyc
│   │           │   │   │   │   ├── direct_url_helpers.cpython-312.pyc
│   │           │   │   │   │   ├── egg_link.cpython-312.pyc
│   │           │   │   │   │   ├── encoding.cpython-312.pyc
│   │           │   │   │   │   ├── entrypoints.cpython-312.pyc
│   │           │   │   │   │   ├── filesystem.cpython-312.pyc
│   │           │   │   │   │   ├── filetypes.cpython-312.pyc
│   │           │   │   │   │   ├── glibc.cpython-312.pyc
│   │           │   │   │   │   ├── hashes.cpython-312.pyc
│   │           │   │   │   │   ├── logging.cpython-312.pyc
│   │           │   │   │   │   ├── misc.cpython-312.pyc
│   │           │   │   │   │   ├── packaging.cpython-312.pyc
│   │           │   │   │   │   ├── retry.cpython-312.pyc
│   │           │   │   │   │   ├── setuptools_build.cpython-312.pyc
│   │           │   │   │   │   ├── subprocess.cpython-312.pyc
│   │           │   │   │   │   ├── temp_dir.cpython-312.pyc
│   │           │   │   │   │   ├── unpacking.cpython-312.pyc
│   │           │   │   │   │   ├── urls.cpython-312.pyc
│   │           │   │   │   │   ├── virtualenv.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── _jaraco_text.py
│   │           │   │   │   ├── _log.py
│   │           │   │   │   ├── appdirs.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── compatibility_tags.py
│   │           │   │   │   ├── datetime.py
│   │           │   │   │   ├── deprecation.py
│   │           │   │   │   ├── direct_url_helpers.py
│   │           │   │   │   ├── egg_link.py
│   │           │   │   │   ├── encoding.py
│   │           │   │   │   ├── entrypoints.py
│   │           │   │   │   ├── filesystem.py
│   │           │   │   │   ├── filetypes.py
│   │           │   │   │   ├── glibc.py
│   │           │   │   │   ├── hashes.py
│   │           │   │   │   ├── logging.py
│   │           │   │   │   ├── misc.py
│   │           │   │   │   ├── packaging.py
│   │           │   │   │   ├── retry.py
│   │           │   │   │   ├── setuptools_build.py
│   │           │   │   │   ├── subprocess.py
│   │           │   │   │   ├── temp_dir.py
│   │           │   │   │   ├── unpacking.py
│   │           │   │   │   ├── urls.py
│   │           │   │   │   ├── virtualenv.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── vcs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── bazaar.cpython-312.pyc
│   │           │   │   │   │   ├── git.cpython-312.pyc
│   │           │   │   │   │   ├── mercurial.cpython-312.pyc
│   │           │   │   │   │   ├── subversion.cpython-312.pyc
│   │           │   │   │   │   └── versioncontrol.cpython-312.pyc
│   │           │   │   │   ├── bazaar.py
│   │           │   │   │   ├── git.py
│   │           │   │   │   ├── mercurial.py
│   │           │   │   │   ├── subversion.py
│   │           │   │   │   └── versioncontrol.py
│   │           │   │   └── wheel_builder.py
│   │           │   ├── _vendor
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   └── typing_extensions.cpython-312.pyc
│   │           │   │   ├── cachecontrol
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _cmd.cpython-312.pyc
│   │           │   │   │   │   ├── adapter.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── controller.cpython-312.pyc
│   │           │   │   │   │   ├── filewrapper.cpython-312.pyc
│   │           │   │   │   │   ├── heuristics.cpython-312.pyc
│   │           │   │   │   │   ├── serialize.cpython-312.pyc
│   │           │   │   │   │   └── wrapper.cpython-312.pyc
│   │           │   │   │   ├── _cmd.py
│   │           │   │   │   ├── adapter.py
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── caches
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── file_cache.cpython-312.pyc
│   │           │   │   │   │   │   └── redis_cache.cpython-312.pyc
│   │           │   │   │   │   ├── file_cache.py
│   │           │   │   │   │   └── redis_cache.py
│   │           │   │   │   ├── controller.py
│   │           │   │   │   ├── filewrapper.py
│   │           │   │   │   ├── heuristics.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── serialize.py
│   │           │   │   │   └── wrapper.py
│   │           │   │   ├── certifi
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   └── core.cpython-312.pyc
│   │           │   │   │   ├── cacert.pem
│   │           │   │   │   ├── core.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── distlib
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── database.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── locators.cpython-312.pyc
│   │           │   │   │   │   ├── manifest.cpython-312.pyc
│   │           │   │   │   │   ├── markers.cpython-312.pyc
│   │           │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   ├── resources.cpython-312.pyc
│   │           │   │   │   │   ├── scripts.cpython-312.pyc
│   │           │   │   │   │   ├── util.cpython-312.pyc
│   │           │   │   │   │   ├── version.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── database.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── locators.py
│   │           │   │   │   ├── manifest.py
│   │           │   │   │   ├── markers.py
│   │           │   │   │   ├── metadata.py
│   │           │   │   │   ├── resources.py
│   │           │   │   │   ├── scripts.py
│   │           │   │   │   ├── t32.exe
│   │           │   │   │   ├── t64-arm.exe
│   │           │   │   │   ├── t64.exe
│   │           │   │   │   ├── util.py
│   │           │   │   │   ├── version.py
│   │           │   │   │   ├── w32.exe
│   │           │   │   │   ├── w64-arm.exe
│   │           │   │   │   ├── w64.exe
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── distro
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   └── distro.cpython-312.pyc
│   │           │   │   │   ├── distro.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── idna
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── codec.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── core.cpython-312.pyc
│   │           │   │   │   │   ├── idnadata.cpython-312.pyc
│   │           │   │   │   │   ├── intranges.cpython-312.pyc
│   │           │   │   │   │   ├── package_data.cpython-312.pyc
│   │           │   │   │   │   └── uts46data.cpython-312.pyc
│   │           │   │   │   ├── codec.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── core.py
│   │           │   │   │   ├── idnadata.py
│   │           │   │   │   ├── intranges.py
│   │           │   │   │   ├── package_data.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   └── uts46data.py
│   │           │   │   ├── msgpack
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── ext.cpython-312.pyc
│   │           │   │   │   │   └── fallback.cpython-312.pyc
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── ext.py
│   │           │   │   │   └── fallback.py
│   │           │   │   ├── packaging
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _elffile.cpython-312.pyc
│   │           │   │   │   │   ├── _manylinux.cpython-312.pyc
│   │           │   │   │   │   ├── _musllinux.cpython-312.pyc
│   │           │   │   │   │   ├── _parser.cpython-312.pyc
│   │           │   │   │   │   ├── _structures.cpython-312.pyc
│   │           │   │   │   │   ├── _tokenizer.cpython-312.pyc
│   │           │   │   │   │   ├── markers.cpython-312.pyc
│   │           │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   ├── requirements.cpython-312.pyc
│   │           │   │   │   │   ├── specifiers.cpython-312.pyc
│   │           │   │   │   │   ├── tags.cpython-312.pyc
│   │           │   │   │   │   ├── utils.cpython-312.pyc
│   │           │   │   │   │   └── version.cpython-312.pyc
│   │           │   │   │   ├── _elffile.py
│   │           │   │   │   ├── _manylinux.py
│   │           │   │   │   ├── _musllinux.py
│   │           │   │   │   ├── _parser.py
│   │           │   │   │   ├── _structures.py
│   │           │   │   │   ├── _tokenizer.py
│   │           │   │   │   ├── markers.py
│   │           │   │   │   ├── metadata.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── requirements.py
│   │           │   │   │   ├── specifiers.py
│   │           │   │   │   ├── tags.py
│   │           │   │   │   ├── utils.py
│   │           │   │   │   └── version.py
│   │           │   │   ├── pkg_resources
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   └── __pycache__
│   │           │   │   │       └── __init__.cpython-312.pyc
│   │           │   │   ├── platformdirs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── android.cpython-312.pyc
│   │           │   │   │   │   ├── api.cpython-312.pyc
│   │           │   │   │   │   ├── macos.cpython-312.pyc
│   │           │   │   │   │   ├── unix.cpython-312.pyc
│   │           │   │   │   │   ├── version.cpython-312.pyc
│   │           │   │   │   │   └── windows.cpython-312.pyc
│   │           │   │   │   ├── android.py
│   │           │   │   │   ├── api.py
│   │           │   │   │   ├── macos.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── unix.py
│   │           │   │   │   ├── version.py
│   │           │   │   │   └── windows.py
│   │           │   │   ├── pygments
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── cmdline.cpython-312.pyc
│   │           │   │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   │   ├── filter.cpython-312.pyc
│   │           │   │   │   │   ├── formatter.cpython-312.pyc
│   │           │   │   │   │   ├── lexer.cpython-312.pyc
│   │           │   │   │   │   ├── modeline.cpython-312.pyc
│   │           │   │   │   │   ├── plugin.cpython-312.pyc
│   │           │   │   │   │   ├── regexopt.cpython-312.pyc
│   │           │   │   │   │   ├── scanner.cpython-312.pyc
│   │           │   │   │   │   ├── sphinxext.cpython-312.pyc
│   │           │   │   │   │   ├── style.cpython-312.pyc
│   │           │   │   │   │   ├── token.cpython-312.pyc
│   │           │   │   │   │   ├── unistring.cpython-312.pyc
│   │           │   │   │   │   └── util.cpython-312.pyc
│   │           │   │   │   ├── cmdline.py
│   │           │   │   │   ├── console.py
│   │           │   │   │   ├── filter.py
│   │           │   │   │   ├── filters
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   └── __pycache__
│   │           │   │   │   │       └── __init__.cpython-312.pyc
│   │           │   │   │   ├── formatter.py
│   │           │   │   │   ├── formatters
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _mapping.cpython-312.pyc
│   │           │   │   │   │   │   ├── bbcode.cpython-312.pyc
│   │           │   │   │   │   │   ├── groff.cpython-312.pyc
│   │           │   │   │   │   │   ├── html.cpython-312.pyc
│   │           │   │   │   │   │   ├── img.cpython-312.pyc
│   │           │   │   │   │   │   ├── irc.cpython-312.pyc
│   │           │   │   │   │   │   ├── latex.cpython-312.pyc
│   │           │   │   │   │   │   ├── other.cpython-312.pyc
│   │           │   │   │   │   │   ├── pangomarkup.cpython-312.pyc
│   │           │   │   │   │   │   ├── rtf.cpython-312.pyc
│   │           │   │   │   │   │   ├── svg.cpython-312.pyc
│   │           │   │   │   │   │   ├── terminal.cpython-312.pyc
│   │           │   │   │   │   │   └── terminal256.cpython-312.pyc
│   │           │   │   │   │   ├── _mapping.py
│   │           │   │   │   │   ├── bbcode.py
│   │           │   │   │   │   ├── groff.py
│   │           │   │   │   │   ├── html.py
│   │           │   │   │   │   ├── img.py
│   │           │   │   │   │   ├── irc.py
│   │           │   │   │   │   ├── latex.py
│   │           │   │   │   │   ├── other.py
│   │           │   │   │   │   ├── pangomarkup.py
│   │           │   │   │   │   ├── rtf.py
│   │           │   │   │   │   ├── svg.py
│   │           │   │   │   │   ├── terminal.py
│   │           │   │   │   │   └── terminal256.py
│   │           │   │   │   ├── lexer.py
│   │           │   │   │   ├── lexers
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _mapping.cpython-312.pyc
│   │           │   │   │   │   │   └── python.cpython-312.pyc
│   │           │   │   │   │   ├── _mapping.py
│   │           │   │   │   │   └── python.py
│   │           │   │   │   ├── modeline.py
│   │           │   │   │   ├── plugin.py
│   │           │   │   │   ├── regexopt.py
│   │           │   │   │   ├── scanner.py
│   │           │   │   │   ├── sphinxext.py
│   │           │   │   │   ├── style.py
│   │           │   │   │   ├── styles
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── _mapping.cpython-312.pyc
│   │           │   │   │   │   └── _mapping.py
│   │           │   │   │   ├── token.py
│   │           │   │   │   ├── unistring.py
│   │           │   │   │   └── util.py
│   │           │   │   ├── pyproject_hooks
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _compat.cpython-312.pyc
│   │           │   │   │   │   └── _impl.cpython-312.pyc
│   │           │   │   │   ├── _compat.py
│   │           │   │   │   ├── _impl.py
│   │           │   │   │   └── _in_process
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   └── _in_process.cpython-312.pyc
│   │           │   │   │       └── _in_process.py
│   │           │   │   ├── requests
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __version__.cpython-312.pyc
│   │           │   │   │   │   ├── _internal_utils.cpython-312.pyc
│   │           │   │   │   │   ├── adapters.cpython-312.pyc
│   │           │   │   │   │   ├── api.cpython-312.pyc
│   │           │   │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   │   ├── certs.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── cookies.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── help.cpython-312.pyc
│   │           │   │   │   │   ├── hooks.cpython-312.pyc
│   │           │   │   │   │   ├── models.cpython-312.pyc
│   │           │   │   │   │   ├── packages.cpython-312.pyc
│   │           │   │   │   │   ├── sessions.cpython-312.pyc
│   │           │   │   │   │   ├── status_codes.cpython-312.pyc
│   │           │   │   │   │   ├── structures.cpython-312.pyc
│   │           │   │   │   │   └── utils.cpython-312.pyc
│   │           │   │   │   ├── __version__.py
│   │           │   │   │   ├── _internal_utils.py
│   │           │   │   │   ├── adapters.py
│   │           │   │   │   ├── api.py
│   │           │   │   │   ├── auth.py
│   │           │   │   │   ├── certs.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── cookies.py
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── help.py
│   │           │   │   │   ├── hooks.py
│   │           │   │   │   ├── models.py
│   │           │   │   │   ├── packages.py
│   │           │   │   │   ├── sessions.py
│   │           │   │   │   ├── status_codes.py
│   │           │   │   │   ├── structures.py
│   │           │   │   │   └── utils.py
│   │           │   │   ├── resolvelib
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── providers.cpython-312.pyc
│   │           │   │   │   │   ├── reporters.cpython-312.pyc
│   │           │   │   │   │   ├── resolvers.cpython-312.pyc
│   │           │   │   │   │   └── structs.cpython-312.pyc
│   │           │   │   │   ├── compat
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── collections_abc.cpython-312.pyc
│   │           │   │   │   │   └── collections_abc.py
│   │           │   │   │   ├── providers.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── reporters.py
│   │           │   │   │   ├── resolvers.py
│   │           │   │   │   └── structs.py
│   │           │   │   ├── rich
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── _cell_widths.cpython-312.pyc
│   │           │   │   │   │   ├── _emoji_codes.cpython-312.pyc
│   │           │   │   │   │   ├── _emoji_replace.cpython-312.pyc
│   │           │   │   │   │   ├── _export_format.cpython-312.pyc
│   │           │   │   │   │   ├── _extension.cpython-312.pyc
│   │           │   │   │   │   ├── _fileno.cpython-312.pyc
│   │           │   │   │   │   ├── _inspect.cpython-312.pyc
│   │           │   │   │   │   ├── _log_render.cpython-312.pyc
│   │           │   │   │   │   ├── _loop.cpython-312.pyc
│   │           │   │   │   │   ├── _null_file.cpython-312.pyc
│   │           │   │   │   │   ├── _palettes.cpython-312.pyc
│   │           │   │   │   │   ├── _pick.cpython-312.pyc
│   │           │   │   │   │   ├── _ratio.cpython-312.pyc
│   │           │   │   │   │   ├── _spinners.cpython-312.pyc
│   │           │   │   │   │   ├── _stack.cpython-312.pyc
│   │           │   │   │   │   ├── _timer.cpython-312.pyc
│   │           │   │   │   │   ├── _win32_console.cpython-312.pyc
│   │           │   │   │   │   ├── _windows_renderer.cpython-312.pyc
│   │           │   │   │   │   ├── _windows.cpython-312.pyc
│   │           │   │   │   │   ├── _wrap.cpython-312.pyc
│   │           │   │   │   │   ├── abc.cpython-312.pyc
│   │           │   │   │   │   ├── align.cpython-312.pyc
│   │           │   │   │   │   ├── ansi.cpython-312.pyc
│   │           │   │   │   │   ├── bar.cpython-312.pyc
│   │           │   │   │   │   ├── box.cpython-312.pyc
│   │           │   │   │   │   ├── cells.cpython-312.pyc
│   │           │   │   │   │   ├── color_triplet.cpython-312.pyc
│   │           │   │   │   │   ├── color.cpython-312.pyc
│   │           │   │   │   │   ├── columns.cpython-312.pyc
│   │           │   │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   │   ├── constrain.cpython-312.pyc
│   │           │   │   │   │   ├── containers.cpython-312.pyc
│   │           │   │   │   │   ├── control.cpython-312.pyc
│   │           │   │   │   │   ├── default_styles.cpython-312.pyc
│   │           │   │   │   │   ├── diagnose.cpython-312.pyc
│   │           │   │   │   │   ├── emoji.cpython-312.pyc
│   │           │   │   │   │   ├── errors.cpython-312.pyc
│   │           │   │   │   │   ├── file_proxy.cpython-312.pyc
│   │           │   │   │   │   ├── filesize.cpython-312.pyc
│   │           │   │   │   │   ├── highlighter.cpython-312.pyc
│   │           │   │   │   │   ├── json.cpython-312.pyc
│   │           │   │   │   │   ├── jupyter.cpython-312.pyc
│   │           │   │   │   │   ├── layout.cpython-312.pyc
│   │           │   │   │   │   ├── live_render.cpython-312.pyc
│   │           │   │   │   │   ├── live.cpython-312.pyc
│   │           │   │   │   │   ├── logging.cpython-312.pyc
│   │           │   │   │   │   ├── markup.cpython-312.pyc
│   │           │   │   │   │   ├── measure.cpython-312.pyc
│   │           │   │   │   │   ├── padding.cpython-312.pyc
│   │           │   │   │   │   ├── pager.cpython-312.pyc
│   │           │   │   │   │   ├── palette.cpython-312.pyc
│   │           │   │   │   │   ├── panel.cpython-312.pyc
│   │           │   │   │   │   ├── pretty.cpython-312.pyc
│   │           │   │   │   │   ├── progress_bar.cpython-312.pyc
│   │           │   │   │   │   ├── progress.cpython-312.pyc
│   │           │   │   │   │   ├── prompt.cpython-312.pyc
│   │           │   │   │   │   ├── protocol.cpython-312.pyc
│   │           │   │   │   │   ├── region.cpython-312.pyc
│   │           │   │   │   │   ├── repr.cpython-312.pyc
│   │           │   │   │   │   ├── rule.cpython-312.pyc
│   │           │   │   │   │   ├── scope.cpython-312.pyc
│   │           │   │   │   │   ├── screen.cpython-312.pyc
│   │           │   │   │   │   ├── segment.cpython-312.pyc
│   │           │   │   │   │   ├── spinner.cpython-312.pyc
│   │           │   │   │   │   ├── status.cpython-312.pyc
│   │           │   │   │   │   ├── style.cpython-312.pyc
│   │           │   │   │   │   ├── styled.cpython-312.pyc
│   │           │   │   │   │   ├── syntax.cpython-312.pyc
│   │           │   │   │   │   ├── table.cpython-312.pyc
│   │           │   │   │   │   ├── terminal_theme.cpython-312.pyc
│   │           │   │   │   │   ├── text.cpython-312.pyc
│   │           │   │   │   │   ├── theme.cpython-312.pyc
│   │           │   │   │   │   ├── themes.cpython-312.pyc
│   │           │   │   │   │   ├── traceback.cpython-312.pyc
│   │           │   │   │   │   └── tree.cpython-312.pyc
│   │           │   │   │   ├── _cell_widths.py
│   │           │   │   │   ├── _emoji_codes.py
│   │           │   │   │   ├── _emoji_replace.py
│   │           │   │   │   ├── _export_format.py
│   │           │   │   │   ├── _extension.py
│   │           │   │   │   ├── _fileno.py
│   │           │   │   │   ├── _inspect.py
│   │           │   │   │   ├── _log_render.py
│   │           │   │   │   ├── _loop.py
│   │           │   │   │   ├── _null_file.py
│   │           │   │   │   ├── _palettes.py
│   │           │   │   │   ├── _pick.py
│   │           │   │   │   ├── _ratio.py
│   │           │   │   │   ├── _spinners.py
│   │           │   │   │   ├── _stack.py
│   │           │   │   │   ├── _timer.py
│   │           │   │   │   ├── _win32_console.py
│   │           │   │   │   ├── _windows_renderer.py
│   │           │   │   │   ├── _windows.py
│   │           │   │   │   ├── _wrap.py
│   │           │   │   │   ├── abc.py
│   │           │   │   │   ├── align.py
│   │           │   │   │   ├── ansi.py
│   │           │   │   │   ├── bar.py
│   │           │   │   │   ├── box.py
│   │           │   │   │   ├── cells.py
│   │           │   │   │   ├── color_triplet.py
│   │           │   │   │   ├── color.py
│   │           │   │   │   ├── columns.py
│   │           │   │   │   ├── console.py
│   │           │   │   │   ├── constrain.py
│   │           │   │   │   ├── containers.py
│   │           │   │   │   ├── control.py
│   │           │   │   │   ├── default_styles.py
│   │           │   │   │   ├── diagnose.py
│   │           │   │   │   ├── emoji.py
│   │           │   │   │   ├── errors.py
│   │           │   │   │   ├── file_proxy.py
│   │           │   │   │   ├── filesize.py
│   │           │   │   │   ├── highlighter.py
│   │           │   │   │   ├── json.py
│   │           │   │   │   ├── jupyter.py
│   │           │   │   │   ├── layout.py
│   │           │   │   │   ├── live_render.py
│   │           │   │   │   ├── live.py
│   │           │   │   │   ├── logging.py
│   │           │   │   │   ├── markup.py
│   │           │   │   │   ├── measure.py
│   │           │   │   │   ├── padding.py
│   │           │   │   │   ├── pager.py
│   │           │   │   │   ├── palette.py
│   │           │   │   │   ├── panel.py
│   │           │   │   │   ├── pretty.py
│   │           │   │   │   ├── progress_bar.py
│   │           │   │   │   ├── progress.py
│   │           │   │   │   ├── prompt.py
│   │           │   │   │   ├── protocol.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── region.py
│   │           │   │   │   ├── repr.py
│   │           │   │   │   ├── rule.py
│   │           │   │   │   ├── scope.py
│   │           │   │   │   ├── screen.py
│   │           │   │   │   ├── segment.py
│   │           │   │   │   ├── spinner.py
│   │           │   │   │   ├── status.py
│   │           │   │   │   ├── style.py
│   │           │   │   │   ├── styled.py
│   │           │   │   │   ├── syntax.py
│   │           │   │   │   ├── table.py
│   │           │   │   │   ├── terminal_theme.py
│   │           │   │   │   ├── text.py
│   │           │   │   │   ├── theme.py
│   │           │   │   │   ├── themes.py
│   │           │   │   │   ├── traceback.py
│   │           │   │   │   └── tree.py
│   │           │   │   ├── tomli
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _parser.cpython-312.pyc
│   │           │   │   │   │   ├── _re.cpython-312.pyc
│   │           │   │   │   │   └── _types.cpython-312.pyc
│   │           │   │   │   ├── _parser.py
│   │           │   │   │   ├── _re.py
│   │           │   │   │   ├── _types.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── truststore
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _api.cpython-312.pyc
│   │           │   │   │   │   ├── _macos.cpython-312.pyc
│   │           │   │   │   │   ├── _openssl.cpython-312.pyc
│   │           │   │   │   │   ├── _ssl_constants.cpython-312.pyc
│   │           │   │   │   │   └── _windows.cpython-312.pyc
│   │           │   │   │   ├── _api.py
│   │           │   │   │   ├── _macos.py
│   │           │   │   │   ├── _openssl.py
│   │           │   │   │   ├── _ssl_constants.py
│   │           │   │   │   ├── _windows.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── typing_extensions.py
│   │           │   │   ├── urllib3
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _collections.cpython-312.pyc
│   │           │   │   │   │   ├── _version.cpython-312.pyc
│   │           │   │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   │   ├── connectionpool.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── fields.cpython-312.pyc
│   │           │   │   │   │   ├── filepost.cpython-312.pyc
│   │           │   │   │   │   ├── poolmanager.cpython-312.pyc
│   │           │   │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   │   └── response.cpython-312.pyc
│   │           │   │   │   ├── _collections.py
│   │           │   │   │   ├── _version.py
│   │           │   │   │   ├── connection.py
│   │           │   │   │   ├── connectionpool.py
│   │           │   │   │   ├── contrib
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _appengine_environ.cpython-312.pyc
│   │           │   │   │   │   │   ├── appengine.cpython-312.pyc
│   │           │   │   │   │   │   ├── ntlmpool.cpython-312.pyc
│   │           │   │   │   │   │   ├── pyopenssl.cpython-312.pyc
│   │           │   │   │   │   │   ├── securetransport.cpython-312.pyc
│   │           │   │   │   │   │   └── socks.cpython-312.pyc
│   │           │   │   │   │   ├── _appengine_environ.py
│   │           │   │   │   │   ├── _securetransport
│   │           │   │   │   │   │   ├── __init__.py
│   │           │   │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   │   ├── bindings.cpython-312.pyc
│   │           │   │   │   │   │   │   └── low_level.cpython-312.pyc
│   │           │   │   │   │   │   ├── bindings.py
│   │           │   │   │   │   │   └── low_level.py
│   │           │   │   │   │   ├── appengine.py
│   │           │   │   │   │   ├── ntlmpool.py
│   │           │   │   │   │   ├── pyopenssl.py
│   │           │   │   │   │   ├── securetransport.py
│   │           │   │   │   │   └── socks.py
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── fields.py
│   │           │   │   │   ├── filepost.py
│   │           │   │   │   ├── packages
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── six.cpython-312.pyc
│   │           │   │   │   │   ├── backports
│   │           │   │   │   │   │   ├── __init__.py
│   │           │   │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   │   ├── makefile.cpython-312.pyc
│   │           │   │   │   │   │   │   └── weakref_finalize.cpython-312.pyc
│   │           │   │   │   │   │   ├── makefile.py
│   │           │   │   │   │   │   └── weakref_finalize.py
│   │           │   │   │   │   └── six.py
│   │           │   │   │   ├── poolmanager.py
│   │           │   │   │   ├── request.py
│   │           │   │   │   ├── response.py
│   │           │   │   │   └── util
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   ├── connection.cpython-312.pyc
│   │           │   │   │       │   ├── proxy.cpython-312.pyc
│   │           │   │   │       │   ├── queue.cpython-312.pyc
│   │           │   │   │       │   ├── request.cpython-312.pyc
│   │           │   │   │       │   ├── response.cpython-312.pyc
│   │           │   │   │       │   ├── retry.cpython-312.pyc
│   │           │   │   │       │   ├── ssl_.cpython-312.pyc
│   │           │   │   │       │   ├── ssl_match_hostname.cpython-312.pyc
│   │           │   │   │       │   ├── ssltransport.cpython-312.pyc
│   │           │   │   │       │   ├── timeout.cpython-312.pyc
│   │           │   │   │       │   ├── url.cpython-312.pyc
│   │           │   │   │       │   └── wait.cpython-312.pyc
│   │           │   │   │       ├── connection.py
│   │           │   │   │       ├── proxy.py
│   │           │   │   │       ├── queue.py
│   │           │   │   │       ├── request.py
│   │           │   │   │       ├── response.py
│   │           │   │   │       ├── retry.py
│   │           │   │   │       ├── ssl_.py
│   │           │   │   │       ├── ssl_match_hostname.py
│   │           │   │   │       ├── ssltransport.py
│   │           │   │   │       ├── timeout.py
│   │           │   │   │       ├── url.py
│   │           │   │   │       └── wait.py
│   │           │   │   └── vendor.txt
│   │           │   └── py.typed
│   │           ├── pip-24.2.dist-info
│   │           │   ├── AUTHORS.txt
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── requests
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __version__.cpython-312.pyc
│   │           │   │   ├── _internal_utils.cpython-312.pyc
│   │           │   │   ├── adapters.cpython-312.pyc
│   │           │   │   ├── api.cpython-312.pyc
│   │           │   │   ├── auth.cpython-312.pyc
│   │           │   │   ├── certs.cpython-312.pyc
│   │           │   │   ├── compat.cpython-312.pyc
│   │           │   │   ├── cookies.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── help.cpython-312.pyc
│   │           │   │   ├── hooks.cpython-312.pyc
│   │           │   │   ├── models.cpython-312.pyc
│   │           │   │   ├── packages.cpython-312.pyc
│   │           │   │   ├── sessions.cpython-312.pyc
│   │           │   │   ├── status_codes.cpython-312.pyc
│   │           │   │   ├── structures.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── __version__.py
│   │           │   ├── _internal_utils.py
│   │           │   ├── adapters.py
│   │           │   ├── api.py
│   │           │   ├── auth.py
│   │           │   ├── certs.py
│   │           │   ├── compat.py
│   │           │   ├── cookies.py
│   │           │   ├── exceptions.py
│   │           │   ├── help.py
│   │           │   ├── hooks.py
│   │           │   ├── models.py
│   │           │   ├── packages.py
│   │           │   ├── sessions.py
│   │           │   ├── status_codes.py
│   │           │   ├── structures.py
│   │           │   └── utils.py
│   │           ├── requests-2.32.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── soupsieve
│   │           │   ├── __init__.py
│   │           │   ├── __meta__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __meta__.cpython-312.pyc
│   │           │   │   ├── css_match.cpython-312.pyc
│   │           │   │   ├── css_parser.cpython-312.pyc
│   │           │   │   ├── css_types.cpython-312.pyc
│   │           │   │   ├── pretty.cpython-312.pyc
│   │           │   │   └── util.cpython-312.pyc
│   │           │   ├── css_match.py
│   │           │   ├── css_parser.py
│   │           │   ├── css_types.py
│   │           │   ├── pretty.py
│   │           │   ├── py.typed
│   │           │   └── util.py
│   │           ├── soupsieve-2.6.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   └── LICENSE.md
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── urllib3
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _base_connection.cpython-312.pyc
│   │           │   │   ├── _collections.cpython-312.pyc
│   │           │   │   ├── _request_methods.cpython-312.pyc
│   │           │   │   ├── _version.cpython-312.pyc
│   │           │   │   ├── connection.cpython-312.pyc
│   │           │   │   ├── connectionpool.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── fields.cpython-312.pyc
│   │           │   │   ├── filepost.cpython-312.pyc
│   │           │   │   ├── poolmanager.cpython-312.pyc
│   │           │   │   └── response.cpython-312.pyc
│   │           │   ├── _base_connection.py
│   │           │   ├── _collections.py
│   │           │   ├── _request_methods.py
│   │           │   ├── _version.py
│   │           │   ├── connection.py
│   │           │   ├── connectionpool.py
│   │           │   ├── contrib
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── pyopenssl.cpython-312.pyc
│   │           │   │   │   └── socks.cpython-312.pyc
│   │           │   │   ├── emscripten
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   │   ├── fetch.cpython-312.pyc
│   │           │   │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   │   └── response.cpython-312.pyc
│   │           │   │   │   ├── connection.py
│   │           │   │   │   ├── emscripten_fetch_worker.js
│   │           │   │   │   ├── fetch.py
│   │           │   │   │   ├── request.py
│   │           │   │   │   └── response.py
│   │           │   │   ├── pyopenssl.py
│   │           │   │   └── socks.py
│   │           │   ├── exceptions.py
│   │           │   ├── fields.py
│   │           │   ├── filepost.py
│   │           │   ├── http2
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   └── probe.cpython-312.pyc
│   │           │   │   ├── connection.py
│   │           │   │   └── probe.py
│   │           │   ├── poolmanager.py
│   │           │   ├── py.typed
│   │           │   ├── response.py
│   │           │   └── util
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   ├── __init__.cpython-312.pyc
│   │           │       │   ├── connection.cpython-312.pyc
│   │           │       │   ├── proxy.cpython-312.pyc
│   │           │       │   ├── request.cpython-312.pyc
│   │           │       │   ├── response.cpython-312.pyc
│   │           │       │   ├── retry.cpython-312.pyc
│   │           │       │   ├── ssl_.cpython-312.pyc
│   │           │       │   ├── ssl_match_hostname.cpython-312.pyc
│   │           │       │   ├── ssltransport.cpython-312.pyc
│   │           │       │   ├── timeout.cpython-312.pyc
│   │           │       │   ├── url.cpython-312.pyc
│   │           │       │   ├── util.cpython-312.pyc
│   │           │       │   └── wait.cpython-312.pyc
│   │           │       ├── connection.py
│   │           │       ├── proxy.py
│   │           │       ├── request.py
│   │           │       ├── response.py
│   │           │       ├── retry.py
│   │           │       ├── ssl_.py
│   │           │       ├── ssl_match_hostname.py
│   │           │       ├── ssltransport.py
│   │           │       ├── timeout.py
│   │           │       ├── url.py
│   │           │       ├── util.py
│   │           │       └── wait.py
│   │           ├── urllib3-2.2.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   └── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── useragent
│   │           │   ├── __init__.py
│   │           │   ├── __init__.pyc
│   │           │   ├── __pycache__
│   │           │   │   └── __init__.cpython-312.pyc
│   │           │   ├── resources
│   │           │   │   └── user_agent_data.json
│   │           │   └── test
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   └── __init__.cpython-312.pyc
│   │           │       ├── test_additional_os.json
│   │           │       ├── test_browser.json
│   │           │       ├── test_device.json
│   │           │       ├── test_firefox.json
│   │           │       ├── test_os.json
│   │           │       └── test_pgts_browser.json
│   │           ├── useragent-0.1.1.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── werkzeug
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _internal.cpython-312.pyc
│   │           │   │   ├── _reloader.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── formparser.cpython-312.pyc
│   │           │   │   ├── http.cpython-312.pyc
│   │           │   │   ├── local.cpython-312.pyc
│   │           │   │   ├── security.cpython-312.pyc
│   │           │   │   ├── serving.cpython-312.pyc
│   │           │   │   ├── test.cpython-312.pyc
│   │           │   │   ├── testapp.cpython-312.pyc
│   │           │   │   ├── urls.cpython-312.pyc
│   │           │   │   ├── user_agent.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── wsgi.cpython-312.pyc
│   │           │   ├── _internal.py
│   │           │   ├── _reloader.py
│   │           │   ├── datastructures
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── accept.cpython-312.pyc
│   │           │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   ├── cache_control.cpython-312.pyc
│   │           │   │   │   ├── csp.cpython-312.pyc
│   │           │   │   │   ├── etag.cpython-312.pyc
│   │           │   │   │   ├── file_storage.cpython-312.pyc
│   │           │   │   │   ├── headers.cpython-312.pyc
│   │           │   │   │   ├── mixins.cpython-312.pyc
│   │           │   │   │   ├── range.cpython-312.pyc
│   │           │   │   │   └── structures.cpython-312.pyc
│   │           │   │   ├── accept.py
│   │           │   │   ├── accept.pyi
│   │           │   │   ├── auth.py
│   │           │   │   ├── cache_control.py
│   │           │   │   ├── cache_control.pyi
│   │           │   │   ├── csp.py
│   │           │   │   ├── csp.pyi
│   │           │   │   ├── etag.py
│   │           │   │   ├── etag.pyi
│   │           │   │   ├── file_storage.py
│   │           │   │   ├── file_storage.pyi
│   │           │   │   ├── headers.py
│   │           │   │   ├── headers.pyi
│   │           │   │   ├── mixins.py
│   │           │   │   ├── mixins.pyi
│   │           │   │   ├── range.py
│   │           │   │   ├── range.pyi
│   │           │   │   ├── structures.py
│   │           │   │   └── structures.pyi
│   │           │   ├── debug
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   ├── repr.cpython-312.pyc
│   │           │   │   │   └── tbtools.cpython-312.pyc
│   │           │   │   ├── console.py
│   │           │   │   ├── repr.py
│   │           │   │   ├── shared
│   │           │   │   │   ├── console.png
│   │           │   │   │   ├── debugger.js
│   │           │   │   │   ├── ICON_LICENSE.md
│   │           │   │   │   ├── less.png
│   │           │   │   │   ├── more.png
│   │           │   │   │   └── style.css
│   │           │   │   └── tbtools.py
│   │           │   ├── exceptions.py
│   │           │   ├── formparser.py
│   │           │   ├── http.py
│   │           │   ├── local.py
│   │           │   ├── middleware
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── dispatcher.cpython-312.pyc
│   │           │   │   │   ├── http_proxy.cpython-312.pyc
│   │           │   │   │   ├── lint.cpython-312.pyc
│   │           │   │   │   ├── profiler.cpython-312.pyc
│   │           │   │   │   ├── proxy_fix.cpython-312.pyc
│   │           │   │   │   └── shared_data.cpython-312.pyc
│   │           │   │   ├── dispatcher.py
│   │           │   │   ├── http_proxy.py
│   │           │   │   ├── lint.py
│   │           │   │   ├── profiler.py
│   │           │   │   ├── proxy_fix.py
│   │           │   │   └── shared_data.py
│   │           │   ├── py.typed
│   │           │   ├── routing
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── converters.cpython-312.pyc
│   │           │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   ├── map.cpython-312.pyc
│   │           │   │   │   ├── matcher.cpython-312.pyc
│   │           │   │   │   └── rules.cpython-312.pyc
│   │           │   │   ├── converters.py
│   │           │   │   ├── exceptions.py
│   │           │   │   ├── map.py
│   │           │   │   ├── matcher.py
│   │           │   │   └── rules.py
│   │           │   ├── sansio
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── http.cpython-312.pyc
│   │           │   │   │   ├── multipart.cpython-312.pyc
│   │           │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   ├── response.cpython-312.pyc
│   │           │   │   │   └── utils.cpython-312.pyc
│   │           │   │   ├── http.py
│   │           │   │   ├── multipart.py
│   │           │   │   ├── request.py
│   │           │   │   ├── response.py
│   │           │   │   └── utils.py
│   │           │   ├── security.py
│   │           │   ├── serving.py
│   │           │   ├── test.py
│   │           │   ├── testapp.py
│   │           │   ├── urls.py
│   │           │   ├── user_agent.py
│   │           │   ├── utils.py
│   │           │   ├── wrappers
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   └── response.cpython-312.pyc
│   │           │   │   ├── request.py
│   │           │   │   └── response.py
│   │           │   └── wsgi.py
│   │           └── werkzeug-3.0.4.dist-info
│   │               ├── INSTALLER
│   │               ├── LICENSE.txt
│   │               ├── METADATA
│   │               ├── RECORD
│   │               └── WHEEL
│   ├── pyvenv.cfg
│   ├── static
│   │   └── styles.css
│   ├── templates
│   │   └── index.html
│   └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
    ├── text1.txt
    └── text2.txt
```

# Files

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/wrappers/response.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import annotations
  2 | 
  3 | import json
  4 | import typing as t
  5 | from http import HTTPStatus
  6 | from urllib.parse import urljoin
  7 | 
  8 | from .._internal import _get_environ
  9 | from ..datastructures import Headers
 10 | from ..http import generate_etag
 11 | from ..http import http_date
 12 | from ..http import is_resource_modified
 13 | from ..http import parse_etags
 14 | from ..http import parse_range_header
 15 | from ..http import remove_entity_headers
 16 | from ..sansio.response import Response as _SansIOResponse
 17 | from ..urls import iri_to_uri
 18 | from ..utils import cached_property
 19 | from ..wsgi import _RangeWrapper
 20 | from ..wsgi import ClosingIterator
 21 | from ..wsgi import get_current_url
 22 | 
 23 | if t.TYPE_CHECKING:
 24 |     from _typeshed.wsgi import StartResponse
 25 |     from _typeshed.wsgi import WSGIApplication
 26 |     from _typeshed.wsgi import WSGIEnvironment
 27 | 
 28 |     from .request import Request
 29 | 
 30 | 
 31 | def _iter_encoded(iterable: t.Iterable[str | bytes]) -> t.Iterator[bytes]:
 32 |     for item in iterable:
 33 |         if isinstance(item, str):
 34 |             yield item.encode()
 35 |         else:
 36 |             yield item
 37 | 
 38 | 
 39 | class Response(_SansIOResponse):
 40 |     """Represents an outgoing WSGI HTTP response with body, status, and
 41 |     headers. Has properties and methods for using the functionality
 42 |     defined by various HTTP specs.
 43 | 
 44 |     The response body is flexible to support different use cases. The
 45 |     simple form is passing bytes, or a string which will be encoded as
 46 |     UTF-8. Passing an iterable of bytes or strings makes this a
 47 |     streaming response. A generator is particularly useful for building
 48 |     a CSV file in memory or using SSE (Server Sent Events). A file-like
 49 |     object is also iterable, although the
 50 |     :func:`~werkzeug.utils.send_file` helper should be used in that
 51 |     case.
 52 | 
 53 |     The response object is itself a WSGI application callable. When
 54 |     called (:meth:`__call__`) with ``environ`` and ``start_response``,
 55 |     it will pass its status and headers to ``start_response`` then
 56 |     return its body as an iterable.
 57 | 
 58 |     .. code-block:: python
 59 | 
 60 |         from werkzeug.wrappers.response import Response
 61 | 
 62 |         def index():
 63 |             return Response("Hello, World!")
 64 | 
 65 |         def application(environ, start_response):
 66 |             path = environ.get("PATH_INFO") or "/"
 67 | 
 68 |             if path == "/":
 69 |                 response = index()
 70 |             else:
 71 |                 response = Response("Not Found", status=404)
 72 | 
 73 |             return response(environ, start_response)
 74 | 
 75 |     :param response: The data for the body of the response. A string or
 76 |         bytes, or tuple or list of strings or bytes, for a fixed-length
 77 |         response, or any other iterable of strings or bytes for a
 78 |         streaming response. Defaults to an empty body.
 79 |     :param status: The status code for the response. Either an int, in
 80 |         which case the default status message is added, or a string in
 81 |         the form ``{code} {message}``, like ``404 Not Found``. Defaults
 82 |         to 200.
 83 |     :param headers: A :class:`~werkzeug.datastructures.Headers` object,
 84 |         or a list of ``(key, value)`` tuples that will be converted to a
 85 |         ``Headers`` object.
 86 |     :param mimetype: The mime type (content type without charset or
 87 |         other parameters) of the response. If the value starts with
 88 |         ``text/`` (or matches some other special cases), the charset
 89 |         will be added to create the ``content_type``.
 90 |     :param content_type: The full content type of the response.
 91 |         Overrides building the value from ``mimetype``.
 92 |     :param direct_passthrough: Pass the response body directly through
 93 |         as the WSGI iterable. This can be used when the body is a binary
 94 |         file or other iterator of bytes, to skip some unnecessary
 95 |         checks. Use :func:`~werkzeug.utils.send_file` instead of setting
 96 |         this manually.
 97 | 
 98 |     .. versionchanged:: 2.1
 99 |         Old ``BaseResponse`` and mixin classes were removed.
100 | 
101 |     .. versionchanged:: 2.0
102 |         Combine ``BaseResponse`` and mixins into a single ``Response``
103 |         class.
104 | 
105 |     .. versionchanged:: 0.5
106 |         The ``direct_passthrough`` parameter was added.
107 |     """
108 | 
109 |     #: if set to `False` accessing properties on the response object will
110 |     #: not try to consume the response iterator and convert it into a list.
111 |     #:
112 |     #: .. versionadded:: 0.6.2
113 |     #:
114 |     #:    That attribute was previously called `implicit_seqence_conversion`.
115 |     #:    (Notice the typo).  If you did use this feature, you have to adapt
116 |     #:    your code to the name change.
117 |     implicit_sequence_conversion = True
118 | 
119 |     #: If a redirect ``Location`` header is a relative URL, make it an
120 |     #: absolute URL, including scheme and domain.
121 |     #:
122 |     #: .. versionchanged:: 2.1
123 |     #:     This is disabled by default, so responses will send relative
124 |     #:     redirects.
125 |     #:
126 |     #: .. versionadded:: 0.8
127 |     autocorrect_location_header = False
128 | 
129 |     #: Should this response object automatically set the content-length
130 |     #: header if possible?  This is true by default.
131 |     #:
132 |     #: .. versionadded:: 0.8
133 |     automatically_set_content_length = True
134 | 
135 |     #: The response body to send as the WSGI iterable. A list of strings
136 |     #: or bytes represents a fixed-length response, any other iterable
137 |     #: is a streaming response. Strings are encoded to bytes as UTF-8.
138 |     #:
139 |     #: Do not set to a plain string or bytes, that will cause sending
140 |     #: the response to be very inefficient as it will iterate one byte
141 |     #: at a time.
142 |     response: t.Iterable[str] | t.Iterable[bytes]
143 | 
144 |     def __init__(
145 |         self,
146 |         response: t.Iterable[bytes] | bytes | t.Iterable[str] | str | None = None,
147 |         status: int | str | HTTPStatus | None = None,
148 |         headers: t.Mapping[str, str | t.Iterable[str]]
149 |         | t.Iterable[tuple[str, str]]
150 |         | None = None,
151 |         mimetype: str | None = None,
152 |         content_type: str | None = None,
153 |         direct_passthrough: bool = False,
154 |     ) -> None:
155 |         super().__init__(
156 |             status=status,
157 |             headers=headers,
158 |             mimetype=mimetype,
159 |             content_type=content_type,
160 |         )
161 | 
162 |         #: Pass the response body directly through as the WSGI iterable.
163 |         #: This can be used when the body is a binary file or other
164 |         #: iterator of bytes, to skip some unnecessary checks. Use
165 |         #: :func:`~werkzeug.utils.send_file` instead of setting this
166 |         #: manually.
167 |         self.direct_passthrough = direct_passthrough
168 |         self._on_close: list[t.Callable[[], t.Any]] = []
169 | 
170 |         # we set the response after the headers so that if a class changes
171 |         # the charset attribute, the data is set in the correct charset.
172 |         if response is None:
173 |             self.response = []
174 |         elif isinstance(response, (str, bytes, bytearray)):
175 |             self.set_data(response)
176 |         else:
177 |             self.response = response
178 | 
179 |     def call_on_close(self, func: t.Callable[[], t.Any]) -> t.Callable[[], t.Any]:
180 |         """Adds a function to the internal list of functions that should
181 |         be called as part of closing down the response.  Since 0.7 this
182 |         function also returns the function that was passed so that this
183 |         can be used as a decorator.
184 | 
185 |         .. versionadded:: 0.6
186 |         """
187 |         self._on_close.append(func)
188 |         return func
189 | 
190 |     def __repr__(self) -> str:
191 |         if self.is_sequence:
192 |             body_info = f"{sum(map(len, self.iter_encoded()))} bytes"
193 |         else:
194 |             body_info = "streamed" if self.is_streamed else "likely-streamed"
195 |         return f"<{type(self).__name__} {body_info} [{self.status}]>"
196 | 
197 |     @classmethod
198 |     def force_type(
199 |         cls, response: Response, environ: WSGIEnvironment | None = None
200 |     ) -> Response:
201 |         """Enforce that the WSGI response is a response object of the current
202 |         type.  Werkzeug will use the :class:`Response` internally in many
203 |         situations like the exceptions.  If you call :meth:`get_response` on an
204 |         exception you will get back a regular :class:`Response` object, even
205 |         if you are using a custom subclass.
206 | 
207 |         This method can enforce a given response type, and it will also
208 |         convert arbitrary WSGI callables into response objects if an environ
209 |         is provided::
210 | 
211 |             # convert a Werkzeug response object into an instance of the
212 |             # MyResponseClass subclass.
213 |             response = MyResponseClass.force_type(response)
214 | 
215 |             # convert any WSGI application into a response object
216 |             response = MyResponseClass.force_type(response, environ)
217 | 
218 |         This is especially useful if you want to post-process responses in
219 |         the main dispatcher and use functionality provided by your subclass.
220 | 
221 |         Keep in mind that this will modify response objects in place if
222 |         possible!
223 | 
224 |         :param response: a response object or wsgi application.
225 |         :param environ: a WSGI environment object.
226 |         :return: a response object.
227 |         """
228 |         if not isinstance(response, Response):
229 |             if environ is None:
230 |                 raise TypeError(
231 |                     "cannot convert WSGI application into response"
232 |                     " objects without an environ"
233 |                 )
234 | 
235 |             from ..test import run_wsgi_app
236 | 
237 |             response = Response(*run_wsgi_app(response, environ))
238 | 
239 |         response.__class__ = cls
240 |         return response
241 | 
242 |     @classmethod
243 |     def from_app(
244 |         cls, app: WSGIApplication, environ: WSGIEnvironment, buffered: bool = False
245 |     ) -> Response:
246 |         """Create a new response object from an application output.  This
247 |         works best if you pass it an application that returns a generator all
248 |         the time.  Sometimes applications may use the `write()` callable
249 |         returned by the `start_response` function.  This tries to resolve such
250 |         edge cases automatically.  But if you don't get the expected output
251 |         you should set `buffered` to `True` which enforces buffering.
252 | 
253 |         :param app: the WSGI application to execute.
254 |         :param environ: the WSGI environment to execute against.
255 |         :param buffered: set to `True` to enforce buffering.
256 |         :return: a response object.
257 |         """
258 |         from ..test import run_wsgi_app
259 | 
260 |         return cls(*run_wsgi_app(app, environ, buffered))
261 | 
262 |     @t.overload
263 |     def get_data(self, as_text: t.Literal[False] = False) -> bytes: ...
264 | 
265 |     @t.overload
266 |     def get_data(self, as_text: t.Literal[True]) -> str: ...
267 | 
268 |     def get_data(self, as_text: bool = False) -> bytes | str:
269 |         """The string representation of the response body.  Whenever you call
270 |         this property the response iterable is encoded and flattened.  This
271 |         can lead to unwanted behavior if you stream big data.
272 | 
273 |         This behavior can be disabled by setting
274 |         :attr:`implicit_sequence_conversion` to `False`.
275 | 
276 |         If `as_text` is set to `True` the return value will be a decoded
277 |         string.
278 | 
279 |         .. versionadded:: 0.9
280 |         """
281 |         self._ensure_sequence()
282 |         rv = b"".join(self.iter_encoded())
283 | 
284 |         if as_text:
285 |             return rv.decode()
286 | 
287 |         return rv
288 | 
289 |     def set_data(self, value: bytes | str) -> None:
290 |         """Sets a new string as response.  The value must be a string or
291 |         bytes. If a string is set it's encoded to the charset of the
292 |         response (utf-8 by default).
293 | 
294 |         .. versionadded:: 0.9
295 |         """
296 |         if isinstance(value, str):
297 |             value = value.encode()
298 |         self.response = [value]
299 |         if self.automatically_set_content_length:
300 |             self.headers["Content-Length"] = str(len(value))
301 | 
302 |     data = property(
303 |         get_data,
304 |         set_data,
305 |         doc="A descriptor that calls :meth:`get_data` and :meth:`set_data`.",
306 |     )
307 | 
308 |     def calculate_content_length(self) -> int | None:
309 |         """Returns the content length if available or `None` otherwise."""
310 |         try:
311 |             self._ensure_sequence()
312 |         except RuntimeError:
313 |             return None
314 |         return sum(len(x) for x in self.iter_encoded())
315 | 
316 |     def _ensure_sequence(self, mutable: bool = False) -> None:
317 |         """This method can be called by methods that need a sequence.  If
318 |         `mutable` is true, it will also ensure that the response sequence
319 |         is a standard Python list.
320 | 
321 |         .. versionadded:: 0.6
322 |         """
323 |         if self.is_sequence:
324 |             # if we need a mutable object, we ensure it's a list.
325 |             if mutable and not isinstance(self.response, list):
326 |                 self.response = list(self.response)  # type: ignore
327 |             return
328 |         if self.direct_passthrough:
329 |             raise RuntimeError(
330 |                 "Attempted implicit sequence conversion but the"
331 |                 " response object is in direct passthrough mode."
332 |             )
333 |         if not self.implicit_sequence_conversion:
334 |             raise RuntimeError(
335 |                 "The response object required the iterable to be a"
336 |                 " sequence, but the implicit conversion was disabled."
337 |                 " Call make_sequence() yourself."
338 |             )
339 |         self.make_sequence()
340 | 
341 |     def make_sequence(self) -> None:
342 |         """Converts the response iterator in a list.  By default this happens
343 |         automatically if required.  If `implicit_sequence_conversion` is
344 |         disabled, this method is not automatically called and some properties
345 |         might raise exceptions.  This also encodes all the items.
346 | 
347 |         .. versionadded:: 0.6
348 |         """
349 |         if not self.is_sequence:
350 |             # if we consume an iterable we have to ensure that the close
351 |             # method of the iterable is called if available when we tear
352 |             # down the response
353 |             close = getattr(self.response, "close", None)
354 |             self.response = list(self.iter_encoded())
355 |             if close is not None:
356 |                 self.call_on_close(close)
357 | 
358 |     def iter_encoded(self) -> t.Iterator[bytes]:
359 |         """Iter the response encoded with the encoding of the response.
360 |         If the response object is invoked as WSGI application the return
361 |         value of this method is used as application iterator unless
362 |         :attr:`direct_passthrough` was activated.
363 |         """
364 |         # Encode in a separate function so that self.response is fetched
365 |         # early.  This allows us to wrap the response with the return
366 |         # value from get_app_iter or iter_encoded.
367 |         return _iter_encoded(self.response)
368 | 
369 |     @property
370 |     def is_streamed(self) -> bool:
371 |         """If the response is streamed (the response is not an iterable with
372 |         a length information) this property is `True`.  In this case streamed
373 |         means that there is no information about the number of iterations.
374 |         This is usually `True` if a generator is passed to the response object.
375 | 
376 |         This is useful for checking before applying some sort of post
377 |         filtering that should not take place for streamed responses.
378 |         """
379 |         try:
380 |             len(self.response)  # type: ignore
381 |         except (TypeError, AttributeError):
382 |             return True
383 |         return False
384 | 
385 |     @property
386 |     def is_sequence(self) -> bool:
387 |         """If the iterator is buffered, this property will be `True`.  A
388 |         response object will consider an iterator to be buffered if the
389 |         response attribute is a list or tuple.
390 | 
391 |         .. versionadded:: 0.6
392 |         """
393 |         return isinstance(self.response, (tuple, list))
394 | 
395 |     def close(self) -> None:
396 |         """Close the wrapped response if possible.  You can also use the object
397 |         in a with statement which will automatically close it.
398 | 
399 |         .. versionadded:: 0.9
400 |            Can now be used in a with statement.
401 |         """
402 |         if hasattr(self.response, "close"):
403 |             self.response.close()
404 |         for func in self._on_close:
405 |             func()
406 | 
407 |     def __enter__(self) -> Response:
408 |         return self
409 | 
410 |     def __exit__(self, exc_type, exc_value, tb):  # type: ignore
411 |         self.close()
412 | 
413 |     def freeze(self) -> None:
414 |         """Make the response object ready to be pickled. Does the
415 |         following:
416 | 
417 |         *   Buffer the response into a list, ignoring
418 |             :attr:`implicity_sequence_conversion` and
419 |             :attr:`direct_passthrough`.
420 |         *   Set the ``Content-Length`` header.
421 |         *   Generate an ``ETag`` header if one is not already set.
422 | 
423 |         .. versionchanged:: 2.1
424 |             Removed the ``no_etag`` parameter.
425 | 
426 |         .. versionchanged:: 2.0
427 |             An ``ETag`` header is always added.
428 | 
429 |         .. versionchanged:: 0.6
430 |             The ``Content-Length`` header is set.
431 |         """
432 |         # Always freeze the encoded response body, ignore
433 |         # implicit_sequence_conversion and direct_passthrough.
434 |         self.response = list(self.iter_encoded())
435 |         self.headers["Content-Length"] = str(sum(map(len, self.response)))
436 |         self.add_etag()
437 | 
438 |     def get_wsgi_headers(self, environ: WSGIEnvironment) -> Headers:
439 |         """This is automatically called right before the response is started
440 |         and returns headers modified for the given environment.  It returns a
441 |         copy of the headers from the response with some modifications applied
442 |         if necessary.
443 | 
444 |         For example the location header (if present) is joined with the root
445 |         URL of the environment.  Also the content length is automatically set
446 |         to zero here for certain status codes.
447 | 
448 |         .. versionchanged:: 0.6
449 |            Previously that function was called `fix_headers` and modified
450 |            the response object in place.  Also since 0.6, IRIs in location
451 |            and content-location headers are handled properly.
452 | 
453 |            Also starting with 0.6, Werkzeug will attempt to set the content
454 |            length if it is able to figure it out on its own.  This is the
455 |            case if all the strings in the response iterable are already
456 |            encoded and the iterable is buffered.
457 | 
458 |         :param environ: the WSGI environment of the request.
459 |         :return: returns a new :class:`~werkzeug.datastructures.Headers`
460 |                  object.
461 |         """
462 |         headers = Headers(self.headers)
463 |         location: str | None = None
464 |         content_location: str | None = None
465 |         content_length: str | int | None = None
466 |         status = self.status_code
467 | 
468 |         # iterate over the headers to find all values in one go.  Because
469 |         # get_wsgi_headers is used each response that gives us a tiny
470 |         # speedup.
471 |         for key, value in headers:
472 |             ikey = key.lower()
473 |             if ikey == "location":
474 |                 location = value
475 |             elif ikey == "content-location":
476 |                 content_location = value
477 |             elif ikey == "content-length":
478 |                 content_length = value
479 | 
480 |         if location is not None:
481 |             location = iri_to_uri(location)
482 | 
483 |             if self.autocorrect_location_header:
484 |                 # Make the location header an absolute URL.
485 |                 current_url = get_current_url(environ, strip_querystring=True)
486 |                 current_url = iri_to_uri(current_url)
487 |                 location = urljoin(current_url, location)
488 | 
489 |             headers["Location"] = location
490 | 
491 |         # make sure the content location is a URL
492 |         if content_location is not None:
493 |             headers["Content-Location"] = iri_to_uri(content_location)
494 | 
495 |         if 100 <= status < 200 or status == 204:
496 |             # Per section 3.3.2 of RFC 7230, "a server MUST NOT send a
497 |             # Content-Length header field in any response with a status
498 |             # code of 1xx (Informational) or 204 (No Content)."
499 |             headers.remove("Content-Length")
500 |         elif status == 304:
501 |             remove_entity_headers(headers)
502 | 
503 |         # if we can determine the content length automatically, we
504 |         # should try to do that.  But only if this does not involve
505 |         # flattening the iterator or encoding of strings in the
506 |         # response. We however should not do that if we have a 304
507 |         # response.
508 |         if (
509 |             self.automatically_set_content_length
510 |             and self.is_sequence
511 |             and content_length is None
512 |             and status not in (204, 304)
513 |             and not (100 <= status < 200)
514 |         ):
515 |             content_length = sum(len(x) for x in self.iter_encoded())
516 |             headers["Content-Length"] = str(content_length)
517 | 
518 |         return headers
519 | 
520 |     def get_app_iter(self, environ: WSGIEnvironment) -> t.Iterable[bytes]:
521 |         """Returns the application iterator for the given environ.  Depending
522 |         on the request method and the current status code the return value
523 |         might be an empty response rather than the one from the response.
524 | 
525 |         If the request method is `HEAD` or the status code is in a range
526 |         where the HTTP specification requires an empty response, an empty
527 |         iterable is returned.
528 | 
529 |         .. versionadded:: 0.6
530 | 
531 |         :param environ: the WSGI environment of the request.
532 |         :return: a response iterable.
533 |         """
534 |         status = self.status_code
535 |         if (
536 |             environ["REQUEST_METHOD"] == "HEAD"
537 |             or 100 <= status < 200
538 |             or status in (204, 304)
539 |         ):
540 |             iterable: t.Iterable[bytes] = ()
541 |         elif self.direct_passthrough:
542 |             return self.response  # type: ignore
543 |         else:
544 |             iterable = self.iter_encoded()
545 |         return ClosingIterator(iterable, self.close)
546 | 
547 |     def get_wsgi_response(
548 |         self, environ: WSGIEnvironment
549 |     ) -> tuple[t.Iterable[bytes], str, list[tuple[str, str]]]:
550 |         """Returns the final WSGI response as tuple.  The first item in
551 |         the tuple is the application iterator, the second the status and
552 |         the third the list of headers.  The response returned is created
553 |         specially for the given environment.  For example if the request
554 |         method in the WSGI environment is ``'HEAD'`` the response will
555 |         be empty and only the headers and status code will be present.
556 | 
557 |         .. versionadded:: 0.6
558 | 
559 |         :param environ: the WSGI environment of the request.
560 |         :return: an ``(app_iter, status, headers)`` tuple.
561 |         """
562 |         headers = self.get_wsgi_headers(environ)
563 |         app_iter = self.get_app_iter(environ)
564 |         return app_iter, self.status, headers.to_wsgi_list()
565 | 
566 |     def __call__(
567 |         self, environ: WSGIEnvironment, start_response: StartResponse
568 |     ) -> t.Iterable[bytes]:
569 |         """Process this response as WSGI application.
570 | 
571 |         :param environ: the WSGI environment.
572 |         :param start_response: the response callable provided by the WSGI
573 |                                server.
574 |         :return: an application iterator
575 |         """
576 |         app_iter, status, headers = self.get_wsgi_response(environ)
577 |         start_response(status, headers)
578 |         return app_iter
579 | 
580 |     # JSON
581 | 
582 |     #: A module or other object that has ``dumps`` and ``loads``
583 |     #: functions that match the API of the built-in :mod:`json` module.
584 |     json_module = json
585 | 
586 |     @property
587 |     def json(self) -> t.Any | None:
588 |         """The parsed JSON data if :attr:`mimetype` indicates JSON
589 |         (:mimetype:`application/json`, see :attr:`is_json`).
590 | 
591 |         Calls :meth:`get_json` with default arguments.
592 |         """
593 |         return self.get_json()
594 | 
595 |     @t.overload
596 |     def get_json(self, force: bool = ..., silent: t.Literal[False] = ...) -> t.Any: ...
597 | 
598 |     @t.overload
599 |     def get_json(self, force: bool = ..., silent: bool = ...) -> t.Any | None: ...
600 | 
601 |     def get_json(self, force: bool = False, silent: bool = False) -> t.Any | None:
602 |         """Parse :attr:`data` as JSON. Useful during testing.
603 | 
604 |         If the mimetype does not indicate JSON
605 |         (:mimetype:`application/json`, see :attr:`is_json`), this
606 |         returns ``None``.
607 | 
608 |         Unlike :meth:`Request.get_json`, the result is not cached.
609 | 
610 |         :param force: Ignore the mimetype and always try to parse JSON.
611 |         :param silent: Silence parsing errors and return ``None``
612 |             instead.
613 |         """
614 |         if not (force or self.is_json):
615 |             return None
616 | 
617 |         data = self.get_data()
618 | 
619 |         try:
620 |             return self.json_module.loads(data)
621 |         except ValueError:
622 |             if not silent:
623 |                 raise
624 | 
625 |             return None
626 | 
627 |     # Stream
628 | 
629 |     @cached_property
630 |     def stream(self) -> ResponseStream:
631 |         """The response iterable as write-only stream."""
632 |         return ResponseStream(self)
633 | 
634 |     def _wrap_range_response(self, start: int, length: int) -> None:
635 |         """Wrap existing Response in case of Range Request context."""
636 |         if self.status_code == 206:
637 |             self.response = _RangeWrapper(self.response, start, length)  # type: ignore
638 | 
639 |     def _is_range_request_processable(self, environ: WSGIEnvironment) -> bool:
640 |         """Return ``True`` if `Range` header is present and if underlying
641 |         resource is considered unchanged when compared with `If-Range` header.
642 |         """
643 |         return (
644 |             "HTTP_IF_RANGE" not in environ
645 |             or not is_resource_modified(
646 |                 environ,
647 |                 self.headers.get("etag"),
648 |                 None,
649 |                 self.headers.get("last-modified"),
650 |                 ignore_if_range=False,
651 |             )
652 |         ) and "HTTP_RANGE" in environ
653 | 
654 |     def _process_range_request(
655 |         self,
656 |         environ: WSGIEnvironment,
657 |         complete_length: int | None,
658 |         accept_ranges: bool | str,
659 |     ) -> bool:
660 |         """Handle Range Request related headers (RFC7233).  If `Accept-Ranges`
661 |         header is valid, and Range Request is processable, we set the headers
662 |         as described by the RFC, and wrap the underlying response in a
663 |         RangeWrapper.
664 | 
665 |         Returns ``True`` if Range Request can be fulfilled, ``False`` otherwise.
666 | 
667 |         :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable`
668 |                  if `Range` header could not be parsed or satisfied.
669 | 
670 |         .. versionchanged:: 2.0
671 |             Returns ``False`` if the length is 0.
672 |         """
673 |         from ..exceptions import RequestedRangeNotSatisfiable
674 | 
675 |         if (
676 |             not accept_ranges
677 |             or complete_length is None
678 |             or complete_length == 0
679 |             or not self._is_range_request_processable(environ)
680 |         ):
681 |             return False
682 | 
683 |         if accept_ranges is True:
684 |             accept_ranges = "bytes"
685 | 
686 |         parsed_range = parse_range_header(environ.get("HTTP_RANGE"))
687 | 
688 |         if parsed_range is None:
689 |             raise RequestedRangeNotSatisfiable(complete_length)
690 | 
691 |         range_tuple = parsed_range.range_for_length(complete_length)
692 |         content_range_header = parsed_range.to_content_range_header(complete_length)
693 | 
694 |         if range_tuple is None or content_range_header is None:
695 |             raise RequestedRangeNotSatisfiable(complete_length)
696 | 
697 |         content_length = range_tuple[1] - range_tuple[0]
698 |         self.headers["Content-Length"] = str(content_length)
699 |         self.headers["Accept-Ranges"] = accept_ranges
700 |         self.content_range = content_range_header  # type: ignore
701 |         self.status_code = 206
702 |         self._wrap_range_response(range_tuple[0], content_length)
703 |         return True
704 | 
705 |     def make_conditional(
706 |         self,
707 |         request_or_environ: WSGIEnvironment | Request,
708 |         accept_ranges: bool | str = False,
709 |         complete_length: int | None = None,
710 |     ) -> Response:
711 |         """Make the response conditional to the request.  This method works
712 |         best if an etag was defined for the response already.  The `add_etag`
713 |         method can be used to do that.  If called without etag just the date
714 |         header is set.
715 | 
716 |         This does nothing if the request method in the request or environ is
717 |         anything but GET or HEAD.
718 | 
719 |         For optimal performance when handling range requests, it's recommended
720 |         that your response data object implements `seekable`, `seek` and `tell`
721 |         methods as described by :py:class:`io.IOBase`.  Objects returned by
722 |         :meth:`~werkzeug.wsgi.wrap_file` automatically implement those methods.
723 | 
724 |         It does not remove the body of the response because that's something
725 |         the :meth:`__call__` function does for us automatically.
726 | 
727 |         Returns self so that you can do ``return resp.make_conditional(req)``
728 |         but modifies the object in-place.
729 | 
730 |         :param request_or_environ: a request object or WSGI environment to be
731 |                                    used to make the response conditional
732 |                                    against.
733 |         :param accept_ranges: This parameter dictates the value of
734 |                               `Accept-Ranges` header. If ``False`` (default),
735 |                               the header is not set. If ``True``, it will be set
736 |                               to ``"bytes"``. If it's a string, it will use this
737 |                               value.
738 |         :param complete_length: Will be used only in valid Range Requests.
739 |                                 It will set `Content-Range` complete length
740 |                                 value and compute `Content-Length` real value.
741 |                                 This parameter is mandatory for successful
742 |                                 Range Requests completion.
743 |         :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable`
744 |                  if `Range` header could not be parsed or satisfied.
745 | 
746 |         .. versionchanged:: 2.0
747 |             Range processing is skipped if length is 0 instead of
748 |             raising a 416 Range Not Satisfiable error.
749 |         """
750 |         environ = _get_environ(request_or_environ)
751 |         if environ["REQUEST_METHOD"] in ("GET", "HEAD"):
752 |             # if the date is not in the headers, add it now.  We however
753 |             # will not override an already existing header.  Unfortunately
754 |             # this header will be overridden by many WSGI servers including
755 |             # wsgiref.
756 |             if "date" not in self.headers:
757 |                 self.headers["Date"] = http_date()
758 |             is206 = self._process_range_request(environ, complete_length, accept_ranges)
759 |             if not is206 and not is_resource_modified(
760 |                 environ,
761 |                 self.headers.get("etag"),
762 |                 None,
763 |                 self.headers.get("last-modified"),
764 |             ):
765 |                 if parse_etags(environ.get("HTTP_IF_MATCH")):
766 |                     self.status_code = 412
767 |                 else:
768 |                     self.status_code = 304
769 |             if (
770 |                 self.automatically_set_content_length
771 |                 and "content-length" not in self.headers
772 |             ):
773 |                 length = self.calculate_content_length()
774 |                 if length is not None:
775 |                     self.headers["Content-Length"] = str(length)
776 |         return self
777 | 
778 |     def add_etag(self, overwrite: bool = False, weak: bool = False) -> None:
779 |         """Add an etag for the current response if there is none yet.
780 | 
781 |         .. versionchanged:: 2.0
782 |             SHA-1 is used to generate the value. MD5 may not be
783 |             available in some environments.
784 |         """
785 |         if overwrite or "etag" not in self.headers:
786 |             self.set_etag(generate_etag(self.get_data()), weak)
787 | 
788 | 
789 | class ResponseStream:
790 |     """A file descriptor like object used by :meth:`Response.stream` to
791 |     represent the body of the stream. It directly pushes into the
792 |     response iterable of the response object.
793 |     """
794 | 
795 |     mode = "wb+"
796 | 
797 |     def __init__(self, response: Response):
798 |         self.response = response
799 |         self.closed = False
800 | 
801 |     def write(self, value: bytes) -> int:
802 |         if self.closed:
803 |             raise ValueError("I/O operation on closed file")
804 |         self.response._ensure_sequence(mutable=True)
805 |         self.response.response.append(value)  # type: ignore
806 |         self.response.headers.pop("Content-Length", None)
807 |         return len(value)
808 | 
809 |     def writelines(self, seq: t.Iterable[bytes]) -> None:
810 |         for item in seq:
811 |             self.write(item)
812 | 
813 |     def close(self) -> None:
814 |         self.closed = True
815 | 
816 |     def flush(self) -> None:
817 |         if self.closed:
818 |             raise ValueError("I/O operation on closed file")
819 | 
820 |     def isatty(self) -> bool:
821 |         if self.closed:
822 |             raise ValueError("I/O operation on closed file")
823 |         return False
824 | 
825 |     def tell(self) -> int:
826 |         self.response._ensure_sequence()
827 |         return sum(map(len, self.response.response))
828 | 
829 |     @property
830 |     def encoding(self) -> str:
831 |         return "utf-8"
832 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/routing/rules.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import annotations
  2 | 
  3 | import ast
  4 | import re
  5 | import typing as t
  6 | from dataclasses import dataclass
  7 | from string import Template
  8 | from types import CodeType
  9 | from urllib.parse import quote
 10 | 
 11 | from ..datastructures import iter_multi_items
 12 | from ..urls import _urlencode
 13 | from .converters import ValidationError
 14 | 
 15 | if t.TYPE_CHECKING:
 16 |     from .converters import BaseConverter
 17 |     from .map import Map
 18 | 
 19 | 
 20 | class Weighting(t.NamedTuple):
 21 |     number_static_weights: int
 22 |     static_weights: list[tuple[int, int]]
 23 |     number_argument_weights: int
 24 |     argument_weights: list[int]
 25 | 
 26 | 
 27 | @dataclass
 28 | class RulePart:
 29 |     """A part of a rule.
 30 | 
 31 |     Rules can be represented by parts as delimited by `/` with
 32 |     instances of this class representing those parts. The *content* is
 33 |     either the raw content if *static* or a regex string to match
 34 |     against. The *weight* can be used to order parts when matching.
 35 | 
 36 |     """
 37 | 
 38 |     content: str
 39 |     final: bool
 40 |     static: bool
 41 |     suffixed: bool
 42 |     weight: Weighting
 43 | 
 44 | 
 45 | _part_re = re.compile(
 46 |     r"""
 47 |     (?:
 48 |         (?P<slash>/)                                 # a slash
 49 |       |
 50 |         (?P<static>[^</]+)                           # static rule data
 51 |       |
 52 |         (?:
 53 |           <
 54 |             (?:
 55 |               (?P<converter>[a-zA-Z_][a-zA-Z0-9_]*)   # converter name
 56 |               (?:\((?P<arguments>.*?)\))?             # converter arguments
 57 |               :                                       # variable delimiter
 58 |             )?
 59 |             (?P<variable>[a-zA-Z_][a-zA-Z0-9_]*)      # variable name
 60 |            >
 61 |         )
 62 |     )
 63 |     """,
 64 |     re.VERBOSE,
 65 | )
 66 | 
 67 | _simple_rule_re = re.compile(r"<([^>]+)>")
 68 | _converter_args_re = re.compile(
 69 |     r"""
 70 |     \s*
 71 |     ((?P<name>\w+)\s*=\s*)?
 72 |     (?P<value>
 73 |         True|False|
 74 |         \d+.\d+|
 75 |         \d+.|
 76 |         \d+|
 77 |         [\w\d_.]+|
 78 |         [urUR]?(?P<stringval>"[^"]*?"|'[^']*')
 79 |     )\s*,
 80 |     """,
 81 |     re.VERBOSE,
 82 | )
 83 | 
 84 | 
 85 | _PYTHON_CONSTANTS = {"None": None, "True": True, "False": False}
 86 | 
 87 | 
 88 | def _find(value: str, target: str, pos: int) -> int:
 89 |     """Find the *target* in *value* after *pos*.
 90 | 
 91 |     Returns the *value* length if *target* isn't found.
 92 |     """
 93 |     try:
 94 |         return value.index(target, pos)
 95 |     except ValueError:
 96 |         return len(value)
 97 | 
 98 | 
 99 | def _pythonize(value: str) -> None | bool | int | float | str:
100 |     if value in _PYTHON_CONSTANTS:
101 |         return _PYTHON_CONSTANTS[value]
102 |     for convert in int, float:
103 |         try:
104 |             return convert(value)
105 |         except ValueError:
106 |             pass
107 |     if value[:1] == value[-1:] and value[0] in "\"'":
108 |         value = value[1:-1]
109 |     return str(value)
110 | 
111 | 
112 | def parse_converter_args(argstr: str) -> tuple[tuple[t.Any, ...], dict[str, t.Any]]:
113 |     argstr += ","
114 |     args = []
115 |     kwargs = {}
116 |     position = 0
117 | 
118 |     for item in _converter_args_re.finditer(argstr):
119 |         if item.start() != position:
120 |             raise ValueError(
121 |                 f"Cannot parse converter argument '{argstr[position:item.start()]}'"
122 |             )
123 | 
124 |         value = item.group("stringval")
125 |         if value is None:
126 |             value = item.group("value")
127 |         value = _pythonize(value)
128 |         if not item.group("name"):
129 |             args.append(value)
130 |         else:
131 |             name = item.group("name")
132 |             kwargs[name] = value
133 |         position = item.end()
134 | 
135 |     return tuple(args), kwargs
136 | 
137 | 
138 | class RuleFactory:
139 |     """As soon as you have more complex URL setups it's a good idea to use rule
140 |     factories to avoid repetitive tasks.  Some of them are builtin, others can
141 |     be added by subclassing `RuleFactory` and overriding `get_rules`.
142 |     """
143 | 
144 |     def get_rules(self, map: Map) -> t.Iterable[Rule]:
145 |         """Subclasses of `RuleFactory` have to override this method and return
146 |         an iterable of rules."""
147 |         raise NotImplementedError()
148 | 
149 | 
150 | class Subdomain(RuleFactory):
151 |     """All URLs provided by this factory have the subdomain set to a
152 |     specific domain. For example if you want to use the subdomain for
153 |     the current language this can be a good setup::
154 | 
155 |         url_map = Map([
156 |             Rule('/', endpoint='#select_language'),
157 |             Subdomain('<string(length=2):lang_code>', [
158 |                 Rule('/', endpoint='index'),
159 |                 Rule('/about', endpoint='about'),
160 |                 Rule('/help', endpoint='help')
161 |             ])
162 |         ])
163 | 
164 |     All the rules except for the ``'#select_language'`` endpoint will now
165 |     listen on a two letter long subdomain that holds the language code
166 |     for the current request.
167 |     """
168 | 
169 |     def __init__(self, subdomain: str, rules: t.Iterable[RuleFactory]) -> None:
170 |         self.subdomain = subdomain
171 |         self.rules = rules
172 | 
173 |     def get_rules(self, map: Map) -> t.Iterator[Rule]:
174 |         for rulefactory in self.rules:
175 |             for rule in rulefactory.get_rules(map):
176 |                 rule = rule.empty()
177 |                 rule.subdomain = self.subdomain
178 |                 yield rule
179 | 
180 | 
181 | class Submount(RuleFactory):
182 |     """Like `Subdomain` but prefixes the URL rule with a given string::
183 | 
184 |         url_map = Map([
185 |             Rule('/', endpoint='index'),
186 |             Submount('/blog', [
187 |                 Rule('/', endpoint='blog/index'),
188 |                 Rule('/entry/<entry_slug>', endpoint='blog/show')
189 |             ])
190 |         ])
191 | 
192 |     Now the rule ``'blog/show'`` matches ``/blog/entry/<entry_slug>``.
193 |     """
194 | 
195 |     def __init__(self, path: str, rules: t.Iterable[RuleFactory]) -> None:
196 |         self.path = path.rstrip("/")
197 |         self.rules = rules
198 | 
199 |     def get_rules(self, map: Map) -> t.Iterator[Rule]:
200 |         for rulefactory in self.rules:
201 |             for rule in rulefactory.get_rules(map):
202 |                 rule = rule.empty()
203 |                 rule.rule = self.path + rule.rule
204 |                 yield rule
205 | 
206 | 
207 | class EndpointPrefix(RuleFactory):
208 |     """Prefixes all endpoints (which must be strings for this factory) with
209 |     another string. This can be useful for sub applications::
210 | 
211 |         url_map = Map([
212 |             Rule('/', endpoint='index'),
213 |             EndpointPrefix('blog/', [Submount('/blog', [
214 |                 Rule('/', endpoint='index'),
215 |                 Rule('/entry/<entry_slug>', endpoint='show')
216 |             ])])
217 |         ])
218 |     """
219 | 
220 |     def __init__(self, prefix: str, rules: t.Iterable[RuleFactory]) -> None:
221 |         self.prefix = prefix
222 |         self.rules = rules
223 | 
224 |     def get_rules(self, map: Map) -> t.Iterator[Rule]:
225 |         for rulefactory in self.rules:
226 |             for rule in rulefactory.get_rules(map):
227 |                 rule = rule.empty()
228 |                 rule.endpoint = self.prefix + rule.endpoint
229 |                 yield rule
230 | 
231 | 
232 | class RuleTemplate:
233 |     """Returns copies of the rules wrapped and expands string templates in
234 |     the endpoint, rule, defaults or subdomain sections.
235 | 
236 |     Here a small example for such a rule template::
237 | 
238 |         from werkzeug.routing import Map, Rule, RuleTemplate
239 | 
240 |         resource = RuleTemplate([
241 |             Rule('/$name/', endpoint='$name.list'),
242 |             Rule('/$name/<int:id>', endpoint='$name.show')
243 |         ])
244 | 
245 |         url_map = Map([resource(name='user'), resource(name='page')])
246 | 
247 |     When a rule template is called the keyword arguments are used to
248 |     replace the placeholders in all the string parameters.
249 |     """
250 | 
251 |     def __init__(self, rules: t.Iterable[Rule]) -> None:
252 |         self.rules = list(rules)
253 | 
254 |     def __call__(self, *args: t.Any, **kwargs: t.Any) -> RuleTemplateFactory:
255 |         return RuleTemplateFactory(self.rules, dict(*args, **kwargs))
256 | 
257 | 
258 | class RuleTemplateFactory(RuleFactory):
259 |     """A factory that fills in template variables into rules.  Used by
260 |     `RuleTemplate` internally.
261 | 
262 |     :internal:
263 |     """
264 | 
265 |     def __init__(
266 |         self, rules: t.Iterable[RuleFactory], context: dict[str, t.Any]
267 |     ) -> None:
268 |         self.rules = rules
269 |         self.context = context
270 | 
271 |     def get_rules(self, map: Map) -> t.Iterator[Rule]:
272 |         for rulefactory in self.rules:
273 |             for rule in rulefactory.get_rules(map):
274 |                 new_defaults = subdomain = None
275 |                 if rule.defaults:
276 |                     new_defaults = {}
277 |                     for key, value in rule.defaults.items():
278 |                         if isinstance(value, str):
279 |                             value = Template(value).substitute(self.context)
280 |                         new_defaults[key] = value
281 |                 if rule.subdomain is not None:
282 |                     subdomain = Template(rule.subdomain).substitute(self.context)
283 |                 new_endpoint = rule.endpoint
284 |                 if isinstance(new_endpoint, str):
285 |                     new_endpoint = Template(new_endpoint).substitute(self.context)
286 |                 yield Rule(
287 |                     Template(rule.rule).substitute(self.context),
288 |                     new_defaults,
289 |                     subdomain,
290 |                     rule.methods,
291 |                     rule.build_only,
292 |                     new_endpoint,
293 |                     rule.strict_slashes,
294 |                 )
295 | 
296 | 
297 | _ASTT = t.TypeVar("_ASTT", bound=ast.AST)
298 | 
299 | 
300 | def _prefix_names(src: str, expected_type: type[_ASTT]) -> _ASTT:
301 |     """ast parse and prefix names with `.` to avoid collision with user vars"""
302 |     tree: ast.AST = ast.parse(src).body[0]
303 |     if isinstance(tree, ast.Expr):
304 |         tree = tree.value
305 |     if not isinstance(tree, expected_type):
306 |         raise TypeError(
307 |             f"AST node is of type {type(tree).__name__}, not {expected_type.__name__}"
308 |         )
309 |     for node in ast.walk(tree):
310 |         if isinstance(node, ast.Name):
311 |             node.id = f".{node.id}"
312 |     return tree
313 | 
314 | 
315 | _CALL_CONVERTER_CODE_FMT = "self._converters[{elem!r}].to_url()"
316 | _IF_KWARGS_URL_ENCODE_CODE = """\
317 | if kwargs:
318 |     params = self._encode_query_vars(kwargs)
319 |     q = "?" if params else ""
320 | else:
321 |     q = params = ""
322 | """
323 | _IF_KWARGS_URL_ENCODE_AST = _prefix_names(_IF_KWARGS_URL_ENCODE_CODE, ast.If)
324 | _URL_ENCODE_AST_NAMES = (
325 |     _prefix_names("q", ast.Name),
326 |     _prefix_names("params", ast.Name),
327 | )
328 | 
329 | 
330 | class Rule(RuleFactory):
331 |     """A Rule represents one URL pattern.  There are some options for `Rule`
332 |     that change the way it behaves and are passed to the `Rule` constructor.
333 |     Note that besides the rule-string all arguments *must* be keyword arguments
334 |     in order to not break the application on Werkzeug upgrades.
335 | 
336 |     `string`
337 |         Rule strings basically are just normal URL paths with placeholders in
338 |         the format ``<converter(arguments):name>`` where the converter and the
339 |         arguments are optional.  If no converter is defined the `default`
340 |         converter is used which means `string` in the normal configuration.
341 | 
342 |         URL rules that end with a slash are branch URLs, others are leaves.
343 |         If you have `strict_slashes` enabled (which is the default), all
344 |         branch URLs that are matched without a trailing slash will trigger a
345 |         redirect to the same URL with the missing slash appended.
346 | 
347 |         The converters are defined on the `Map`.
348 | 
349 |     `endpoint`
350 |         The endpoint for this rule. This can be anything. A reference to a
351 |         function, a string, a number etc.  The preferred way is using a string
352 |         because the endpoint is used for URL generation.
353 | 
354 |     `defaults`
355 |         An optional dict with defaults for other rules with the same endpoint.
356 |         This is a bit tricky but useful if you want to have unique URLs::
357 | 
358 |             url_map = Map([
359 |                 Rule('/all/', defaults={'page': 1}, endpoint='all_entries'),
360 |                 Rule('/all/page/<int:page>', endpoint='all_entries')
361 |             ])
362 | 
363 |         If a user now visits ``http://example.com/all/page/1`` they will be
364 |         redirected to ``http://example.com/all/``.  If `redirect_defaults` is
365 |         disabled on the `Map` instance this will only affect the URL
366 |         generation.
367 | 
368 |     `subdomain`
369 |         The subdomain rule string for this rule. If not specified the rule
370 |         only matches for the `default_subdomain` of the map.  If the map is
371 |         not bound to a subdomain this feature is disabled.
372 | 
373 |         Can be useful if you want to have user profiles on different subdomains
374 |         and all subdomains are forwarded to your application::
375 | 
376 |             url_map = Map([
377 |                 Rule('/', subdomain='<username>', endpoint='user/homepage'),
378 |                 Rule('/stats', subdomain='<username>', endpoint='user/stats')
379 |             ])
380 | 
381 |     `methods`
382 |         A sequence of http methods this rule applies to.  If not specified, all
383 |         methods are allowed. For example this can be useful if you want different
384 |         endpoints for `POST` and `GET`.  If methods are defined and the path
385 |         matches but the method matched against is not in this list or in the
386 |         list of another rule for that path the error raised is of the type
387 |         `MethodNotAllowed` rather than `NotFound`.  If `GET` is present in the
388 |         list of methods and `HEAD` is not, `HEAD` is added automatically.
389 | 
390 |     `strict_slashes`
391 |         Override the `Map` setting for `strict_slashes` only for this rule. If
392 |         not specified the `Map` setting is used.
393 | 
394 |     `merge_slashes`
395 |         Override :attr:`Map.merge_slashes` for this rule.
396 | 
397 |     `build_only`
398 |         Set this to True and the rule will never match but will create a URL
399 |         that can be build. This is useful if you have resources on a subdomain
400 |         or folder that are not handled by the WSGI application (like static data)
401 | 
402 |     `redirect_to`
403 |         If given this must be either a string or callable.  In case of a
404 |         callable it's called with the url adapter that triggered the match and
405 |         the values of the URL as keyword arguments and has to return the target
406 |         for the redirect, otherwise it has to be a string with placeholders in
407 |         rule syntax::
408 | 
409 |             def foo_with_slug(adapter, id):
410 |                 # ask the database for the slug for the old id.  this of
411 |                 # course has nothing to do with werkzeug.
412 |                 return f'foo/{Foo.get_slug_for_id(id)}'
413 | 
414 |             url_map = Map([
415 |                 Rule('/foo/<slug>', endpoint='foo'),
416 |                 Rule('/some/old/url/<slug>', redirect_to='foo/<slug>'),
417 |                 Rule('/other/old/url/<int:id>', redirect_to=foo_with_slug)
418 |             ])
419 | 
420 |         When the rule is matched the routing system will raise a
421 |         `RequestRedirect` exception with the target for the redirect.
422 | 
423 |         Keep in mind that the URL will be joined against the URL root of the
424 |         script so don't use a leading slash on the target URL unless you
425 |         really mean root of that domain.
426 | 
427 |     `alias`
428 |         If enabled this rule serves as an alias for another rule with the same
429 |         endpoint and arguments.
430 | 
431 |     `host`
432 |         If provided and the URL map has host matching enabled this can be
433 |         used to provide a match rule for the whole host.  This also means
434 |         that the subdomain feature is disabled.
435 | 
436 |     `websocket`
437 |         If ``True``, this rule is only matches for WebSocket (``ws://``,
438 |         ``wss://``) requests. By default, rules will only match for HTTP
439 |         requests.
440 | 
441 |     .. versionchanged:: 2.1
442 |         Percent-encoded newlines (``%0a``), which are decoded by WSGI
443 |         servers, are considered when routing instead of terminating the
444 |         match early.
445 | 
446 |     .. versionadded:: 1.0
447 |         Added ``websocket``.
448 | 
449 |     .. versionadded:: 1.0
450 |         Added ``merge_slashes``.
451 | 
452 |     .. versionadded:: 0.7
453 |         Added ``alias`` and ``host``.
454 | 
455 |     .. versionchanged:: 0.6.1
456 |        ``HEAD`` is added to ``methods`` if ``GET`` is present.
457 |     """
458 | 
459 |     def __init__(
460 |         self,
461 |         string: str,
462 |         defaults: t.Mapping[str, t.Any] | None = None,
463 |         subdomain: str | None = None,
464 |         methods: t.Iterable[str] | None = None,
465 |         build_only: bool = False,
466 |         endpoint: t.Any | None = None,
467 |         strict_slashes: bool | None = None,
468 |         merge_slashes: bool | None = None,
469 |         redirect_to: str | t.Callable[..., str] | None = None,
470 |         alias: bool = False,
471 |         host: str | None = None,
472 |         websocket: bool = False,
473 |     ) -> None:
474 |         if not string.startswith("/"):
475 |             raise ValueError(f"URL rule '{string}' must start with a slash.")
476 | 
477 |         self.rule = string
478 |         self.is_leaf = not string.endswith("/")
479 |         self.is_branch = string.endswith("/")
480 | 
481 |         self.map: Map = None  # type: ignore
482 |         self.strict_slashes = strict_slashes
483 |         self.merge_slashes = merge_slashes
484 |         self.subdomain = subdomain
485 |         self.host = host
486 |         self.defaults = defaults
487 |         self.build_only = build_only
488 |         self.alias = alias
489 |         self.websocket = websocket
490 | 
491 |         if methods is not None:
492 |             if isinstance(methods, str):
493 |                 raise TypeError("'methods' should be a list of strings.")
494 | 
495 |             methods = {x.upper() for x in methods}
496 | 
497 |             if "HEAD" not in methods and "GET" in methods:
498 |                 methods.add("HEAD")
499 | 
500 |             if websocket and methods - {"GET", "HEAD", "OPTIONS"}:
501 |                 raise ValueError(
502 |                     "WebSocket rules can only use 'GET', 'HEAD', and 'OPTIONS' methods."
503 |                 )
504 | 
505 |         self.methods = methods
506 |         self.endpoint: t.Any = endpoint
507 |         self.redirect_to = redirect_to
508 | 
509 |         if defaults:
510 |             self.arguments = set(map(str, defaults))
511 |         else:
512 |             self.arguments = set()
513 | 
514 |         self._converters: dict[str, BaseConverter] = {}
515 |         self._trace: list[tuple[bool, str]] = []
516 |         self._parts: list[RulePart] = []
517 | 
518 |     def empty(self) -> Rule:
519 |         """
520 |         Return an unbound copy of this rule.
521 | 
522 |         This can be useful if want to reuse an already bound URL for another
523 |         map.  See ``get_empty_kwargs`` to override what keyword arguments are
524 |         provided to the new copy.
525 |         """
526 |         return type(self)(self.rule, **self.get_empty_kwargs())
527 | 
528 |     def get_empty_kwargs(self) -> t.Mapping[str, t.Any]:
529 |         """
530 |         Provides kwargs for instantiating empty copy with empty()
531 | 
532 |         Use this method to provide custom keyword arguments to the subclass of
533 |         ``Rule`` when calling ``some_rule.empty()``.  Helpful when the subclass
534 |         has custom keyword arguments that are needed at instantiation.
535 | 
536 |         Must return a ``dict`` that will be provided as kwargs to the new
537 |         instance of ``Rule``, following the initial ``self.rule`` value which
538 |         is always provided as the first, required positional argument.
539 |         """
540 |         defaults = None
541 |         if self.defaults:
542 |             defaults = dict(self.defaults)
543 |         return dict(
544 |             defaults=defaults,
545 |             subdomain=self.subdomain,
546 |             methods=self.methods,
547 |             build_only=self.build_only,
548 |             endpoint=self.endpoint,
549 |             strict_slashes=self.strict_slashes,
550 |             redirect_to=self.redirect_to,
551 |             alias=self.alias,
552 |             host=self.host,
553 |         )
554 | 
555 |     def get_rules(self, map: Map) -> t.Iterator[Rule]:
556 |         yield self
557 | 
558 |     def refresh(self) -> None:
559 |         """Rebinds and refreshes the URL.  Call this if you modified the
560 |         rule in place.
561 | 
562 |         :internal:
563 |         """
564 |         self.bind(self.map, rebind=True)
565 | 
566 |     def bind(self, map: Map, rebind: bool = False) -> None:
567 |         """Bind the url to a map and create a regular expression based on
568 |         the information from the rule itself and the defaults from the map.
569 | 
570 |         :internal:
571 |         """
572 |         if self.map is not None and not rebind:
573 |             raise RuntimeError(f"url rule {self!r} already bound to map {self.map!r}")
574 |         self.map = map
575 |         if self.strict_slashes is None:
576 |             self.strict_slashes = map.strict_slashes
577 |         if self.merge_slashes is None:
578 |             self.merge_slashes = map.merge_slashes
579 |         if self.subdomain is None:
580 |             self.subdomain = map.default_subdomain
581 |         self.compile()
582 | 
583 |     def get_converter(
584 |         self,
585 |         variable_name: str,
586 |         converter_name: str,
587 |         args: tuple[t.Any, ...],
588 |         kwargs: t.Mapping[str, t.Any],
589 |     ) -> BaseConverter:
590 |         """Looks up the converter for the given parameter.
591 | 
592 |         .. versionadded:: 0.9
593 |         """
594 |         if converter_name not in self.map.converters:
595 |             raise LookupError(f"the converter {converter_name!r} does not exist")
596 |         return self.map.converters[converter_name](self.map, *args, **kwargs)
597 | 
598 |     def _encode_query_vars(self, query_vars: t.Mapping[str, t.Any]) -> str:
599 |         items: t.Iterable[tuple[str, str]] = iter_multi_items(query_vars)
600 | 
601 |         if self.map.sort_parameters:
602 |             items = sorted(items, key=self.map.sort_key)
603 | 
604 |         return _urlencode(items)
605 | 
606 |     def _parse_rule(self, rule: str) -> t.Iterable[RulePart]:
607 |         content = ""
608 |         static = True
609 |         argument_weights = []
610 |         static_weights: list[tuple[int, int]] = []
611 |         final = False
612 |         convertor_number = 0
613 | 
614 |         pos = 0
615 |         while pos < len(rule):
616 |             match = _part_re.match(rule, pos)
617 |             if match is None:
618 |                 raise ValueError(f"malformed url rule: {rule!r}")
619 | 
620 |             data = match.groupdict()
621 |             if data["static"] is not None:
622 |                 static_weights.append((len(static_weights), -len(data["static"])))
623 |                 self._trace.append((False, data["static"]))
624 |                 content += data["static"] if static else re.escape(data["static"])
625 | 
626 |             if data["variable"] is not None:
627 |                 if static:
628 |                     # Switching content to represent regex, hence the need to escape
629 |                     content = re.escape(content)
630 |                 static = False
631 |                 c_args, c_kwargs = parse_converter_args(data["arguments"] or "")
632 |                 convobj = self.get_converter(
633 |                     data["variable"], data["converter"] or "default", c_args, c_kwargs
634 |                 )
635 |                 self._converters[data["variable"]] = convobj
636 |                 self.arguments.add(data["variable"])
637 |                 if not convobj.part_isolating:
638 |                     final = True
639 |                 content += f"(?P<__werkzeug_{convertor_number}>{convobj.regex})"
640 |                 convertor_number += 1
641 |                 argument_weights.append(convobj.weight)
642 |                 self._trace.append((True, data["variable"]))
643 | 
644 |             if data["slash"] is not None:
645 |                 self._trace.append((False, "/"))
646 |                 if final:
647 |                     content += "/"
648 |                 else:
649 |                     if not static:
650 |                         content += r"\Z"
651 |                     weight = Weighting(
652 |                         -len(static_weights),
653 |                         static_weights,
654 |                         -len(argument_weights),
655 |                         argument_weights,
656 |                     )
657 |                     yield RulePart(
658 |                         content=content,
659 |                         final=final,
660 |                         static=static,
661 |                         suffixed=False,
662 |                         weight=weight,
663 |                     )
664 |                     content = ""
665 |                     static = True
666 |                     argument_weights = []
667 |                     static_weights = []
668 |                     final = False
669 |                     convertor_number = 0
670 | 
671 |             pos = match.end()
672 | 
673 |         suffixed = False
674 |         if final and content[-1] == "/":
675 |             # If a converter is part_isolating=False (matches slashes) and ends with a
676 |             # slash, augment the regex to support slash redirects.
677 |             suffixed = True
678 |             content = content[:-1] + "(?<!/)(/?)"
679 |         if not static:
680 |             content += r"\Z"
681 |         weight = Weighting(
682 |             -len(static_weights),
683 |             static_weights,
684 |             -len(argument_weights),
685 |             argument_weights,
686 |         )
687 |         yield RulePart(
688 |             content=content,
689 |             final=final,
690 |             static=static,
691 |             suffixed=suffixed,
692 |             weight=weight,
693 |         )
694 |         if suffixed:
695 |             yield RulePart(
696 |                 content="", final=False, static=True, suffixed=False, weight=weight
697 |             )
698 | 
699 |     def compile(self) -> None:
700 |         """Compiles the regular expression and stores it."""
701 |         assert self.map is not None, "rule not bound"
702 | 
703 |         if self.map.host_matching:
704 |             domain_rule = self.host or ""
705 |         else:
706 |             domain_rule = self.subdomain or ""
707 |         self._parts = []
708 |         self._trace = []
709 |         self._converters = {}
710 |         if domain_rule == "":
711 |             self._parts = [
712 |                 RulePart(
713 |                     content="",
714 |                     final=False,
715 |                     static=True,
716 |                     suffixed=False,
717 |                     weight=Weighting(0, [], 0, []),
718 |                 )
719 |             ]
720 |         else:
721 |             self._parts.extend(self._parse_rule(domain_rule))
722 |         self._trace.append((False, "|"))
723 |         rule = self.rule
724 |         if self.merge_slashes:
725 |             rule = re.sub("/{2,}?", "/", self.rule)
726 |         self._parts.extend(self._parse_rule(rule))
727 | 
728 |         self._build: t.Callable[..., tuple[str, str]]
729 |         self._build = self._compile_builder(False).__get__(self, None)
730 |         self._build_unknown: t.Callable[..., tuple[str, str]]
731 |         self._build_unknown = self._compile_builder(True).__get__(self, None)
732 | 
733 |     @staticmethod
734 |     def _get_func_code(code: CodeType, name: str) -> t.Callable[..., tuple[str, str]]:
735 |         globs: dict[str, t.Any] = {}
736 |         locs: dict[str, t.Any] = {}
737 |         exec(code, globs, locs)
738 |         return locs[name]  # type: ignore
739 | 
740 |     def _compile_builder(
741 |         self, append_unknown: bool = True
742 |     ) -> t.Callable[..., tuple[str, str]]:
743 |         defaults = self.defaults or {}
744 |         dom_ops: list[tuple[bool, str]] = []
745 |         url_ops: list[tuple[bool, str]] = []
746 | 
747 |         opl = dom_ops
748 |         for is_dynamic, data in self._trace:
749 |             if data == "|" and opl is dom_ops:
750 |                 opl = url_ops
751 |                 continue
752 |             # this seems like a silly case to ever come up but:
753 |             # if a default is given for a value that appears in the rule,
754 |             # resolve it to a constant ahead of time
755 |             if is_dynamic and data in defaults:
756 |                 data = self._converters[data].to_url(defaults[data])
757 |                 opl.append((False, data))
758 |             elif not is_dynamic:
759 |                 # safe = https://url.spec.whatwg.org/#url-path-segment-string
760 |                 opl.append((False, quote(data, safe="!$&'()*+,/:;=@")))
761 |             else:
762 |                 opl.append((True, data))
763 | 
764 |         def _convert(elem: str) -> ast.Call:
765 |             ret = _prefix_names(_CALL_CONVERTER_CODE_FMT.format(elem=elem), ast.Call)
766 |             ret.args = [ast.Name(elem, ast.Load())]
767 |             return ret
768 | 
769 |         def _parts(ops: list[tuple[bool, str]]) -> list[ast.expr]:
770 |             parts: list[ast.expr] = [
771 |                 _convert(elem) if is_dynamic else ast.Constant(elem)
772 |                 for is_dynamic, elem in ops
773 |             ]
774 |             parts = parts or [ast.Constant("")]
775 |             # constant fold
776 |             ret = [parts[0]]
777 |             for p in parts[1:]:
778 |                 if isinstance(p, ast.Constant) and isinstance(ret[-1], ast.Constant):
779 |                     ret[-1] = ast.Constant(ret[-1].value + p.value)
780 |                 else:
781 |                     ret.append(p)
782 |             return ret
783 | 
784 |         dom_parts = _parts(dom_ops)
785 |         url_parts = _parts(url_ops)
786 |         body: list[ast.stmt]
787 |         if not append_unknown:
788 |             body = []
789 |         else:
790 |             body = [_IF_KWARGS_URL_ENCODE_AST]
791 |             url_parts.extend(_URL_ENCODE_AST_NAMES)
792 | 
793 |         def _join(parts: list[ast.expr]) -> ast.expr:
794 |             if len(parts) == 1:  # shortcut
795 |                 return parts[0]
796 |             return ast.JoinedStr(parts)
797 | 
798 |         body.append(
799 |             ast.Return(ast.Tuple([_join(dom_parts), _join(url_parts)], ast.Load()))
800 |         )
801 | 
802 |         pargs = [
803 |             elem
804 |             for is_dynamic, elem in dom_ops + url_ops
805 |             if is_dynamic and elem not in defaults
806 |         ]
807 |         kargs = [str(k) for k in defaults]
808 | 
809 |         func_ast = _prefix_names("def _(): pass", ast.FunctionDef)
810 |         func_ast.name = f"<builder:{self.rule!r}>"
811 |         func_ast.args.args.append(ast.arg(".self", None))
812 |         for arg in pargs + kargs:
813 |             func_ast.args.args.append(ast.arg(arg, None))
814 |         func_ast.args.kwarg = ast.arg(".kwargs", None)
815 |         for _ in kargs:
816 |             func_ast.args.defaults.append(ast.Constant(""))
817 |         func_ast.body = body
818 | 
819 |         # Use `ast.parse` instead of `ast.Module` for better portability, since the
820 |         # signature of `ast.Module` can change.
821 |         module = ast.parse("")
822 |         module.body = [func_ast]
823 | 
824 |         # mark everything as on line 1, offset 0
825 |         # less error-prone than `ast.fix_missing_locations`
826 |         # bad line numbers cause an assert to fail in debug builds
827 |         for node in ast.walk(module):
828 |             if "lineno" in node._attributes:
829 |                 node.lineno = 1  # type: ignore[attr-defined]
830 |             if "end_lineno" in node._attributes:
831 |                 node.end_lineno = node.lineno  # type: ignore[attr-defined]
832 |             if "col_offset" in node._attributes:
833 |                 node.col_offset = 0  # type: ignore[attr-defined]
834 |             if "end_col_offset" in node._attributes:
835 |                 node.end_col_offset = node.col_offset  # type: ignore[attr-defined]
836 | 
837 |         code = compile(module, "<werkzeug routing>", "exec")
838 |         return self._get_func_code(code, func_ast.name)
839 | 
840 |     def build(
841 |         self, values: t.Mapping[str, t.Any], append_unknown: bool = True
842 |     ) -> tuple[str, str] | None:
843 |         """Assembles the relative url for that rule and the subdomain.
844 |         If building doesn't work for some reasons `None` is returned.
845 | 
846 |         :internal:
847 |         """
848 |         try:
849 |             if append_unknown:
850 |                 return self._build_unknown(**values)
851 |             else:
852 |                 return self._build(**values)
853 |         except ValidationError:
854 |             return None
855 | 
856 |     def provides_defaults_for(self, rule: Rule) -> bool:
857 |         """Check if this rule has defaults for a given rule.
858 | 
859 |         :internal:
860 |         """
861 |         return bool(
862 |             not self.build_only
863 |             and self.defaults
864 |             and self.endpoint == rule.endpoint
865 |             and self != rule
866 |             and self.arguments == rule.arguments
867 |         )
868 | 
869 |     def suitable_for(
870 |         self, values: t.Mapping[str, t.Any], method: str | None = None
871 |     ) -> bool:
872 |         """Check if the dict of values has enough data for url generation.
873 | 
874 |         :internal:
875 |         """
876 |         # if a method was given explicitly and that method is not supported
877 |         # by this rule, this rule is not suitable.
878 |         if (
879 |             method is not None
880 |             and self.methods is not None
881 |             and method not in self.methods
882 |         ):
883 |             return False
884 | 
885 |         defaults = self.defaults or ()
886 | 
887 |         # all arguments required must be either in the defaults dict or
888 |         # the value dictionary otherwise it's not suitable
889 |         for key in self.arguments:
890 |             if key not in defaults and key not in values:
891 |                 return False
892 | 
893 |         # in case defaults are given we ensure that either the value was
894 |         # skipped or the value is the same as the default value.
895 |         if defaults:
896 |             for key, value in defaults.items():
897 |                 if key in values and value != values[key]:
898 |                     return False
899 | 
900 |         return True
901 | 
902 |     def build_compare_key(self) -> tuple[int, int, int]:
903 |         """The build compare key for sorting.
904 | 
905 |         :internal:
906 |         """
907 |         return (1 if self.alias else 0, -len(self.arguments), -len(self.defaults or ()))
908 | 
909 |     def __eq__(self, other: object) -> bool:
910 |         return isinstance(other, type(self)) and self._trace == other._trace
911 | 
912 |     __hash__ = None  # type: ignore
913 | 
914 |     def __str__(self) -> str:
915 |         return self.rule
916 | 
917 |     def __repr__(self) -> str:
918 |         if self.map is None:
919 |             return f"<{type(self).__name__} (unbound)>"
920 |         parts = []
921 |         for is_dynamic, data in self._trace:
922 |             if is_dynamic:
923 |                 parts.append(f"<{data}>")
924 |             else:
925 |                 parts.append(data)
926 |         parts_str = "".join(parts).lstrip("|")
927 |         methods = f" ({', '.join(self.methods)})" if self.methods is not None else ""
928 |         return f"<{type(self).__name__} {parts_str!r}{methods} -> {self.endpoint}>"
929 | 
```
Page 98/168FirstPrevNextLast