#
tokens: 48720/50000 2/808 files (page 95/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 95 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/pip/_vendor/urllib3/response.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import absolute_import
  2 | 
  3 | import io
  4 | import logging
  5 | import sys
  6 | import warnings
  7 | import zlib
  8 | from contextlib import contextmanager
  9 | from socket import error as SocketError
 10 | from socket import timeout as SocketTimeout
 11 | 
 12 | brotli = None
 13 | 
 14 | from . import util
 15 | from ._collections import HTTPHeaderDict
 16 | from .connection import BaseSSLError, HTTPException
 17 | from .exceptions import (
 18 |     BodyNotHttplibCompatible,
 19 |     DecodeError,
 20 |     HTTPError,
 21 |     IncompleteRead,
 22 |     InvalidChunkLength,
 23 |     InvalidHeader,
 24 |     ProtocolError,
 25 |     ReadTimeoutError,
 26 |     ResponseNotChunked,
 27 |     SSLError,
 28 | )
 29 | from .packages import six
 30 | from .util.response import is_fp_closed, is_response_to_head
 31 | 
 32 | log = logging.getLogger(__name__)
 33 | 
 34 | 
 35 | class DeflateDecoder(object):
 36 |     def __init__(self):
 37 |         self._first_try = True
 38 |         self._data = b""
 39 |         self._obj = zlib.decompressobj()
 40 | 
 41 |     def __getattr__(self, name):
 42 |         return getattr(self._obj, name)
 43 | 
 44 |     def decompress(self, data):
 45 |         if not data:
 46 |             return data
 47 | 
 48 |         if not self._first_try:
 49 |             return self._obj.decompress(data)
 50 | 
 51 |         self._data += data
 52 |         try:
 53 |             decompressed = self._obj.decompress(data)
 54 |             if decompressed:
 55 |                 self._first_try = False
 56 |                 self._data = None
 57 |             return decompressed
 58 |         except zlib.error:
 59 |             self._first_try = False
 60 |             self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
 61 |             try:
 62 |                 return self.decompress(self._data)
 63 |             finally:
 64 |                 self._data = None
 65 | 
 66 | 
 67 | class GzipDecoderState(object):
 68 | 
 69 |     FIRST_MEMBER = 0
 70 |     OTHER_MEMBERS = 1
 71 |     SWALLOW_DATA = 2
 72 | 
 73 | 
 74 | class GzipDecoder(object):
 75 |     def __init__(self):
 76 |         self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
 77 |         self._state = GzipDecoderState.FIRST_MEMBER
 78 | 
 79 |     def __getattr__(self, name):
 80 |         return getattr(self._obj, name)
 81 | 
 82 |     def decompress(self, data):
 83 |         ret = bytearray()
 84 |         if self._state == GzipDecoderState.SWALLOW_DATA or not data:
 85 |             return bytes(ret)
 86 |         while True:
 87 |             try:
 88 |                 ret += self._obj.decompress(data)
 89 |             except zlib.error:
 90 |                 previous_state = self._state
 91 |                 # Ignore data after the first error
 92 |                 self._state = GzipDecoderState.SWALLOW_DATA
 93 |                 if previous_state == GzipDecoderState.OTHER_MEMBERS:
 94 |                     # Allow trailing garbage acceptable in other gzip clients
 95 |                     return bytes(ret)
 96 |                 raise
 97 |             data = self._obj.unused_data
 98 |             if not data:
 99 |                 return bytes(ret)
100 |             self._state = GzipDecoderState.OTHER_MEMBERS
101 |             self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
102 | 
103 | 
104 | if brotli is not None:
105 | 
106 |     class BrotliDecoder(object):
107 |         # Supports both 'brotlipy' and 'Brotli' packages
108 |         # since they share an import name. The top branches
109 |         # are for 'brotlipy' and bottom branches for 'Brotli'
110 |         def __init__(self):
111 |             self._obj = brotli.Decompressor()
112 |             if hasattr(self._obj, "decompress"):
113 |                 self.decompress = self._obj.decompress
114 |             else:
115 |                 self.decompress = self._obj.process
116 | 
117 |         def flush(self):
118 |             if hasattr(self._obj, "flush"):
119 |                 return self._obj.flush()
120 |             return b""
121 | 
122 | 
123 | class MultiDecoder(object):
124 |     """
125 |     From RFC7231:
126 |         If one or more encodings have been applied to a representation, the
127 |         sender that applied the encodings MUST generate a Content-Encoding
128 |         header field that lists the content codings in the order in which
129 |         they were applied.
130 |     """
131 | 
132 |     def __init__(self, modes):
133 |         self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")]
134 | 
135 |     def flush(self):
136 |         return self._decoders[0].flush()
137 | 
138 |     def decompress(self, data):
139 |         for d in reversed(self._decoders):
140 |             data = d.decompress(data)
141 |         return data
142 | 
143 | 
144 | def _get_decoder(mode):
145 |     if "," in mode:
146 |         return MultiDecoder(mode)
147 | 
148 |     if mode == "gzip":
149 |         return GzipDecoder()
150 | 
151 |     if brotli is not None and mode == "br":
152 |         return BrotliDecoder()
153 | 
154 |     return DeflateDecoder()
155 | 
156 | 
157 | class HTTPResponse(io.IOBase):
158 |     """
159 |     HTTP Response container.
160 | 
161 |     Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
162 |     loaded and decoded on-demand when the ``data`` property is accessed.  This
163 |     class is also compatible with the Python standard library's :mod:`io`
164 |     module, and can hence be treated as a readable object in the context of that
165 |     framework.
166 | 
167 |     Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
168 | 
169 |     :param preload_content:
170 |         If True, the response's body will be preloaded during construction.
171 | 
172 |     :param decode_content:
173 |         If True, will attempt to decode the body based on the
174 |         'content-encoding' header.
175 | 
176 |     :param original_response:
177 |         When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
178 |         object, it's convenient to include the original for debug purposes. It's
179 |         otherwise unused.
180 | 
181 |     :param retries:
182 |         The retries contains the last :class:`~urllib3.util.retry.Retry` that
183 |         was used during the request.
184 | 
185 |     :param enforce_content_length:
186 |         Enforce content length checking. Body returned by server must match
187 |         value of Content-Length header, if present. Otherwise, raise error.
188 |     """
189 | 
190 |     CONTENT_DECODERS = ["gzip", "deflate"]
191 |     if brotli is not None:
192 |         CONTENT_DECODERS += ["br"]
193 |     REDIRECT_STATUSES = [301, 302, 303, 307, 308]
194 | 
195 |     def __init__(
196 |         self,
197 |         body="",
198 |         headers=None,
199 |         status=0,
200 |         version=0,
201 |         reason=None,
202 |         strict=0,
203 |         preload_content=True,
204 |         decode_content=True,
205 |         original_response=None,
206 |         pool=None,
207 |         connection=None,
208 |         msg=None,
209 |         retries=None,
210 |         enforce_content_length=False,
211 |         request_method=None,
212 |         request_url=None,
213 |         auto_close=True,
214 |     ):
215 | 
216 |         if isinstance(headers, HTTPHeaderDict):
217 |             self.headers = headers
218 |         else:
219 |             self.headers = HTTPHeaderDict(headers)
220 |         self.status = status
221 |         self.version = version
222 |         self.reason = reason
223 |         self.strict = strict
224 |         self.decode_content = decode_content
225 |         self.retries = retries
226 |         self.enforce_content_length = enforce_content_length
227 |         self.auto_close = auto_close
228 | 
229 |         self._decoder = None
230 |         self._body = None
231 |         self._fp = None
232 |         self._original_response = original_response
233 |         self._fp_bytes_read = 0
234 |         self.msg = msg
235 |         self._request_url = request_url
236 | 
237 |         if body and isinstance(body, (six.string_types, bytes)):
238 |             self._body = body
239 | 
240 |         self._pool = pool
241 |         self._connection = connection
242 | 
243 |         if hasattr(body, "read"):
244 |             self._fp = body
245 | 
246 |         # Are we using the chunked-style of transfer encoding?
247 |         self.chunked = False
248 |         self.chunk_left = None
249 |         tr_enc = self.headers.get("transfer-encoding", "").lower()
250 |         # Don't incur the penalty of creating a list and then discarding it
251 |         encodings = (enc.strip() for enc in tr_enc.split(","))
252 |         if "chunked" in encodings:
253 |             self.chunked = True
254 | 
255 |         # Determine length of response
256 |         self.length_remaining = self._init_length(request_method)
257 | 
258 |         # If requested, preload the body.
259 |         if preload_content and not self._body:
260 |             self._body = self.read(decode_content=decode_content)
261 | 
262 |     def get_redirect_location(self):
263 |         """
264 |         Should we redirect and where to?
265 | 
266 |         :returns: Truthy redirect location string if we got a redirect status
267 |             code and valid location. ``None`` if redirect status and no
268 |             location. ``False`` if not a redirect status code.
269 |         """
270 |         if self.status in self.REDIRECT_STATUSES:
271 |             return self.headers.get("location")
272 | 
273 |         return False
274 | 
275 |     def release_conn(self):
276 |         if not self._pool or not self._connection:
277 |             return
278 | 
279 |         self._pool._put_conn(self._connection)
280 |         self._connection = None
281 | 
282 |     def drain_conn(self):
283 |         """
284 |         Read and discard any remaining HTTP response data in the response connection.
285 | 
286 |         Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
287 |         """
288 |         try:
289 |             self.read()
290 |         except (HTTPError, SocketError, BaseSSLError, HTTPException):
291 |             pass
292 | 
293 |     @property
294 |     def data(self):
295 |         # For backwards-compat with earlier urllib3 0.4 and earlier.
296 |         if self._body:
297 |             return self._body
298 | 
299 |         if self._fp:
300 |             return self.read(cache_content=True)
301 | 
302 |     @property
303 |     def connection(self):
304 |         return self._connection
305 | 
306 |     def isclosed(self):
307 |         return is_fp_closed(self._fp)
308 | 
309 |     def tell(self):
310 |         """
311 |         Obtain the number of bytes pulled over the wire so far. May differ from
312 |         the amount of content returned by :meth:``urllib3.response.HTTPResponse.read``
313 |         if bytes are encoded on the wire (e.g, compressed).
314 |         """
315 |         return self._fp_bytes_read
316 | 
317 |     def _init_length(self, request_method):
318 |         """
319 |         Set initial length value for Response content if available.
320 |         """
321 |         length = self.headers.get("content-length")
322 | 
323 |         if length is not None:
324 |             if self.chunked:
325 |                 # This Response will fail with an IncompleteRead if it can't be
326 |                 # received as chunked. This method falls back to attempt reading
327 |                 # the response before raising an exception.
328 |                 log.warning(
329 |                     "Received response with both Content-Length and "
330 |                     "Transfer-Encoding set. This is expressly forbidden "
331 |                     "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
332 |                     "attempting to process response as Transfer-Encoding: "
333 |                     "chunked."
334 |                 )
335 |                 return None
336 | 
337 |             try:
338 |                 # RFC 7230 section 3.3.2 specifies multiple content lengths can
339 |                 # be sent in a single Content-Length header
340 |                 # (e.g. Content-Length: 42, 42). This line ensures the values
341 |                 # are all valid ints and that as long as the `set` length is 1,
342 |                 # all values are the same. Otherwise, the header is invalid.
343 |                 lengths = set([int(val) for val in length.split(",")])
344 |                 if len(lengths) > 1:
345 |                     raise InvalidHeader(
346 |                         "Content-Length contained multiple "
347 |                         "unmatching values (%s)" % length
348 |                     )
349 |                 length = lengths.pop()
350 |             except ValueError:
351 |                 length = None
352 |             else:
353 |                 if length < 0:
354 |                     length = None
355 | 
356 |         # Convert status to int for comparison
357 |         # In some cases, httplib returns a status of "_UNKNOWN"
358 |         try:
359 |             status = int(self.status)
360 |         except ValueError:
361 |             status = 0
362 | 
363 |         # Check for responses that shouldn't include a body
364 |         if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD":
365 |             length = 0
366 | 
367 |         return length
368 | 
369 |     def _init_decoder(self):
370 |         """
371 |         Set-up the _decoder attribute if necessary.
372 |         """
373 |         # Note: content-encoding value should be case-insensitive, per RFC 7230
374 |         # Section 3.2
375 |         content_encoding = self.headers.get("content-encoding", "").lower()
376 |         if self._decoder is None:
377 |             if content_encoding in self.CONTENT_DECODERS:
378 |                 self._decoder = _get_decoder(content_encoding)
379 |             elif "," in content_encoding:
380 |                 encodings = [
381 |                     e.strip()
382 |                     for e in content_encoding.split(",")
383 |                     if e.strip() in self.CONTENT_DECODERS
384 |                 ]
385 |                 if len(encodings):
386 |                     self._decoder = _get_decoder(content_encoding)
387 | 
388 |     DECODER_ERROR_CLASSES = (IOError, zlib.error)
389 |     if brotli is not None:
390 |         DECODER_ERROR_CLASSES += (brotli.error,)
391 | 
392 |     def _decode(self, data, decode_content, flush_decoder):
393 |         """
394 |         Decode the data passed in and potentially flush the decoder.
395 |         """
396 |         if not decode_content:
397 |             return data
398 | 
399 |         try:
400 |             if self._decoder:
401 |                 data = self._decoder.decompress(data)
402 |         except self.DECODER_ERROR_CLASSES as e:
403 |             content_encoding = self.headers.get("content-encoding", "").lower()
404 |             raise DecodeError(
405 |                 "Received response with content-encoding: %s, but "
406 |                 "failed to decode it." % content_encoding,
407 |                 e,
408 |             )
409 |         if flush_decoder:
410 |             data += self._flush_decoder()
411 | 
412 |         return data
413 | 
414 |     def _flush_decoder(self):
415 |         """
416 |         Flushes the decoder. Should only be called if the decoder is actually
417 |         being used.
418 |         """
419 |         if self._decoder:
420 |             buf = self._decoder.decompress(b"")
421 |             return buf + self._decoder.flush()
422 | 
423 |         return b""
424 | 
425 |     @contextmanager
426 |     def _error_catcher(self):
427 |         """
428 |         Catch low-level python exceptions, instead re-raising urllib3
429 |         variants, so that low-level exceptions are not leaked in the
430 |         high-level api.
431 | 
432 |         On exit, release the connection back to the pool.
433 |         """
434 |         clean_exit = False
435 | 
436 |         try:
437 |             try:
438 |                 yield
439 | 
440 |             except SocketTimeout:
441 |                 # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
442 |                 # there is yet no clean way to get at it from this context.
443 |                 raise ReadTimeoutError(self._pool, None, "Read timed out.")
444 | 
445 |             except BaseSSLError as e:
446 |                 # FIXME: Is there a better way to differentiate between SSLErrors?
447 |                 if "read operation timed out" not in str(e):
448 |                     # SSL errors related to framing/MAC get wrapped and reraised here
449 |                     raise SSLError(e)
450 | 
451 |                 raise ReadTimeoutError(self._pool, None, "Read timed out.")
452 | 
453 |             except (HTTPException, SocketError) as e:
454 |                 # This includes IncompleteRead.
455 |                 raise ProtocolError("Connection broken: %r" % e, e)
456 | 
457 |             # If no exception is thrown, we should avoid cleaning up
458 |             # unnecessarily.
459 |             clean_exit = True
460 |         finally:
461 |             # If we didn't terminate cleanly, we need to throw away our
462 |             # connection.
463 |             if not clean_exit:
464 |                 # The response may not be closed but we're not going to use it
465 |                 # anymore so close it now to ensure that the connection is
466 |                 # released back to the pool.
467 |                 if self._original_response:
468 |                     self._original_response.close()
469 | 
470 |                 # Closing the response may not actually be sufficient to close
471 |                 # everything, so if we have a hold of the connection close that
472 |                 # too.
473 |                 if self._connection:
474 |                     self._connection.close()
475 | 
476 |             # If we hold the original response but it's closed now, we should
477 |             # return the connection back to the pool.
478 |             if self._original_response and self._original_response.isclosed():
479 |                 self.release_conn()
480 | 
481 |     def _fp_read(self, amt):
482 |         """
483 |         Read a response with the thought that reading the number of bytes
484 |         larger than can fit in a 32-bit int at a time via SSL in some
485 |         known cases leads to an overflow error that has to be prevented
486 |         if `amt` or `self.length_remaining` indicate that a problem may
487 |         happen.
488 | 
489 |         The known cases:
490 |           * 3.8 <= CPython < 3.9.7 because of a bug
491 |             https://github.com/urllib3/urllib3/issues/2513#issuecomment-1152559900.
492 |           * urllib3 injected with pyOpenSSL-backed SSL-support.
493 |           * CPython < 3.10 only when `amt` does not fit 32-bit int.
494 |         """
495 |         assert self._fp
496 |         c_int_max = 2 ** 31 - 1
497 |         if (
498 |             (
499 |                 (amt and amt > c_int_max)
500 |                 or (self.length_remaining and self.length_remaining > c_int_max)
501 |             )
502 |             and not util.IS_SECURETRANSPORT
503 |             and (util.IS_PYOPENSSL or sys.version_info < (3, 10))
504 |         ):
505 |             buffer = io.BytesIO()
506 |             # Besides `max_chunk_amt` being a maximum chunk size, it
507 |             # affects memory overhead of reading a response by this
508 |             # method in CPython.
509 |             # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum
510 |             # chunk size that does not lead to an overflow error, but
511 |             # 256 MiB is a compromise.
512 |             max_chunk_amt = 2 ** 28
513 |             while amt is None or amt != 0:
514 |                 if amt is not None:
515 |                     chunk_amt = min(amt, max_chunk_amt)
516 |                     amt -= chunk_amt
517 |                 else:
518 |                     chunk_amt = max_chunk_amt
519 |                 data = self._fp.read(chunk_amt)
520 |                 if not data:
521 |                     break
522 |                 buffer.write(data)
523 |                 del data  # to reduce peak memory usage by `max_chunk_amt`.
524 |             return buffer.getvalue()
525 |         else:
526 |             # StringIO doesn't like amt=None
527 |             return self._fp.read(amt) if amt is not None else self._fp.read()
528 | 
529 |     def read(self, amt=None, decode_content=None, cache_content=False):
530 |         """
531 |         Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
532 |         parameters: ``decode_content`` and ``cache_content``.
533 | 
534 |         :param amt:
535 |             How much of the content to read. If specified, caching is skipped
536 |             because it doesn't make sense to cache partial content as the full
537 |             response.
538 | 
539 |         :param decode_content:
540 |             If True, will attempt to decode the body based on the
541 |             'content-encoding' header.
542 | 
543 |         :param cache_content:
544 |             If True, will save the returned data such that the same result is
545 |             returned despite of the state of the underlying file object. This
546 |             is useful if you want the ``.data`` property to continue working
547 |             after having ``.read()`` the file object. (Overridden if ``amt`` is
548 |             set.)
549 |         """
550 |         self._init_decoder()
551 |         if decode_content is None:
552 |             decode_content = self.decode_content
553 | 
554 |         if self._fp is None:
555 |             return
556 | 
557 |         flush_decoder = False
558 |         fp_closed = getattr(self._fp, "closed", False)
559 | 
560 |         with self._error_catcher():
561 |             data = self._fp_read(amt) if not fp_closed else b""
562 |             if amt is None:
563 |                 flush_decoder = True
564 |             else:
565 |                 cache_content = False
566 |                 if (
567 |                     amt != 0 and not data
568 |                 ):  # Platform-specific: Buggy versions of Python.
569 |                     # Close the connection when no data is returned
570 |                     #
571 |                     # This is redundant to what httplib/http.client _should_
572 |                     # already do.  However, versions of python released before
573 |                     # December 15, 2012 (http://bugs.python.org/issue16298) do
574 |                     # not properly close the connection in all cases. There is
575 |                     # no harm in redundantly calling close.
576 |                     self._fp.close()
577 |                     flush_decoder = True
578 |                     if self.enforce_content_length and self.length_remaining not in (
579 |                         0,
580 |                         None,
581 |                     ):
582 |                         # This is an edge case that httplib failed to cover due
583 |                         # to concerns of backward compatibility. We're
584 |                         # addressing it here to make sure IncompleteRead is
585 |                         # raised during streaming, so all calls with incorrect
586 |                         # Content-Length are caught.
587 |                         raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
588 | 
589 |         if data:
590 |             self._fp_bytes_read += len(data)
591 |             if self.length_remaining is not None:
592 |                 self.length_remaining -= len(data)
593 | 
594 |             data = self._decode(data, decode_content, flush_decoder)
595 | 
596 |             if cache_content:
597 |                 self._body = data
598 | 
599 |         return data
600 | 
601 |     def stream(self, amt=2 ** 16, decode_content=None):
602 |         """
603 |         A generator wrapper for the read() method. A call will block until
604 |         ``amt`` bytes have been read from the connection or until the
605 |         connection is closed.
606 | 
607 |         :param amt:
608 |             How much of the content to read. The generator will return up to
609 |             much data per iteration, but may return less. This is particularly
610 |             likely when using compressed data. However, the empty string will
611 |             never be returned.
612 | 
613 |         :param decode_content:
614 |             If True, will attempt to decode the body based on the
615 |             'content-encoding' header.
616 |         """
617 |         if self.chunked and self.supports_chunked_reads():
618 |             for line in self.read_chunked(amt, decode_content=decode_content):
619 |                 yield line
620 |         else:
621 |             while not is_fp_closed(self._fp):
622 |                 data = self.read(amt=amt, decode_content=decode_content)
623 | 
624 |                 if data:
625 |                     yield data
626 | 
627 |     @classmethod
628 |     def from_httplib(ResponseCls, r, **response_kw):
629 |         """
630 |         Given an :class:`http.client.HTTPResponse` instance ``r``, return a
631 |         corresponding :class:`urllib3.response.HTTPResponse` object.
632 | 
633 |         Remaining parameters are passed to the HTTPResponse constructor, along
634 |         with ``original_response=r``.
635 |         """
636 |         headers = r.msg
637 | 
638 |         if not isinstance(headers, HTTPHeaderDict):
639 |             if six.PY2:
640 |                 # Python 2.7
641 |                 headers = HTTPHeaderDict.from_httplib(headers)
642 |             else:
643 |                 headers = HTTPHeaderDict(headers.items())
644 | 
645 |         # HTTPResponse objects in Python 3 don't have a .strict attribute
646 |         strict = getattr(r, "strict", 0)
647 |         resp = ResponseCls(
648 |             body=r,
649 |             headers=headers,
650 |             status=r.status,
651 |             version=r.version,
652 |             reason=r.reason,
653 |             strict=strict,
654 |             original_response=r,
655 |             **response_kw
656 |         )
657 |         return resp
658 | 
659 |     # Backwards-compatibility methods for http.client.HTTPResponse
660 |     def getheaders(self):
661 |         warnings.warn(
662 |             "HTTPResponse.getheaders() is deprecated and will be removed "
663 |             "in urllib3 v2.1.0. Instead access HTTPResponse.headers directly.",
664 |             category=DeprecationWarning,
665 |             stacklevel=2,
666 |         )
667 |         return self.headers
668 | 
669 |     def getheader(self, name, default=None):
670 |         warnings.warn(
671 |             "HTTPResponse.getheader() is deprecated and will be removed "
672 |             "in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).",
673 |             category=DeprecationWarning,
674 |             stacklevel=2,
675 |         )
676 |         return self.headers.get(name, default)
677 | 
678 |     # Backwards compatibility for http.cookiejar
679 |     def info(self):
680 |         return self.headers
681 | 
682 |     # Overrides from io.IOBase
683 |     def close(self):
684 |         if not self.closed:
685 |             self._fp.close()
686 | 
687 |         if self._connection:
688 |             self._connection.close()
689 | 
690 |         if not self.auto_close:
691 |             io.IOBase.close(self)
692 | 
693 |     @property
694 |     def closed(self):
695 |         if not self.auto_close:
696 |             return io.IOBase.closed.__get__(self)
697 |         elif self._fp is None:
698 |             return True
699 |         elif hasattr(self._fp, "isclosed"):
700 |             return self._fp.isclosed()
701 |         elif hasattr(self._fp, "closed"):
702 |             return self._fp.closed
703 |         else:
704 |             return True
705 | 
706 |     def fileno(self):
707 |         if self._fp is None:
708 |             raise IOError("HTTPResponse has no file to get a fileno from")
709 |         elif hasattr(self._fp, "fileno"):
710 |             return self._fp.fileno()
711 |         else:
712 |             raise IOError(
713 |                 "The file-like object this HTTPResponse is wrapped "
714 |                 "around has no file descriptor"
715 |             )
716 | 
717 |     def flush(self):
718 |         if (
719 |             self._fp is not None
720 |             and hasattr(self._fp, "flush")
721 |             and not getattr(self._fp, "closed", False)
722 |         ):
723 |             return self._fp.flush()
724 | 
725 |     def readable(self):
726 |         # This method is required for `io` module compatibility.
727 |         return True
728 | 
729 |     def readinto(self, b):
730 |         # This method is required for `io` module compatibility.
731 |         temp = self.read(len(b))
732 |         if len(temp) == 0:
733 |             return 0
734 |         else:
735 |             b[: len(temp)] = temp
736 |             return len(temp)
737 | 
738 |     def supports_chunked_reads(self):
739 |         """
740 |         Checks if the underlying file-like object looks like a
741 |         :class:`http.client.HTTPResponse` object. We do this by testing for
742 |         the fp attribute. If it is present we assume it returns raw chunks as
743 |         processed by read_chunked().
744 |         """
745 |         return hasattr(self._fp, "fp")
746 | 
747 |     def _update_chunk_length(self):
748 |         # First, we'll figure out length of a chunk and then
749 |         # we'll try to read it from socket.
750 |         if self.chunk_left is not None:
751 |             return
752 |         line = self._fp.fp.readline()
753 |         line = line.split(b";", 1)[0]
754 |         try:
755 |             self.chunk_left = int(line, 16)
756 |         except ValueError:
757 |             # Invalid chunked protocol response, abort.
758 |             self.close()
759 |             raise InvalidChunkLength(self, line)
760 | 
761 |     def _handle_chunk(self, amt):
762 |         returned_chunk = None
763 |         if amt is None:
764 |             chunk = self._fp._safe_read(self.chunk_left)
765 |             returned_chunk = chunk
766 |             self._fp._safe_read(2)  # Toss the CRLF at the end of the chunk.
767 |             self.chunk_left = None
768 |         elif amt < self.chunk_left:
769 |             value = self._fp._safe_read(amt)
770 |             self.chunk_left = self.chunk_left - amt
771 |             returned_chunk = value
772 |         elif amt == self.chunk_left:
773 |             value = self._fp._safe_read(amt)
774 |             self._fp._safe_read(2)  # Toss the CRLF at the end of the chunk.
775 |             self.chunk_left = None
776 |             returned_chunk = value
777 |         else:  # amt > self.chunk_left
778 |             returned_chunk = self._fp._safe_read(self.chunk_left)
779 |             self._fp._safe_read(2)  # Toss the CRLF at the end of the chunk.
780 |             self.chunk_left = None
781 |         return returned_chunk
782 | 
783 |     def read_chunked(self, amt=None, decode_content=None):
784 |         """
785 |         Similar to :meth:`HTTPResponse.read`, but with an additional
786 |         parameter: ``decode_content``.
787 | 
788 |         :param amt:
789 |             How much of the content to read. If specified, caching is skipped
790 |             because it doesn't make sense to cache partial content as the full
791 |             response.
792 | 
793 |         :param decode_content:
794 |             If True, will attempt to decode the body based on the
795 |             'content-encoding' header.
796 |         """
797 |         self._init_decoder()
798 |         # FIXME: Rewrite this method and make it a class with a better structured logic.
799 |         if not self.chunked:
800 |             raise ResponseNotChunked(
801 |                 "Response is not chunked. "
802 |                 "Header 'transfer-encoding: chunked' is missing."
803 |             )
804 |         if not self.supports_chunked_reads():
805 |             raise BodyNotHttplibCompatible(
806 |                 "Body should be http.client.HTTPResponse like. "
807 |                 "It should have have an fp attribute which returns raw chunks."
808 |             )
809 | 
810 |         with self._error_catcher():
811 |             # Don't bother reading the body of a HEAD request.
812 |             if self._original_response and is_response_to_head(self._original_response):
813 |                 self._original_response.close()
814 |                 return
815 | 
816 |             # If a response is already read and closed
817 |             # then return immediately.
818 |             if self._fp.fp is None:
819 |                 return
820 | 
821 |             while True:
822 |                 self._update_chunk_length()
823 |                 if self.chunk_left == 0:
824 |                     break
825 |                 chunk = self._handle_chunk(amt)
826 |                 decoded = self._decode(
827 |                     chunk, decode_content=decode_content, flush_decoder=False
828 |                 )
829 |                 if decoded:
830 |                     yield decoded
831 | 
832 |             if decode_content:
833 |                 # On CPython and PyPy, we should never need to flush the
834 |                 # decoder. However, on Jython we *might* need to, so
835 |                 # lets defensively do it anyway.
836 |                 decoded = self._flush_decoder()
837 |                 if decoded:  # Platform-specific: Jython.
838 |                     yield decoded
839 | 
840 |             # Chunk content ends with \r\n: discard it.
841 |             while True:
842 |                 line = self._fp.fp.readline()
843 |                 if not line:
844 |                     # Some sites may not end with '\r\n'.
845 |                     break
846 |                 if line == b"\r\n":
847 |                     break
848 | 
849 |             # We read everything; close the "file".
850 |             if self._original_response:
851 |                 self._original_response.close()
852 | 
853 |     def geturl(self):
854 |         """
855 |         Returns the URL that was the source of this response.
856 |         If the request that generated this response redirected, this method
857 |         will return the final redirect location.
858 |         """
859 |         if self.retries is not None and len(self.retries.history):
860 |             return self.retries.history[-1].redirect_location
861 |         else:
862 |             return self._request_url
863 | 
864 |     def __iter__(self):
865 |         buffer = []
866 |         for chunk in self.stream(decode_content=True):
867 |             if b"\n" in chunk:
868 |                 chunk = chunk.split(b"\n")
869 |                 yield b"".join(buffer) + chunk[0] + b"\n"
870 |                 for x in chunk[1:-1]:
871 |                     yield x + b"\n"
872 |                 if chunk[-1]:
873 |                     buffer = [chunk[-1]]
874 |                 else:
875 |                     buffer = []
876 |             else:
877 |                 buffer.append(chunk)
878 |         if buffer:
879 |             yield b"".join(buffer)
880 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/jinja2/ext.py:
--------------------------------------------------------------------------------

```python
  1 | """Extension API for adding custom tags and behavior."""
  2 | 
  3 | import pprint
  4 | import re
  5 | import typing as t
  6 | 
  7 | from markupsafe import Markup
  8 | 
  9 | from . import defaults
 10 | from . import nodes
 11 | from .environment import Environment
 12 | from .exceptions import TemplateAssertionError
 13 | from .exceptions import TemplateSyntaxError
 14 | from .runtime import concat  # type: ignore
 15 | from .runtime import Context
 16 | from .runtime import Undefined
 17 | from .utils import import_string
 18 | from .utils import pass_context
 19 | 
 20 | if t.TYPE_CHECKING:
 21 |     import typing_extensions as te
 22 | 
 23 |     from .lexer import Token
 24 |     from .lexer import TokenStream
 25 |     from .parser import Parser
 26 | 
 27 |     class _TranslationsBasic(te.Protocol):
 28 |         def gettext(self, message: str) -> str: ...
 29 | 
 30 |         def ngettext(self, singular: str, plural: str, n: int) -> str:
 31 |             pass
 32 | 
 33 |     class _TranslationsContext(_TranslationsBasic):
 34 |         def pgettext(self, context: str, message: str) -> str: ...
 35 | 
 36 |         def npgettext(
 37 |             self, context: str, singular: str, plural: str, n: int
 38 |         ) -> str: ...
 39 | 
 40 |     _SupportedTranslations = t.Union[_TranslationsBasic, _TranslationsContext]
 41 | 
 42 | 
 43 | # I18N functions available in Jinja templates. If the I18N library
 44 | # provides ugettext, it will be assigned to gettext.
 45 | GETTEXT_FUNCTIONS: t.Tuple[str, ...] = (
 46 |     "_",
 47 |     "gettext",
 48 |     "ngettext",
 49 |     "pgettext",
 50 |     "npgettext",
 51 | )
 52 | _ws_re = re.compile(r"\s*\n\s*")
 53 | 
 54 | 
 55 | class Extension:
 56 |     """Extensions can be used to add extra functionality to the Jinja template
 57 |     system at the parser level.  Custom extensions are bound to an environment
 58 |     but may not store environment specific data on `self`.  The reason for
 59 |     this is that an extension can be bound to another environment (for
 60 |     overlays) by creating a copy and reassigning the `environment` attribute.
 61 | 
 62 |     As extensions are created by the environment they cannot accept any
 63 |     arguments for configuration.  One may want to work around that by using
 64 |     a factory function, but that is not possible as extensions are identified
 65 |     by their import name.  The correct way to configure the extension is
 66 |     storing the configuration values on the environment.  Because this way the
 67 |     environment ends up acting as central configuration storage the
 68 |     attributes may clash which is why extensions have to ensure that the names
 69 |     they choose for configuration are not too generic.  ``prefix`` for example
 70 |     is a terrible name, ``fragment_cache_prefix`` on the other hand is a good
 71 |     name as includes the name of the extension (fragment cache).
 72 |     """
 73 | 
 74 |     identifier: t.ClassVar[str]
 75 | 
 76 |     def __init_subclass__(cls) -> None:
 77 |         cls.identifier = f"{cls.__module__}.{cls.__name__}"
 78 | 
 79 |     #: if this extension parses this is the list of tags it's listening to.
 80 |     tags: t.Set[str] = set()
 81 | 
 82 |     #: the priority of that extension.  This is especially useful for
 83 |     #: extensions that preprocess values.  A lower value means higher
 84 |     #: priority.
 85 |     #:
 86 |     #: .. versionadded:: 2.4
 87 |     priority = 100
 88 | 
 89 |     def __init__(self, environment: Environment) -> None:
 90 |         self.environment = environment
 91 | 
 92 |     def bind(self, environment: Environment) -> "Extension":
 93 |         """Create a copy of this extension bound to another environment."""
 94 |         rv = object.__new__(self.__class__)
 95 |         rv.__dict__.update(self.__dict__)
 96 |         rv.environment = environment
 97 |         return rv
 98 | 
 99 |     def preprocess(
100 |         self, source: str, name: t.Optional[str], filename: t.Optional[str] = None
101 |     ) -> str:
102 |         """This method is called before the actual lexing and can be used to
103 |         preprocess the source.  The `filename` is optional.  The return value
104 |         must be the preprocessed source.
105 |         """
106 |         return source
107 | 
108 |     def filter_stream(
109 |         self, stream: "TokenStream"
110 |     ) -> t.Union["TokenStream", t.Iterable["Token"]]:
111 |         """It's passed a :class:`~jinja2.lexer.TokenStream` that can be used
112 |         to filter tokens returned.  This method has to return an iterable of
113 |         :class:`~jinja2.lexer.Token`\\s, but it doesn't have to return a
114 |         :class:`~jinja2.lexer.TokenStream`.
115 |         """
116 |         return stream
117 | 
118 |     def parse(self, parser: "Parser") -> t.Union[nodes.Node, t.List[nodes.Node]]:
119 |         """If any of the :attr:`tags` matched this method is called with the
120 |         parser as first argument.  The token the parser stream is pointing at
121 |         is the name token that matched.  This method has to return one or a
122 |         list of multiple nodes.
123 |         """
124 |         raise NotImplementedError()
125 | 
126 |     def attr(
127 |         self, name: str, lineno: t.Optional[int] = None
128 |     ) -> nodes.ExtensionAttribute:
129 |         """Return an attribute node for the current extension.  This is useful
130 |         to pass constants on extensions to generated template code.
131 | 
132 |         ::
133 | 
134 |             self.attr('_my_attribute', lineno=lineno)
135 |         """
136 |         return nodes.ExtensionAttribute(self.identifier, name, lineno=lineno)
137 | 
138 |     def call_method(
139 |         self,
140 |         name: str,
141 |         args: t.Optional[t.List[nodes.Expr]] = None,
142 |         kwargs: t.Optional[t.List[nodes.Keyword]] = None,
143 |         dyn_args: t.Optional[nodes.Expr] = None,
144 |         dyn_kwargs: t.Optional[nodes.Expr] = None,
145 |         lineno: t.Optional[int] = None,
146 |     ) -> nodes.Call:
147 |         """Call a method of the extension.  This is a shortcut for
148 |         :meth:`attr` + :class:`jinja2.nodes.Call`.
149 |         """
150 |         if args is None:
151 |             args = []
152 |         if kwargs is None:
153 |             kwargs = []
154 |         return nodes.Call(
155 |             self.attr(name, lineno=lineno),
156 |             args,
157 |             kwargs,
158 |             dyn_args,
159 |             dyn_kwargs,
160 |             lineno=lineno,
161 |         )
162 | 
163 | 
164 | @pass_context
165 | def _gettext_alias(
166 |     __context: Context, *args: t.Any, **kwargs: t.Any
167 | ) -> t.Union[t.Any, Undefined]:
168 |     return __context.call(__context.resolve("gettext"), *args, **kwargs)
169 | 
170 | 
171 | def _make_new_gettext(func: t.Callable[[str], str]) -> t.Callable[..., str]:
172 |     @pass_context
173 |     def gettext(__context: Context, __string: str, **variables: t.Any) -> str:
174 |         rv = __context.call(func, __string)
175 |         if __context.eval_ctx.autoescape:
176 |             rv = Markup(rv)
177 |         # Always treat as a format string, even if there are no
178 |         # variables. This makes translation strings more consistent
179 |         # and predictable. This requires escaping
180 |         return rv % variables  # type: ignore
181 | 
182 |     return gettext
183 | 
184 | 
185 | def _make_new_ngettext(func: t.Callable[[str, str, int], str]) -> t.Callable[..., str]:
186 |     @pass_context
187 |     def ngettext(
188 |         __context: Context,
189 |         __singular: str,
190 |         __plural: str,
191 |         __num: int,
192 |         **variables: t.Any,
193 |     ) -> str:
194 |         variables.setdefault("num", __num)
195 |         rv = __context.call(func, __singular, __plural, __num)
196 |         if __context.eval_ctx.autoescape:
197 |             rv = Markup(rv)
198 |         # Always treat as a format string, see gettext comment above.
199 |         return rv % variables  # type: ignore
200 | 
201 |     return ngettext
202 | 
203 | 
204 | def _make_new_pgettext(func: t.Callable[[str, str], str]) -> t.Callable[..., str]:
205 |     @pass_context
206 |     def pgettext(
207 |         __context: Context, __string_ctx: str, __string: str, **variables: t.Any
208 |     ) -> str:
209 |         variables.setdefault("context", __string_ctx)
210 |         rv = __context.call(func, __string_ctx, __string)
211 | 
212 |         if __context.eval_ctx.autoescape:
213 |             rv = Markup(rv)
214 | 
215 |         # Always treat as a format string, see gettext comment above.
216 |         return rv % variables  # type: ignore
217 | 
218 |     return pgettext
219 | 
220 | 
221 | def _make_new_npgettext(
222 |     func: t.Callable[[str, str, str, int], str],
223 | ) -> t.Callable[..., str]:
224 |     @pass_context
225 |     def npgettext(
226 |         __context: Context,
227 |         __string_ctx: str,
228 |         __singular: str,
229 |         __plural: str,
230 |         __num: int,
231 |         **variables: t.Any,
232 |     ) -> str:
233 |         variables.setdefault("context", __string_ctx)
234 |         variables.setdefault("num", __num)
235 |         rv = __context.call(func, __string_ctx, __singular, __plural, __num)
236 | 
237 |         if __context.eval_ctx.autoescape:
238 |             rv = Markup(rv)
239 | 
240 |         # Always treat as a format string, see gettext comment above.
241 |         return rv % variables  # type: ignore
242 | 
243 |     return npgettext
244 | 
245 | 
246 | class InternationalizationExtension(Extension):
247 |     """This extension adds gettext support to Jinja."""
248 | 
249 |     tags = {"trans"}
250 | 
251 |     # TODO: the i18n extension is currently reevaluating values in a few
252 |     # situations.  Take this example:
253 |     #   {% trans count=something() %}{{ count }} foo{% pluralize
254 |     #     %}{{ count }} fooss{% endtrans %}
255 |     # something is called twice here.  One time for the gettext value and
256 |     # the other time for the n-parameter of the ngettext function.
257 | 
258 |     def __init__(self, environment: Environment) -> None:
259 |         super().__init__(environment)
260 |         environment.globals["_"] = _gettext_alias
261 |         environment.extend(
262 |             install_gettext_translations=self._install,
263 |             install_null_translations=self._install_null,
264 |             install_gettext_callables=self._install_callables,
265 |             uninstall_gettext_translations=self._uninstall,
266 |             extract_translations=self._extract,
267 |             newstyle_gettext=False,
268 |         )
269 | 
270 |     def _install(
271 |         self, translations: "_SupportedTranslations", newstyle: t.Optional[bool] = None
272 |     ) -> None:
273 |         # ugettext and ungettext are preferred in case the I18N library
274 |         # is providing compatibility with older Python versions.
275 |         gettext = getattr(translations, "ugettext", None)
276 |         if gettext is None:
277 |             gettext = translations.gettext
278 |         ngettext = getattr(translations, "ungettext", None)
279 |         if ngettext is None:
280 |             ngettext = translations.ngettext
281 | 
282 |         pgettext = getattr(translations, "pgettext", None)
283 |         npgettext = getattr(translations, "npgettext", None)
284 |         self._install_callables(
285 |             gettext, ngettext, newstyle=newstyle, pgettext=pgettext, npgettext=npgettext
286 |         )
287 | 
288 |     def _install_null(self, newstyle: t.Optional[bool] = None) -> None:
289 |         import gettext
290 | 
291 |         translations = gettext.NullTranslations()
292 | 
293 |         if hasattr(translations, "pgettext"):
294 |             # Python < 3.8
295 |             pgettext = translations.pgettext
296 |         else:
297 | 
298 |             def pgettext(c: str, s: str) -> str:  # type: ignore[misc]
299 |                 return s
300 | 
301 |         if hasattr(translations, "npgettext"):
302 |             npgettext = translations.npgettext
303 |         else:
304 | 
305 |             def npgettext(c: str, s: str, p: str, n: int) -> str:  # type: ignore[misc]
306 |                 return s if n == 1 else p
307 | 
308 |         self._install_callables(
309 |             gettext=translations.gettext,
310 |             ngettext=translations.ngettext,
311 |             newstyle=newstyle,
312 |             pgettext=pgettext,
313 |             npgettext=npgettext,
314 |         )
315 | 
316 |     def _install_callables(
317 |         self,
318 |         gettext: t.Callable[[str], str],
319 |         ngettext: t.Callable[[str, str, int], str],
320 |         newstyle: t.Optional[bool] = None,
321 |         pgettext: t.Optional[t.Callable[[str, str], str]] = None,
322 |         npgettext: t.Optional[t.Callable[[str, str, str, int], str]] = None,
323 |     ) -> None:
324 |         if newstyle is not None:
325 |             self.environment.newstyle_gettext = newstyle  # type: ignore
326 |         if self.environment.newstyle_gettext:  # type: ignore
327 |             gettext = _make_new_gettext(gettext)
328 |             ngettext = _make_new_ngettext(ngettext)
329 | 
330 |             if pgettext is not None:
331 |                 pgettext = _make_new_pgettext(pgettext)
332 | 
333 |             if npgettext is not None:
334 |                 npgettext = _make_new_npgettext(npgettext)
335 | 
336 |         self.environment.globals.update(
337 |             gettext=gettext, ngettext=ngettext, pgettext=pgettext, npgettext=npgettext
338 |         )
339 | 
340 |     def _uninstall(self, translations: "_SupportedTranslations") -> None:
341 |         for key in ("gettext", "ngettext", "pgettext", "npgettext"):
342 |             self.environment.globals.pop(key, None)
343 | 
344 |     def _extract(
345 |         self,
346 |         source: t.Union[str, nodes.Template],
347 |         gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
348 |     ) -> t.Iterator[
349 |         t.Tuple[int, str, t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]]]
350 |     ]:
351 |         if isinstance(source, str):
352 |             source = self.environment.parse(source)
353 |         return extract_from_ast(source, gettext_functions)
354 | 
355 |     def parse(self, parser: "Parser") -> t.Union[nodes.Node, t.List[nodes.Node]]:
356 |         """Parse a translatable tag."""
357 |         lineno = next(parser.stream).lineno
358 | 
359 |         context = None
360 |         context_token = parser.stream.next_if("string")
361 | 
362 |         if context_token is not None:
363 |             context = context_token.value
364 | 
365 |         # find all the variables referenced.  Additionally a variable can be
366 |         # defined in the body of the trans block too, but this is checked at
367 |         # a later state.
368 |         plural_expr: t.Optional[nodes.Expr] = None
369 |         plural_expr_assignment: t.Optional[nodes.Assign] = None
370 |         num_called_num = False
371 |         variables: t.Dict[str, nodes.Expr] = {}
372 |         trimmed = None
373 |         while parser.stream.current.type != "block_end":
374 |             if variables:
375 |                 parser.stream.expect("comma")
376 | 
377 |             # skip colon for python compatibility
378 |             if parser.stream.skip_if("colon"):
379 |                 break
380 | 
381 |             token = parser.stream.expect("name")
382 |             if token.value in variables:
383 |                 parser.fail(
384 |                     f"translatable variable {token.value!r} defined twice.",
385 |                     token.lineno,
386 |                     exc=TemplateAssertionError,
387 |                 )
388 | 
389 |             # expressions
390 |             if parser.stream.current.type == "assign":
391 |                 next(parser.stream)
392 |                 variables[token.value] = var = parser.parse_expression()
393 |             elif trimmed is None and token.value in ("trimmed", "notrimmed"):
394 |                 trimmed = token.value == "trimmed"
395 |                 continue
396 |             else:
397 |                 variables[token.value] = var = nodes.Name(token.value, "load")
398 | 
399 |             if plural_expr is None:
400 |                 if isinstance(var, nodes.Call):
401 |                     plural_expr = nodes.Name("_trans", "load")
402 |                     variables[token.value] = plural_expr
403 |                     plural_expr_assignment = nodes.Assign(
404 |                         nodes.Name("_trans", "store"), var
405 |                     )
406 |                 else:
407 |                     plural_expr = var
408 |                 num_called_num = token.value == "num"
409 | 
410 |         parser.stream.expect("block_end")
411 | 
412 |         plural = None
413 |         have_plural = False
414 |         referenced = set()
415 | 
416 |         # now parse until endtrans or pluralize
417 |         singular_names, singular = self._parse_block(parser, True)
418 |         if singular_names:
419 |             referenced.update(singular_names)
420 |             if plural_expr is None:
421 |                 plural_expr = nodes.Name(singular_names[0], "load")
422 |                 num_called_num = singular_names[0] == "num"
423 | 
424 |         # if we have a pluralize block, we parse that too
425 |         if parser.stream.current.test("name:pluralize"):
426 |             have_plural = True
427 |             next(parser.stream)
428 |             if parser.stream.current.type != "block_end":
429 |                 token = parser.stream.expect("name")
430 |                 if token.value not in variables:
431 |                     parser.fail(
432 |                         f"unknown variable {token.value!r} for pluralization",
433 |                         token.lineno,
434 |                         exc=TemplateAssertionError,
435 |                     )
436 |                 plural_expr = variables[token.value]
437 |                 num_called_num = token.value == "num"
438 |             parser.stream.expect("block_end")
439 |             plural_names, plural = self._parse_block(parser, False)
440 |             next(parser.stream)
441 |             referenced.update(plural_names)
442 |         else:
443 |             next(parser.stream)
444 | 
445 |         # register free names as simple name expressions
446 |         for name in referenced:
447 |             if name not in variables:
448 |                 variables[name] = nodes.Name(name, "load")
449 | 
450 |         if not have_plural:
451 |             plural_expr = None
452 |         elif plural_expr is None:
453 |             parser.fail("pluralize without variables", lineno)
454 | 
455 |         if trimmed is None:
456 |             trimmed = self.environment.policies["ext.i18n.trimmed"]
457 |         if trimmed:
458 |             singular = self._trim_whitespace(singular)
459 |             if plural:
460 |                 plural = self._trim_whitespace(plural)
461 | 
462 |         node = self._make_node(
463 |             singular,
464 |             plural,
465 |             context,
466 |             variables,
467 |             plural_expr,
468 |             bool(referenced),
469 |             num_called_num and have_plural,
470 |         )
471 |         node.set_lineno(lineno)
472 |         if plural_expr_assignment is not None:
473 |             return [plural_expr_assignment, node]
474 |         else:
475 |             return node
476 | 
477 |     def _trim_whitespace(self, string: str, _ws_re: t.Pattern[str] = _ws_re) -> str:
478 |         return _ws_re.sub(" ", string.strip())
479 | 
480 |     def _parse_block(
481 |         self, parser: "Parser", allow_pluralize: bool
482 |     ) -> t.Tuple[t.List[str], str]:
483 |         """Parse until the next block tag with a given name."""
484 |         referenced = []
485 |         buf = []
486 | 
487 |         while True:
488 |             if parser.stream.current.type == "data":
489 |                 buf.append(parser.stream.current.value.replace("%", "%%"))
490 |                 next(parser.stream)
491 |             elif parser.stream.current.type == "variable_begin":
492 |                 next(parser.stream)
493 |                 name = parser.stream.expect("name").value
494 |                 referenced.append(name)
495 |                 buf.append(f"%({name})s")
496 |                 parser.stream.expect("variable_end")
497 |             elif parser.stream.current.type == "block_begin":
498 |                 next(parser.stream)
499 |                 block_name = (
500 |                     parser.stream.current.value
501 |                     if parser.stream.current.type == "name"
502 |                     else None
503 |                 )
504 |                 if block_name == "endtrans":
505 |                     break
506 |                 elif block_name == "pluralize":
507 |                     if allow_pluralize:
508 |                         break
509 |                     parser.fail(
510 |                         "a translatable section can have only one pluralize section"
511 |                     )
512 |                 elif block_name == "trans":
513 |                     parser.fail(
514 |                         "trans blocks can't be nested; did you mean `endtrans`?"
515 |                     )
516 |                 parser.fail(
517 |                     f"control structures in translatable sections are not allowed; "
518 |                     f"saw `{block_name}`"
519 |                 )
520 |             elif parser.stream.eos:
521 |                 parser.fail("unclosed translation block")
522 |             else:
523 |                 raise RuntimeError("internal parser error")
524 | 
525 |         return referenced, concat(buf)
526 | 
527 |     def _make_node(
528 |         self,
529 |         singular: str,
530 |         plural: t.Optional[str],
531 |         context: t.Optional[str],
532 |         variables: t.Dict[str, nodes.Expr],
533 |         plural_expr: t.Optional[nodes.Expr],
534 |         vars_referenced: bool,
535 |         num_called_num: bool,
536 |     ) -> nodes.Output:
537 |         """Generates a useful node from the data provided."""
538 |         newstyle = self.environment.newstyle_gettext  # type: ignore
539 |         node: nodes.Expr
540 | 
541 |         # no variables referenced?  no need to escape for old style
542 |         # gettext invocations only if there are vars.
543 |         if not vars_referenced and not newstyle:
544 |             singular = singular.replace("%%", "%")
545 |             if plural:
546 |                 plural = plural.replace("%%", "%")
547 | 
548 |         func_name = "gettext"
549 |         func_args: t.List[nodes.Expr] = [nodes.Const(singular)]
550 | 
551 |         if context is not None:
552 |             func_args.insert(0, nodes.Const(context))
553 |             func_name = f"p{func_name}"
554 | 
555 |         if plural_expr is not None:
556 |             func_name = f"n{func_name}"
557 |             func_args.extend((nodes.Const(plural), plural_expr))
558 | 
559 |         node = nodes.Call(nodes.Name(func_name, "load"), func_args, [], None, None)
560 | 
561 |         # in case newstyle gettext is used, the method is powerful
562 |         # enough to handle the variable expansion and autoescape
563 |         # handling itself
564 |         if newstyle:
565 |             for key, value in variables.items():
566 |                 # the function adds that later anyways in case num was
567 |                 # called num, so just skip it.
568 |                 if num_called_num and key == "num":
569 |                     continue
570 |                 node.kwargs.append(nodes.Keyword(key, value))
571 | 
572 |         # otherwise do that here
573 |         else:
574 |             # mark the return value as safe if we are in an
575 |             # environment with autoescaping turned on
576 |             node = nodes.MarkSafeIfAutoescape(node)
577 |             if variables:
578 |                 node = nodes.Mod(
579 |                     node,
580 |                     nodes.Dict(
581 |                         [
582 |                             nodes.Pair(nodes.Const(key), value)
583 |                             for key, value in variables.items()
584 |                         ]
585 |                     ),
586 |                 )
587 |         return nodes.Output([node])
588 | 
589 | 
590 | class ExprStmtExtension(Extension):
591 |     """Adds a `do` tag to Jinja that works like the print statement just
592 |     that it doesn't print the return value.
593 |     """
594 | 
595 |     tags = {"do"}
596 | 
597 |     def parse(self, parser: "Parser") -> nodes.ExprStmt:
598 |         node = nodes.ExprStmt(lineno=next(parser.stream).lineno)
599 |         node.node = parser.parse_tuple()
600 |         return node
601 | 
602 | 
603 | class LoopControlExtension(Extension):
604 |     """Adds break and continue to the template engine."""
605 | 
606 |     tags = {"break", "continue"}
607 | 
608 |     def parse(self, parser: "Parser") -> t.Union[nodes.Break, nodes.Continue]:
609 |         token = next(parser.stream)
610 |         if token.value == "break":
611 |             return nodes.Break(lineno=token.lineno)
612 |         return nodes.Continue(lineno=token.lineno)
613 | 
614 | 
615 | class DebugExtension(Extension):
616 |     """A ``{% debug %}`` tag that dumps the available variables,
617 |     filters, and tests.
618 | 
619 |     .. code-block:: html+jinja
620 | 
621 |         <pre>{% debug %}</pre>
622 | 
623 |     .. code-block:: text
624 | 
625 |         {'context': {'cycler': <class 'jinja2.utils.Cycler'>,
626 |                      ...,
627 |                      'namespace': <class 'jinja2.utils.Namespace'>},
628 |          'filters': ['abs', 'attr', 'batch', 'capitalize', 'center', 'count', 'd',
629 |                      ..., 'urlencode', 'urlize', 'wordcount', 'wordwrap', 'xmlattr'],
630 |          'tests': ['!=', '<', '<=', '==', '>', '>=', 'callable', 'defined',
631 |                    ..., 'odd', 'sameas', 'sequence', 'string', 'undefined', 'upper']}
632 | 
633 |     .. versionadded:: 2.11.0
634 |     """
635 | 
636 |     tags = {"debug"}
637 | 
638 |     def parse(self, parser: "Parser") -> nodes.Output:
639 |         lineno = parser.stream.expect("name:debug").lineno
640 |         context = nodes.ContextReference()
641 |         result = self.call_method("_render", [context], lineno=lineno)
642 |         return nodes.Output([result], lineno=lineno)
643 | 
644 |     def _render(self, context: Context) -> str:
645 |         result = {
646 |             "context": context.get_all(),
647 |             "filters": sorted(self.environment.filters.keys()),
648 |             "tests": sorted(self.environment.tests.keys()),
649 |         }
650 | 
651 |         # Set the depth since the intent is to show the top few names.
652 |         return pprint.pformat(result, depth=3, compact=True)
653 | 
654 | 
655 | def extract_from_ast(
656 |     ast: nodes.Template,
657 |     gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
658 |     babel_style: bool = True,
659 | ) -> t.Iterator[
660 |     t.Tuple[int, str, t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]]]
661 | ]:
662 |     """Extract localizable strings from the given template node.  Per
663 |     default this function returns matches in babel style that means non string
664 |     parameters as well as keyword arguments are returned as `None`.  This
665 |     allows Babel to figure out what you really meant if you are using
666 |     gettext functions that allow keyword arguments for placeholder expansion.
667 |     If you don't want that behavior set the `babel_style` parameter to `False`
668 |     which causes only strings to be returned and parameters are always stored
669 |     in tuples.  As a consequence invalid gettext calls (calls without a single
670 |     string parameter or string parameters after non-string parameters) are
671 |     skipped.
672 | 
673 |     This example explains the behavior:
674 | 
675 |     >>> from jinja2 import Environment
676 |     >>> env = Environment()
677 |     >>> node = env.parse('{{ (_("foo"), _(), ngettext("foo", "bar", 42)) }}')
678 |     >>> list(extract_from_ast(node))
679 |     [(1, '_', 'foo'), (1, '_', ()), (1, 'ngettext', ('foo', 'bar', None))]
680 |     >>> list(extract_from_ast(node, babel_style=False))
681 |     [(1, '_', ('foo',)), (1, 'ngettext', ('foo', 'bar'))]
682 | 
683 |     For every string found this function yields a ``(lineno, function,
684 |     message)`` tuple, where:
685 | 
686 |     * ``lineno`` is the number of the line on which the string was found,
687 |     * ``function`` is the name of the ``gettext`` function used (if the
688 |       string was extracted from embedded Python code), and
689 |     *   ``message`` is the string, or a tuple of strings for functions
690 |          with multiple string arguments.
691 | 
692 |     This extraction function operates on the AST and is because of that unable
693 |     to extract any comments.  For comment support you have to use the babel
694 |     extraction interface or extract comments yourself.
695 |     """
696 |     out: t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]]
697 | 
698 |     for node in ast.find_all(nodes.Call):
699 |         if (
700 |             not isinstance(node.node, nodes.Name)
701 |             or node.node.name not in gettext_functions
702 |         ):
703 |             continue
704 | 
705 |         strings: t.List[t.Optional[str]] = []
706 | 
707 |         for arg in node.args:
708 |             if isinstance(arg, nodes.Const) and isinstance(arg.value, str):
709 |                 strings.append(arg.value)
710 |             else:
711 |                 strings.append(None)
712 | 
713 |         for _ in node.kwargs:
714 |             strings.append(None)
715 |         if node.dyn_args is not None:
716 |             strings.append(None)
717 |         if node.dyn_kwargs is not None:
718 |             strings.append(None)
719 | 
720 |         if not babel_style:
721 |             out = tuple(x for x in strings if x is not None)
722 | 
723 |             if not out:
724 |                 continue
725 |         else:
726 |             if len(strings) == 1:
727 |                 out = strings[0]
728 |             else:
729 |                 out = tuple(strings)
730 | 
731 |         yield node.lineno, node.node.name, out
732 | 
733 | 
734 | class _CommentFinder:
735 |     """Helper class to find comments in a token stream.  Can only
736 |     find comments for gettext calls forwards.  Once the comment
737 |     from line 4 is found, a comment for line 1 will not return a
738 |     usable value.
739 |     """
740 | 
741 |     def __init__(
742 |         self, tokens: t.Sequence[t.Tuple[int, str, str]], comment_tags: t.Sequence[str]
743 |     ) -> None:
744 |         self.tokens = tokens
745 |         self.comment_tags = comment_tags
746 |         self.offset = 0
747 |         self.last_lineno = 0
748 | 
749 |     def find_backwards(self, offset: int) -> t.List[str]:
750 |         try:
751 |             for _, token_type, token_value in reversed(
752 |                 self.tokens[self.offset : offset]
753 |             ):
754 |                 if token_type in ("comment", "linecomment"):
755 |                     try:
756 |                         prefix, comment = token_value.split(None, 1)
757 |                     except ValueError:
758 |                         continue
759 |                     if prefix in self.comment_tags:
760 |                         return [comment.rstrip()]
761 |             return []
762 |         finally:
763 |             self.offset = offset
764 | 
765 |     def find_comments(self, lineno: int) -> t.List[str]:
766 |         if not self.comment_tags or self.last_lineno > lineno:
767 |             return []
768 |         for idx, (token_lineno, _, _) in enumerate(self.tokens[self.offset :]):
769 |             if token_lineno > lineno:
770 |                 return self.find_backwards(self.offset + idx)
771 |         return self.find_backwards(len(self.tokens))
772 | 
773 | 
774 | def babel_extract(
775 |     fileobj: t.BinaryIO,
776 |     keywords: t.Sequence[str],
777 |     comment_tags: t.Sequence[str],
778 |     options: t.Dict[str, t.Any],
779 | ) -> t.Iterator[
780 |     t.Tuple[
781 |         int, str, t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]], t.List[str]
782 |     ]
783 | ]:
784 |     """Babel extraction method for Jinja templates.
785 | 
786 |     .. versionchanged:: 2.3
787 |        Basic support for translation comments was added.  If `comment_tags`
788 |        is now set to a list of keywords for extraction, the extractor will
789 |        try to find the best preceding comment that begins with one of the
790 |        keywords.  For best results, make sure to not have more than one
791 |        gettext call in one line of code and the matching comment in the
792 |        same line or the line before.
793 | 
794 |     .. versionchanged:: 2.5.1
795 |        The `newstyle_gettext` flag can be set to `True` to enable newstyle
796 |        gettext calls.
797 | 
798 |     .. versionchanged:: 2.7
799 |        A `silent` option can now be provided.  If set to `False` template
800 |        syntax errors are propagated instead of being ignored.
801 | 
802 |     :param fileobj: the file-like object the messages should be extracted from
803 |     :param keywords: a list of keywords (i.e. function names) that should be
804 |                      recognized as translation functions
805 |     :param comment_tags: a list of translator tags to search for and include
806 |                          in the results.
807 |     :param options: a dictionary of additional options (optional)
808 |     :return: an iterator over ``(lineno, funcname, message, comments)`` tuples.
809 |              (comments will be empty currently)
810 |     """
811 |     extensions: t.Dict[t.Type[Extension], None] = {}
812 | 
813 |     for extension_name in options.get("extensions", "").split(","):
814 |         extension_name = extension_name.strip()
815 | 
816 |         if not extension_name:
817 |             continue
818 | 
819 |         extensions[import_string(extension_name)] = None
820 | 
821 |     if InternationalizationExtension not in extensions:
822 |         extensions[InternationalizationExtension] = None
823 | 
824 |     def getbool(options: t.Mapping[str, str], key: str, default: bool = False) -> bool:
825 |         return options.get(key, str(default)).lower() in {"1", "on", "yes", "true"}
826 | 
827 |     silent = getbool(options, "silent", True)
828 |     environment = Environment(
829 |         options.get("block_start_string", defaults.BLOCK_START_STRING),
830 |         options.get("block_end_string", defaults.BLOCK_END_STRING),
831 |         options.get("variable_start_string", defaults.VARIABLE_START_STRING),
832 |         options.get("variable_end_string", defaults.VARIABLE_END_STRING),
833 |         options.get("comment_start_string", defaults.COMMENT_START_STRING),
834 |         options.get("comment_end_string", defaults.COMMENT_END_STRING),
835 |         options.get("line_statement_prefix") or defaults.LINE_STATEMENT_PREFIX,
836 |         options.get("line_comment_prefix") or defaults.LINE_COMMENT_PREFIX,
837 |         getbool(options, "trim_blocks", defaults.TRIM_BLOCKS),
838 |         getbool(options, "lstrip_blocks", defaults.LSTRIP_BLOCKS),
839 |         defaults.NEWLINE_SEQUENCE,
840 |         getbool(options, "keep_trailing_newline", defaults.KEEP_TRAILING_NEWLINE),
841 |         tuple(extensions),
842 |         cache_size=0,
843 |         auto_reload=False,
844 |     )
845 | 
846 |     if getbool(options, "trimmed"):
847 |         environment.policies["ext.i18n.trimmed"] = True
848 |     if getbool(options, "newstyle_gettext"):
849 |         environment.newstyle_gettext = True  # type: ignore
850 | 
851 |     source = fileobj.read().decode(options.get("encoding", "utf-8"))
852 |     try:
853 |         node = environment.parse(source)
854 |         tokens = list(environment.lex(environment.preprocess(source)))
855 |     except TemplateSyntaxError:
856 |         if not silent:
857 |             raise
858 |         # skip templates with syntax errors
859 |         return
860 | 
861 |     finder = _CommentFinder(tokens, comment_tags)
862 |     for lineno, func, message in extract_from_ast(node, keywords):
863 |         yield lineno, func, message, finder.find_comments(lineno)
864 | 
865 | 
866 | #: nicer import names
867 | i18n = InternationalizationExtension
868 | do = ExprStmtExtension
869 | loopcontrols = LoopControlExtension
870 | debug = DebugExtension
871 | 
```
Page 95/168FirstPrevNextLast