#
tokens: 48946/50000 4/808 files (page 51/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 51 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/bs4/tests/test_pageelement.py:
--------------------------------------------------------------------------------

```python
  1 | """Tests of the bs4.element.PageElement class"""
  2 | import copy
  3 | import pickle
  4 | import pytest
  5 | import sys
  6 | 
  7 | from bs4 import BeautifulSoup
  8 | from bs4.element import (
  9 |     Comment,
 10 |     ResultSet,
 11 |     SoupStrainer,
 12 | )
 13 | from . import (
 14 |     SoupTest,
 15 | )
 16 | 
 17 | class TestEncoding(SoupTest):
 18 |     """Test the ability to encode objects into strings."""
 19 | 
 20 |     def test_unicode_string_can_be_encoded(self):
 21 |         html = "<b>\N{SNOWMAN}</b>"
 22 |         soup = self.soup(html)
 23 |         assert soup.b.string.encode("utf-8") == "\N{SNOWMAN}".encode("utf-8")
 24 | 
 25 |     def test_tag_containing_unicode_string_can_be_encoded(self):
 26 |         html = "<b>\N{SNOWMAN}</b>"
 27 |         soup = self.soup(html)
 28 |         assert soup.b.encode("utf-8") == html.encode("utf-8")
 29 | 
 30 |     def test_encoding_substitutes_unrecognized_characters_by_default(self):
 31 |         html = "<b>\N{SNOWMAN}</b>"
 32 |         soup = self.soup(html)
 33 |         assert soup.b.encode("ascii") == b"<b>&#9731;</b>"
 34 | 
 35 |     def test_encoding_can_be_made_strict(self):
 36 |         html = "<b>\N{SNOWMAN}</b>"
 37 |         soup = self.soup(html)
 38 |         with pytest.raises(UnicodeEncodeError):
 39 |             soup.encode("ascii", errors="strict")
 40 | 
 41 |     def test_decode_contents(self):
 42 |         html = "<b>\N{SNOWMAN}</b>"
 43 |         soup = self.soup(html)
 44 |         assert "\N{SNOWMAN}" == soup.b.decode_contents()
 45 | 
 46 |     def test_encode_contents(self):
 47 |         html = "<b>\N{SNOWMAN}</b>"
 48 |         soup = self.soup(html)
 49 |         assert "\N{SNOWMAN}".encode("utf8") == soup.b.encode_contents(
 50 |             encoding="utf8"
 51 |         )
 52 |         
 53 |     def test_encode_deeply_nested_document(self):
 54 |         # This test verifies that encoding a string doesn't involve
 55 |         # any recursive function calls. If it did, this test would
 56 |         # overflow the Python interpreter stack.
 57 |         limit = sys.getrecursionlimit() + 1
 58 |         markup = "<span>" * limit
 59 |         soup = self.soup(markup)
 60 |         encoded = soup.encode()
 61 |         assert limit == encoded.count(b"<span>")
 62 | 
 63 |     def test_deprecated_renderContents(self):
 64 |         html = "<b>\N{SNOWMAN}</b>"
 65 |         soup = self.soup(html)
 66 |         soup.renderContents()
 67 |         assert "\N{SNOWMAN}".encode("utf8") == soup.b.renderContents()
 68 | 
 69 |     def test_repr(self):
 70 |         html = "<b>\N{SNOWMAN}</b>"
 71 |         soup = self.soup(html)
 72 |         assert html == repr(soup)
 73 | 
 74 |         
 75 | class TestFormatters(SoupTest):
 76 |     """Test the formatting feature, used by methods like decode() and
 77 |     prettify(), and the formatters themselves.
 78 |     """
 79 |     
 80 |     def test_default_formatter_is_minimal(self):
 81 |         markup = "<b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
 82 |         soup = self.soup(markup)
 83 |         decoded = soup.decode(formatter="minimal")
 84 |         # The < is converted back into &lt; but the e-with-acute is left alone.
 85 |         assert decoded == self.document_for(
 86 |                 "<b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
 87 |         )
 88 | 
 89 |     def test_formatter_html(self):
 90 |         markup = "<br><b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
 91 |         soup = self.soup(markup)
 92 |         decoded = soup.decode(formatter="html")
 93 |         assert decoded == self.document_for(
 94 |             "<br/><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>"
 95 |         )
 96 | 
 97 |     def test_formatter_html5(self):
 98 |         markup = "<br><b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
 99 |         soup = self.soup(markup)
100 |         decoded = soup.decode(formatter="html5")
101 |         assert decoded == self.document_for(
102 |             "<br><b>&lt;&lt;Sacr&eacute; bleu!&gt;&gt;</b>"
103 |         )
104 |         
105 |     def test_formatter_minimal(self):
106 |         markup = "<b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
107 |         soup = self.soup(markup)
108 |         decoded = soup.decode(formatter="minimal")
109 |         # The < is converted back into &lt; but the e-with-acute is left alone.
110 |         assert decoded == self.document_for(
111 |                 "<b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
112 |         )
113 | 
114 |     def test_formatter_null(self):
115 |         markup = "<b>&lt;&lt;Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!&gt;&gt;</b>"
116 |         soup = self.soup(markup)
117 |         decoded = soup.decode(formatter=None)
118 |         # Neither the angle brackets nor the e-with-acute are converted.
119 |         # This is not valid HTML, but it's what the user wanted.
120 |         assert decoded == self.document_for(
121 |             "<b><<Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!>></b>"
122 |         )
123 | 
124 |     def test_formatter_custom(self):
125 |         markup = "<b>&lt;foo&gt;</b><b>bar</b><br/>"
126 |         soup = self.soup(markup)
127 |         decoded = soup.decode(formatter = lambda x: x.upper())
128 |         # Instead of normal entity conversion code, the custom
129 |         # callable is called on every string.
130 |         assert decoded == self.document_for("<b><FOO></b><b>BAR</b><br/>")
131 | 
132 |     def test_formatter_is_run_on_attribute_values(self):
133 |         markup = '<a href="http://a.com?a=b&c=é">e</a>'
134 |         soup = self.soup(markup)
135 |         a = soup.a
136 | 
137 |         expect_minimal = '<a href="http://a.com?a=b&amp;c=é">e</a>'
138 | 
139 |         assert expect_minimal == a.decode()
140 |         assert expect_minimal == a.decode(formatter="minimal")
141 | 
142 |         expect_html = '<a href="http://a.com?a=b&amp;c=&eacute;">e</a>'
143 |         assert expect_html == a.decode(formatter="html")
144 | 
145 |         assert markup == a.decode(formatter=None)
146 |         expect_upper = '<a href="HTTP://A.COM?A=B&C=É">E</a>'
147 |         assert expect_upper == a.decode(formatter=lambda x: x.upper())
148 | 
149 |     def test_formatter_skips_script_tag_for_html_documents(self):
150 |         doc = """
151 |   <script type="text/javascript">
152 |    console.log("< < hey > > ");
153 |   </script>
154 | """
155 |         encoded = BeautifulSoup(doc, 'html.parser').encode()
156 |         assert b"< < hey > >" in encoded
157 | 
158 |     def test_formatter_skips_style_tag_for_html_documents(self):
159 |         doc = """
160 |   <style type="text/css">
161 |    console.log("< < hey > > ");
162 |   </style>
163 | """
164 |         encoded = BeautifulSoup(doc, 'html.parser').encode()
165 |         assert b"< < hey > >" in encoded
166 | 
167 |     def test_prettify_leaves_preformatted_text_alone(self):
168 |         soup = self.soup("<div>  foo  <pre>  \tbar\n  \n  </pre>  baz  <textarea> eee\nfff\t</textarea></div>")
169 |         # Everything outside the <pre> tag is reformatted, but everything
170 |         # inside is left alone.
171 |         assert '<div>\n foo\n <pre>  \tbar\n  \n  </pre>\n baz\n <textarea> eee\nfff\t</textarea>\n</div>\n' == soup.div.prettify()
172 | 
173 |     def test_prettify_handles_nested_string_literal_tags(self):
174 |         # Most of this markup is inside a <pre> tag, so prettify()
175 |         # only does three things to it:
176 |         # 1. Add a newline and a space between the <div> and the <pre>
177 |         # 2. Add a newline after the </pre>
178 |         # 3. Add a newline at the end.
179 |         #
180 |         # The contents of the <pre> tag are left completely alone.  In
181 |         # particular, we don't start adding whitespace again once we
182 |         # encounter the first </pre> tag, because we know it's not
183 |         # the one that put us into string literal mode.
184 |         markup = """<div><pre><code>some
185 | <script><pre>code</pre></script> for you 
186 | </code></pre></div>"""
187 | 
188 |         expect = """<div>
189 |  <pre><code>some
190 | <script><pre>code</pre></script> for you 
191 | </code></pre>
192 | </div>
193 | """
194 |         soup = self.soup(markup)
195 |         assert expect == soup.div.prettify()
196 | 
197 |     def test_prettify_accepts_formatter_function(self):
198 |         soup = BeautifulSoup("<html><body>foo</body></html>", 'html.parser')
199 |         pretty = soup.prettify(formatter = lambda x: x.upper())
200 |         assert "FOO" in pretty
201 | 
202 |     def test_prettify_outputs_unicode_by_default(self):
203 |         soup = self.soup("<a></a>")
204 |         assert str == type(soup.prettify())
205 | 
206 |     def test_prettify_can_encode_data(self):
207 |         soup = self.soup("<a></a>")
208 |         assert bytes == type(soup.prettify("utf-8"))
209 | 
210 |     def test_html_entity_substitution_off_by_default(self):
211 |         markup = "<b>Sacr\N{LATIN SMALL LETTER E WITH ACUTE} bleu!</b>"
212 |         soup = self.soup(markup)
213 |         encoded = soup.b.encode("utf-8")
214 |         assert encoded == markup.encode('utf-8')
215 | 
216 |     def test_encoding_substitution(self):
217 |         # Here's the <meta> tag saying that a document is
218 |         # encoded in Shift-JIS.
219 |         meta_tag = ('<meta content="text/html; charset=x-sjis" '
220 |                     'http-equiv="Content-type"/>')
221 |         soup = self.soup(meta_tag)
222 | 
223 |         # Parse the document, and the charset apprears unchanged.
224 |         assert soup.meta['content'] == 'text/html; charset=x-sjis'
225 | 
226 |         # Encode the document into some encoding, and the encoding is
227 |         # substituted into the meta tag.
228 |         utf_8 = soup.encode("utf-8")
229 |         assert b"charset=utf-8" in utf_8
230 | 
231 |         euc_jp = soup.encode("euc_jp")
232 |         assert b"charset=euc_jp" in euc_jp
233 | 
234 |         shift_jis = soup.encode("shift-jis")
235 |         assert b"charset=shift-jis" in shift_jis
236 | 
237 |         utf_16_u = soup.encode("utf-16").decode("utf-16")
238 |         assert "charset=utf-16" in utf_16_u
239 | 
240 |     def test_encoding_substitution_doesnt_happen_if_tag_is_strained(self):
241 |         markup = ('<head><meta content="text/html; charset=x-sjis" '
242 |                     'http-equiv="Content-type"/></head><pre>foo</pre>')
243 | 
244 |         # Beautiful Soup used to try to rewrite the meta tag even if the
245 |         # meta tag got filtered out by the strainer. This test makes
246 |         # sure that doesn't happen.
247 |         strainer = SoupStrainer('pre')
248 |         soup = self.soup(markup, parse_only=strainer)
249 |         assert soup.contents[0].name == 'pre'
250 | 
251 | 
252 | class TestPersistence(SoupTest):
253 |     "Testing features like pickle and deepcopy."
254 | 
255 |     def setup_method(self):
256 |         self.page = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
257 | "http://www.w3.org/TR/REC-html40/transitional.dtd">
258 | <html>
259 | <head>
260 | <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
261 | <title>Beautiful Soup: We called him Tortoise because he taught us.</title>
262 | <link rev="made" href="mailto:[email protected]">
263 | <meta name="Description" content="Beautiful Soup: an HTML parser optimized for screen-scraping.">
264 | <meta name="generator" content="Markov Approximation 1.4 (module: leonardr)">
265 | <meta name="author" content="Leonard Richardson">
266 | </head>
267 | <body>
268 | <a href="foo">foo</a>
269 | <a href="foo"><b>bar</b></a>
270 | </body>
271 | </html>"""
272 |         self.tree = self.soup(self.page)
273 | 
274 |     def test_pickle_and_unpickle_identity(self):
275 |         # Pickling a tree, then unpickling it, yields a tree identical
276 |         # to the original.
277 |         dumped = pickle.dumps(self.tree, 2)
278 |         loaded = pickle.loads(dumped)
279 |         assert loaded.__class__ == BeautifulSoup
280 |         assert loaded.decode() == self.tree.decode()
281 |         
282 |     def test_deepcopy_identity(self):
283 |         # Making a deepcopy of a tree yields an identical tree.
284 |         copied = copy.deepcopy(self.tree)
285 |         assert copied.decode() == self.tree.decode()
286 | 
287 |     def test_copy_deeply_nested_document(self):
288 |         # This test verifies that copy and deepcopy don't involve any
289 |         # recursive function calls. If they did, this test would
290 |         # overflow the Python interpreter stack.
291 |         limit = sys.getrecursionlimit() + 1
292 |         markup = "<span>" * limit
293 | 
294 |         soup = self.soup(markup)
295 |         
296 |         copied = copy.copy(soup)
297 |         copied = copy.deepcopy(soup)
298 | 
299 |     def test_copy_preserves_encoding(self):
300 |         soup = BeautifulSoup(b'<p>&nbsp;</p>', 'html.parser')
301 |         encoding = soup.original_encoding
302 |         copy = soup.__copy__()
303 |         assert "<p> </p>" == str(copy)
304 |         assert encoding == copy.original_encoding
305 | 
306 |     def test_copy_preserves_builder_information(self):
307 | 
308 |         tag = self.soup('<p></p>').p
309 | 
310 |         # Simulate a tag obtained from a source file.
311 |         tag.sourceline = 10
312 |         tag.sourcepos = 33
313 |         
314 |         copied = tag.__copy__()
315 | 
316 |         # The TreeBuilder object is no longer availble, but information
317 |         # obtained from it gets copied over to the new Tag object.
318 |         assert tag.sourceline == copied.sourceline
319 |         assert tag.sourcepos == copied.sourcepos
320 |         assert tag.can_be_empty_element == copied.can_be_empty_element
321 |         assert tag.cdata_list_attributes == copied.cdata_list_attributes
322 |         assert tag.preserve_whitespace_tags == copied.preserve_whitespace_tags
323 |         assert tag.interesting_string_types == copied.interesting_string_types
324 |         
325 |     def test_unicode_pickle(self):
326 |         # A tree containing Unicode characters can be pickled.
327 |         html = "<b>\N{SNOWMAN}</b>"
328 |         soup = self.soup(html)
329 |         dumped = pickle.dumps(soup, pickle.HIGHEST_PROTOCOL)
330 |         loaded = pickle.loads(dumped)
331 |         assert loaded.decode() == soup.decode()
332 | 
333 |     def test_copy_navigablestring_is_not_attached_to_tree(self):
334 |         html = "<b>Foo<a></a></b><b>Bar</b>"
335 |         soup = self.soup(html)
336 |         s1 = soup.find(string="Foo")
337 |         s2 = copy.copy(s1)
338 |         assert s1 == s2
339 |         assert None == s2.parent
340 |         assert None == s2.next_element
341 |         assert None != s1.next_sibling
342 |         assert None == s2.next_sibling
343 |         assert None == s2.previous_element
344 | 
345 |     def test_copy_navigablestring_subclass_has_same_type(self):
346 |         html = "<b><!--Foo--></b>"
347 |         soup = self.soup(html)
348 |         s1 = soup.string
349 |         s2 = copy.copy(s1)
350 |         assert s1 == s2
351 |         assert isinstance(s2, Comment)
352 | 
353 |     def test_copy_entire_soup(self):
354 |         html = "<div><b>Foo<a></a></b><b>Bar</b></div>end"
355 |         soup = self.soup(html)
356 |         soup_copy = copy.copy(soup)
357 |         assert soup == soup_copy
358 | 
359 |     def test_copy_tag_copies_contents(self):
360 |         html = "<div><b>Foo<a></a></b><b>Bar</b></div>end"
361 |         soup = self.soup(html)
362 |         div = soup.div
363 |         div_copy = copy.copy(div)
364 | 
365 |         # The two tags look the same, and evaluate to equal.
366 |         assert str(div) == str(div_copy)
367 |         assert div == div_copy
368 | 
369 |         # But they're not the same object.
370 |         assert div is not div_copy
371 | 
372 |         # And they don't have the same relation to the parse tree. The
373 |         # copy is not associated with a parse tree at all.
374 |         assert None == div_copy.parent
375 |         assert None == div_copy.previous_element
376 |         assert None == div_copy.find(string='Bar').next_element
377 |         assert None != div.find(string='Bar').next_element
378 | 
379 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/rich/live.py:
--------------------------------------------------------------------------------

```python
  1 | import sys
  2 | from threading import Event, RLock, Thread
  3 | from types import TracebackType
  4 | from typing import IO, Any, Callable, List, Optional, TextIO, Type, cast
  5 | 
  6 | from . import get_console
  7 | from .console import Console, ConsoleRenderable, RenderableType, RenderHook
  8 | from .control import Control
  9 | from .file_proxy import FileProxy
 10 | from .jupyter import JupyterMixin
 11 | from .live_render import LiveRender, VerticalOverflowMethod
 12 | from .screen import Screen
 13 | from .text import Text
 14 | 
 15 | 
 16 | class _RefreshThread(Thread):
 17 |     """A thread that calls refresh() at regular intervals."""
 18 | 
 19 |     def __init__(self, live: "Live", refresh_per_second: float) -> None:
 20 |         self.live = live
 21 |         self.refresh_per_second = refresh_per_second
 22 |         self.done = Event()
 23 |         super().__init__(daemon=True)
 24 | 
 25 |     def stop(self) -> None:
 26 |         self.done.set()
 27 | 
 28 |     def run(self) -> None:
 29 |         while not self.done.wait(1 / self.refresh_per_second):
 30 |             with self.live._lock:
 31 |                 if not self.done.is_set():
 32 |                     self.live.refresh()
 33 | 
 34 | 
 35 | class Live(JupyterMixin, RenderHook):
 36 |     """Renders an auto-updating live display of any given renderable.
 37 | 
 38 |     Args:
 39 |         renderable (RenderableType, optional): The renderable to live display. Defaults to displaying nothing.
 40 |         console (Console, optional): Optional Console instance. Default will an internal Console instance writing to stdout.
 41 |         screen (bool, optional): Enable alternate screen mode. Defaults to False.
 42 |         auto_refresh (bool, optional): Enable auto refresh. If disabled, you will need to call `refresh()` or `update()` with refresh flag. Defaults to True
 43 |         refresh_per_second (float, optional): Number of times per second to refresh the live display. Defaults to 4.
 44 |         transient (bool, optional): Clear the renderable on exit (has no effect when screen=True). Defaults to False.
 45 |         redirect_stdout (bool, optional): Enable redirection of stdout, so ``print`` may be used. Defaults to True.
 46 |         redirect_stderr (bool, optional): Enable redirection of stderr. Defaults to True.
 47 |         vertical_overflow (VerticalOverflowMethod, optional): How to handle renderable when it is too tall for the console. Defaults to "ellipsis".
 48 |         get_renderable (Callable[[], RenderableType], optional): Optional callable to get renderable. Defaults to None.
 49 |     """
 50 | 
 51 |     def __init__(
 52 |         self,
 53 |         renderable: Optional[RenderableType] = None,
 54 |         *,
 55 |         console: Optional[Console] = None,
 56 |         screen: bool = False,
 57 |         auto_refresh: bool = True,
 58 |         refresh_per_second: float = 4,
 59 |         transient: bool = False,
 60 |         redirect_stdout: bool = True,
 61 |         redirect_stderr: bool = True,
 62 |         vertical_overflow: VerticalOverflowMethod = "ellipsis",
 63 |         get_renderable: Optional[Callable[[], RenderableType]] = None,
 64 |     ) -> None:
 65 |         assert refresh_per_second > 0, "refresh_per_second must be > 0"
 66 |         self._renderable = renderable
 67 |         self.console = console if console is not None else get_console()
 68 |         self._screen = screen
 69 |         self._alt_screen = False
 70 | 
 71 |         self._redirect_stdout = redirect_stdout
 72 |         self._redirect_stderr = redirect_stderr
 73 |         self._restore_stdout: Optional[IO[str]] = None
 74 |         self._restore_stderr: Optional[IO[str]] = None
 75 | 
 76 |         self._lock = RLock()
 77 |         self.ipy_widget: Optional[Any] = None
 78 |         self.auto_refresh = auto_refresh
 79 |         self._started: bool = False
 80 |         self.transient = True if screen else transient
 81 | 
 82 |         self._refresh_thread: Optional[_RefreshThread] = None
 83 |         self.refresh_per_second = refresh_per_second
 84 | 
 85 |         self.vertical_overflow = vertical_overflow
 86 |         self._get_renderable = get_renderable
 87 |         self._live_render = LiveRender(
 88 |             self.get_renderable(), vertical_overflow=vertical_overflow
 89 |         )
 90 | 
 91 |     @property
 92 |     def is_started(self) -> bool:
 93 |         """Check if live display has been started."""
 94 |         return self._started
 95 | 
 96 |     def get_renderable(self) -> RenderableType:
 97 |         renderable = (
 98 |             self._get_renderable()
 99 |             if self._get_renderable is not None
100 |             else self._renderable
101 |         )
102 |         return renderable or ""
103 | 
104 |     def start(self, refresh: bool = False) -> None:
105 |         """Start live rendering display.
106 | 
107 |         Args:
108 |             refresh (bool, optional): Also refresh. Defaults to False.
109 |         """
110 |         with self._lock:
111 |             if self._started:
112 |                 return
113 |             self.console.set_live(self)
114 |             self._started = True
115 |             if self._screen:
116 |                 self._alt_screen = self.console.set_alt_screen(True)
117 |             self.console.show_cursor(False)
118 |             self._enable_redirect_io()
119 |             self.console.push_render_hook(self)
120 |             if refresh:
121 |                 try:
122 |                     self.refresh()
123 |                 except Exception:
124 |                     # If refresh fails, we want to stop the redirection of sys.stderr,
125 |                     # so the error stacktrace is properly displayed in the terminal.
126 |                     # (or, if the code that calls Rich captures the exception and wants to display something,
127 |                     # let this be displayed in the terminal).
128 |                     self.stop()
129 |                     raise
130 |             if self.auto_refresh:
131 |                 self._refresh_thread = _RefreshThread(self, self.refresh_per_second)
132 |                 self._refresh_thread.start()
133 | 
134 |     def stop(self) -> None:
135 |         """Stop live rendering display."""
136 |         with self._lock:
137 |             if not self._started:
138 |                 return
139 |             self.console.clear_live()
140 |             self._started = False
141 | 
142 |             if self.auto_refresh and self._refresh_thread is not None:
143 |                 self._refresh_thread.stop()
144 |                 self._refresh_thread = None
145 |             # allow it to fully render on the last even if overflow
146 |             self.vertical_overflow = "visible"
147 |             with self.console:
148 |                 try:
149 |                     if not self._alt_screen and not self.console.is_jupyter:
150 |                         self.refresh()
151 |                 finally:
152 |                     self._disable_redirect_io()
153 |                     self.console.pop_render_hook()
154 |                     if not self._alt_screen and self.console.is_terminal:
155 |                         self.console.line()
156 |                     self.console.show_cursor(True)
157 |                     if self._alt_screen:
158 |                         self.console.set_alt_screen(False)
159 | 
160 |                     if self.transient and not self._alt_screen:
161 |                         self.console.control(self._live_render.restore_cursor())
162 |                     if self.ipy_widget is not None and self.transient:
163 |                         self.ipy_widget.close()  # pragma: no cover
164 | 
165 |     def __enter__(self) -> "Live":
166 |         self.start(refresh=self._renderable is not None)
167 |         return self
168 | 
169 |     def __exit__(
170 |         self,
171 |         exc_type: Optional[Type[BaseException]],
172 |         exc_val: Optional[BaseException],
173 |         exc_tb: Optional[TracebackType],
174 |     ) -> None:
175 |         self.stop()
176 | 
177 |     def _enable_redirect_io(self) -> None:
178 |         """Enable redirecting of stdout / stderr."""
179 |         if self.console.is_terminal or self.console.is_jupyter:
180 |             if self._redirect_stdout and not isinstance(sys.stdout, FileProxy):
181 |                 self._restore_stdout = sys.stdout
182 |                 sys.stdout = cast("TextIO", FileProxy(self.console, sys.stdout))
183 |             if self._redirect_stderr and not isinstance(sys.stderr, FileProxy):
184 |                 self._restore_stderr = sys.stderr
185 |                 sys.stderr = cast("TextIO", FileProxy(self.console, sys.stderr))
186 | 
187 |     def _disable_redirect_io(self) -> None:
188 |         """Disable redirecting of stdout / stderr."""
189 |         if self._restore_stdout:
190 |             sys.stdout = cast("TextIO", self._restore_stdout)
191 |             self._restore_stdout = None
192 |         if self._restore_stderr:
193 |             sys.stderr = cast("TextIO", self._restore_stderr)
194 |             self._restore_stderr = None
195 | 
196 |     @property
197 |     def renderable(self) -> RenderableType:
198 |         """Get the renderable that is being displayed
199 | 
200 |         Returns:
201 |             RenderableType: Displayed renderable.
202 |         """
203 |         renderable = self.get_renderable()
204 |         return Screen(renderable) if self._alt_screen else renderable
205 | 
206 |     def update(self, renderable: RenderableType, *, refresh: bool = False) -> None:
207 |         """Update the renderable that is being displayed
208 | 
209 |         Args:
210 |             renderable (RenderableType): New renderable to use.
211 |             refresh (bool, optional): Refresh the display. Defaults to False.
212 |         """
213 |         if isinstance(renderable, str):
214 |             renderable = self.console.render_str(renderable)
215 |         with self._lock:
216 |             self._renderable = renderable
217 |             if refresh:
218 |                 self.refresh()
219 | 
220 |     def refresh(self) -> None:
221 |         """Update the display of the Live Render."""
222 |         with self._lock:
223 |             self._live_render.set_renderable(self.renderable)
224 |             if self.console.is_jupyter:  # pragma: no cover
225 |                 try:
226 |                     from IPython.display import display
227 |                     from ipywidgets import Output
228 |                 except ImportError:
229 |                     import warnings
230 | 
231 |                     warnings.warn('install "ipywidgets" for Jupyter support')
232 |                 else:
233 |                     if self.ipy_widget is None:
234 |                         self.ipy_widget = Output()
235 |                         display(self.ipy_widget)
236 | 
237 |                     with self.ipy_widget:
238 |                         self.ipy_widget.clear_output(wait=True)
239 |                         self.console.print(self._live_render.renderable)
240 |             elif self.console.is_terminal and not self.console.is_dumb_terminal:
241 |                 with self.console:
242 |                     self.console.print(Control())
243 |             elif (
244 |                 not self._started and not self.transient
245 |             ):  # if it is finished allow files or dumb-terminals to see final result
246 |                 with self.console:
247 |                     self.console.print(Control())
248 | 
249 |     def process_renderables(
250 |         self, renderables: List[ConsoleRenderable]
251 |     ) -> List[ConsoleRenderable]:
252 |         """Process renderables to restore cursor and display progress."""
253 |         self._live_render.vertical_overflow = self.vertical_overflow
254 |         if self.console.is_interactive:
255 |             # lock needs acquiring as user can modify live_render renderable at any time unlike in Progress.
256 |             with self._lock:
257 |                 reset = (
258 |                     Control.home()
259 |                     if self._alt_screen
260 |                     else self._live_render.position_cursor()
261 |                 )
262 |                 renderables = [reset, *renderables, self._live_render]
263 |         elif (
264 |             not self._started and not self.transient
265 |         ):  # if it is finished render the final output for files or dumb_terminals
266 |             renderables = [*renderables, self._live_render]
267 | 
268 |         return renderables
269 | 
270 | 
271 | if __name__ == "__main__":  # pragma: no cover
272 |     import random
273 |     import time
274 |     from itertools import cycle
275 |     from typing import Dict, List, Tuple
276 | 
277 |     from .align import Align
278 |     from .console import Console
279 |     from .live import Live as Live
280 |     from .panel import Panel
281 |     from .rule import Rule
282 |     from .syntax import Syntax
283 |     from .table import Table
284 | 
285 |     console = Console()
286 | 
287 |     syntax = Syntax(
288 |         '''def loop_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:
289 |     """Iterate and generate a tuple with a flag for last value."""
290 |     iter_values = iter(values)
291 |     try:
292 |         previous_value = next(iter_values)
293 |     except StopIteration:
294 |         return
295 |     for value in iter_values:
296 |         yield False, previous_value
297 |         previous_value = value
298 |     yield True, previous_value''',
299 |         "python",
300 |         line_numbers=True,
301 |     )
302 | 
303 |     table = Table("foo", "bar", "baz")
304 |     table.add_row("1", "2", "3")
305 | 
306 |     progress_renderables = [
307 |         "You can make the terminal shorter and taller to see the live table hide"
308 |         "Text may be printed while the progress bars are rendering.",
309 |         Panel("In fact, [i]any[/i] renderable will work"),
310 |         "Such as [magenta]tables[/]...",
311 |         table,
312 |         "Pretty printed structures...",
313 |         {"type": "example", "text": "Pretty printed"},
314 |         "Syntax...",
315 |         syntax,
316 |         Rule("Give it a try!"),
317 |     ]
318 | 
319 |     examples = cycle(progress_renderables)
320 | 
321 |     exchanges = [
322 |         "SGD",
323 |         "MYR",
324 |         "EUR",
325 |         "USD",
326 |         "AUD",
327 |         "JPY",
328 |         "CNH",
329 |         "HKD",
330 |         "CAD",
331 |         "INR",
332 |         "DKK",
333 |         "GBP",
334 |         "RUB",
335 |         "NZD",
336 |         "MXN",
337 |         "IDR",
338 |         "TWD",
339 |         "THB",
340 |         "VND",
341 |     ]
342 |     with Live(console=console) as live_table:
343 |         exchange_rate_dict: Dict[Tuple[str, str], float] = {}
344 | 
345 |         for index in range(100):
346 |             select_exchange = exchanges[index % len(exchanges)]
347 | 
348 |             for exchange in exchanges:
349 |                 if exchange == select_exchange:
350 |                     continue
351 |                 time.sleep(0.4)
352 |                 if random.randint(0, 10) < 1:
353 |                     console.log(next(examples))
354 |                 exchange_rate_dict[(select_exchange, exchange)] = 200 / (
355 |                     (random.random() * 320) + 1
356 |                 )
357 |                 if len(exchange_rate_dict) > len(exchanges) - 1:
358 |                     exchange_rate_dict.pop(list(exchange_rate_dict.keys())[0])
359 |                 table = Table(title="Exchange Rates")
360 | 
361 |                 table.add_column("Source Currency")
362 |                 table.add_column("Destination Currency")
363 |                 table.add_column("Exchange Rate")
364 | 
365 |                 for (source, dest), exchange_rate in exchange_rate_dict.items():
366 |                     table.add_row(
367 |                         source,
368 |                         dest,
369 |                         Text(
370 |                             f"{exchange_rate:.4f}",
371 |                             style="red" if exchange_rate < 1.0 else "green",
372 |                         ),
373 |                     )
374 | 
375 |                 live_table.update(Align.center(table))
376 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/url.py:
--------------------------------------------------------------------------------

```python
  1 | from __future__ import absolute_import
  2 | 
  3 | import re
  4 | from collections import namedtuple
  5 | 
  6 | from ..exceptions import LocationParseError
  7 | from ..packages import six
  8 | 
  9 | url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"]
 10 | 
 11 | # We only want to normalize urls with an HTTP(S) scheme.
 12 | # urllib3 infers URLs without a scheme (None) to be http.
 13 | NORMALIZABLE_SCHEMES = ("http", "https", None)
 14 | 
 15 | # Almost all of these patterns were derived from the
 16 | # 'rfc3986' module: https://github.com/python-hyper/rfc3986
 17 | PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}")
 18 | SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)")
 19 | URI_RE = re.compile(
 20 |     r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?"
 21 |     r"(?://([^\\/?#]*))?"
 22 |     r"([^?#]*)"
 23 |     r"(?:\?([^#]*))?"
 24 |     r"(?:#(.*))?$",
 25 |     re.UNICODE | re.DOTALL,
 26 | )
 27 | 
 28 | IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}"
 29 | HEX_PAT = "[0-9A-Fa-f]{1,4}"
 30 | LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT)
 31 | _subs = {"hex": HEX_PAT, "ls32": LS32_PAT}
 32 | _variations = [
 33 |     #                            6( h16 ":" ) ls32
 34 |     "(?:%(hex)s:){6}%(ls32)s",
 35 |     #                       "::" 5( h16 ":" ) ls32
 36 |     "::(?:%(hex)s:){5}%(ls32)s",
 37 |     # [               h16 ] "::" 4( h16 ":" ) ls32
 38 |     "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s",
 39 |     # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
 40 |     "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s",
 41 |     # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
 42 |     "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s",
 43 |     # [ *3( h16 ":" ) h16 ] "::"    h16 ":"   ls32
 44 |     "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s",
 45 |     # [ *4( h16 ":" ) h16 ] "::"              ls32
 46 |     "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s",
 47 |     # [ *5( h16 ":" ) h16 ] "::"              h16
 48 |     "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s",
 49 |     # [ *6( h16 ":" ) h16 ] "::"
 50 |     "(?:(?:%(hex)s:){0,6}%(hex)s)?::",
 51 | ]
 52 | 
 53 | UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._\-~"
 54 | IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
 55 | ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
 56 | IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]"
 57 | REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
 58 | TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
 59 | 
 60 | IPV4_RE = re.compile("^" + IPV4_PAT + "$")
 61 | IPV6_RE = re.compile("^" + IPV6_PAT + "$")
 62 | IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$")
 63 | BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$")
 64 | ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$")
 65 | 
 66 | _HOST_PORT_PAT = ("^(%s|%s|%s)(?::0*?(|0|[1-9][0-9]{0,4}))?$") % (
 67 |     REG_NAME_PAT,
 68 |     IPV4_PAT,
 69 |     IPV6_ADDRZ_PAT,
 70 | )
 71 | _HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL)
 72 | 
 73 | UNRESERVED_CHARS = set(
 74 |     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~"
 75 | )
 76 | SUB_DELIM_CHARS = set("!$&'()*+,;=")
 77 | USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"}
 78 | PATH_CHARS = USERINFO_CHARS | {"@", "/"}
 79 | QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"}
 80 | 
 81 | 
 82 | class Url(namedtuple("Url", url_attrs)):
 83 |     """
 84 |     Data structure for representing an HTTP URL. Used as a return value for
 85 |     :func:`parse_url`. Both the scheme and host are normalized as they are
 86 |     both case-insensitive according to RFC 3986.
 87 |     """
 88 | 
 89 |     __slots__ = ()
 90 | 
 91 |     def __new__(
 92 |         cls,
 93 |         scheme=None,
 94 |         auth=None,
 95 |         host=None,
 96 |         port=None,
 97 |         path=None,
 98 |         query=None,
 99 |         fragment=None,
100 |     ):
101 |         if path and not path.startswith("/"):
102 |             path = "/" + path
103 |         if scheme is not None:
104 |             scheme = scheme.lower()
105 |         return super(Url, cls).__new__(
106 |             cls, scheme, auth, host, port, path, query, fragment
107 |         )
108 | 
109 |     @property
110 |     def hostname(self):
111 |         """For backwards-compatibility with urlparse. We're nice like that."""
112 |         return self.host
113 | 
114 |     @property
115 |     def request_uri(self):
116 |         """Absolute path including the query string."""
117 |         uri = self.path or "/"
118 | 
119 |         if self.query is not None:
120 |             uri += "?" + self.query
121 | 
122 |         return uri
123 | 
124 |     @property
125 |     def netloc(self):
126 |         """Network location including host and port"""
127 |         if self.port:
128 |             return "%s:%d" % (self.host, self.port)
129 |         return self.host
130 | 
131 |     @property
132 |     def url(self):
133 |         """
134 |         Convert self into a url
135 | 
136 |         This function should more or less round-trip with :func:`.parse_url`. The
137 |         returned url may not be exactly the same as the url inputted to
138 |         :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
139 |         with a blank port will have : removed).
140 | 
141 |         Example: ::
142 | 
143 |             >>> U = parse_url('http://google.com/mail/')
144 |             >>> U.url
145 |             'http://google.com/mail/'
146 |             >>> Url('http', 'username:password', 'host.com', 80,
147 |             ... '/path', 'query', 'fragment').url
148 |             'http://username:[email protected]:80/path?query#fragment'
149 |         """
150 |         scheme, auth, host, port, path, query, fragment = self
151 |         url = u""
152 | 
153 |         # We use "is not None" we want things to happen with empty strings (or 0 port)
154 |         if scheme is not None:
155 |             url += scheme + u"://"
156 |         if auth is not None:
157 |             url += auth + u"@"
158 |         if host is not None:
159 |             url += host
160 |         if port is not None:
161 |             url += u":" + str(port)
162 |         if path is not None:
163 |             url += path
164 |         if query is not None:
165 |             url += u"?" + query
166 |         if fragment is not None:
167 |             url += u"#" + fragment
168 | 
169 |         return url
170 | 
171 |     def __str__(self):
172 |         return self.url
173 | 
174 | 
175 | def split_first(s, delims):
176 |     """
177 |     .. deprecated:: 1.25
178 | 
179 |     Given a string and an iterable of delimiters, split on the first found
180 |     delimiter. Return two split parts and the matched delimiter.
181 | 
182 |     If not found, then the first part is the full input string.
183 | 
184 |     Example::
185 | 
186 |         >>> split_first('foo/bar?baz', '?/=')
187 |         ('foo', 'bar?baz', '/')
188 |         >>> split_first('foo/bar?baz', '123')
189 |         ('foo/bar?baz', '', None)
190 | 
191 |     Scales linearly with number of delims. Not ideal for large number of delims.
192 |     """
193 |     min_idx = None
194 |     min_delim = None
195 |     for d in delims:
196 |         idx = s.find(d)
197 |         if idx < 0:
198 |             continue
199 | 
200 |         if min_idx is None or idx < min_idx:
201 |             min_idx = idx
202 |             min_delim = d
203 | 
204 |     if min_idx is None or min_idx < 0:
205 |         return s, "", None
206 | 
207 |     return s[:min_idx], s[min_idx + 1 :], min_delim
208 | 
209 | 
210 | def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"):
211 |     """Percent-encodes a URI component without reapplying
212 |     onto an already percent-encoded component.
213 |     """
214 |     if component is None:
215 |         return component
216 | 
217 |     component = six.ensure_text(component)
218 | 
219 |     # Normalize existing percent-encoded bytes.
220 |     # Try to see if the component we're encoding is already percent-encoded
221 |     # so we can skip all '%' characters but still encode all others.
222 |     component, percent_encodings = PERCENT_RE.subn(
223 |         lambda match: match.group(0).upper(), component
224 |     )
225 | 
226 |     uri_bytes = component.encode("utf-8", "surrogatepass")
227 |     is_percent_encoded = percent_encodings == uri_bytes.count(b"%")
228 |     encoded_component = bytearray()
229 | 
230 |     for i in range(0, len(uri_bytes)):
231 |         # Will return a single character bytestring on both Python 2 & 3
232 |         byte = uri_bytes[i : i + 1]
233 |         byte_ord = ord(byte)
234 |         if (is_percent_encoded and byte == b"%") or (
235 |             byte_ord < 128 and byte.decode() in allowed_chars
236 |         ):
237 |             encoded_component += byte
238 |             continue
239 |         encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper()))
240 | 
241 |     return encoded_component.decode(encoding)
242 | 
243 | 
244 | def _remove_path_dot_segments(path):
245 |     # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
246 |     segments = path.split("/")  # Turn the path into a list of segments
247 |     output = []  # Initialize the variable to use to store output
248 | 
249 |     for segment in segments:
250 |         # '.' is the current directory, so ignore it, it is superfluous
251 |         if segment == ".":
252 |             continue
253 |         # Anything other than '..', should be appended to the output
254 |         elif segment != "..":
255 |             output.append(segment)
256 |         # In this case segment == '..', if we can, we should pop the last
257 |         # element
258 |         elif output:
259 |             output.pop()
260 | 
261 |     # If the path starts with '/' and the output is empty or the first string
262 |     # is non-empty
263 |     if path.startswith("/") and (not output or output[0]):
264 |         output.insert(0, "")
265 | 
266 |     # If the path starts with '/.' or '/..' ensure we add one more empty
267 |     # string to add a trailing '/'
268 |     if path.endswith(("/.", "/..")):
269 |         output.append("")
270 | 
271 |     return "/".join(output)
272 | 
273 | 
274 | def _normalize_host(host, scheme):
275 |     if host:
276 |         if isinstance(host, six.binary_type):
277 |             host = six.ensure_str(host)
278 | 
279 |         if scheme in NORMALIZABLE_SCHEMES:
280 |             is_ipv6 = IPV6_ADDRZ_RE.match(host)
281 |             if is_ipv6:
282 |                 # IPv6 hosts of the form 'a::b%zone' are encoded in a URL as
283 |                 # such per RFC 6874: 'a::b%25zone'. Unquote the ZoneID
284 |                 # separator as necessary to return a valid RFC 4007 scoped IP.
285 |                 match = ZONE_ID_RE.search(host)
286 |                 if match:
287 |                     start, end = match.span(1)
288 |                     zone_id = host[start:end]
289 | 
290 |                     if zone_id.startswith("%25") and zone_id != "%25":
291 |                         zone_id = zone_id[3:]
292 |                     else:
293 |                         zone_id = zone_id[1:]
294 |                     zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS)
295 |                     return host[:start].lower() + zone_id + host[end:]
296 |                 else:
297 |                     return host.lower()
298 |             elif not IPV4_RE.match(host):
299 |                 return six.ensure_str(
300 |                     b".".join([_idna_encode(label) for label in host.split(".")])
301 |                 )
302 |     return host
303 | 
304 | 
305 | def _idna_encode(name):
306 |     if name and any(ord(x) >= 128 for x in name):
307 |         try:
308 |             from pip._vendor import idna
309 |         except ImportError:
310 |             six.raise_from(
311 |                 LocationParseError("Unable to parse URL without the 'idna' module"),
312 |                 None,
313 |             )
314 |         try:
315 |             return idna.encode(name.lower(), strict=True, std3_rules=True)
316 |         except idna.IDNAError:
317 |             six.raise_from(
318 |                 LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None
319 |             )
320 |     return name.lower().encode("ascii")
321 | 
322 | 
323 | def _encode_target(target):
324 |     """Percent-encodes a request target so that there are no invalid characters"""
325 |     path, query = TARGET_RE.match(target).groups()
326 |     target = _encode_invalid_chars(path, PATH_CHARS)
327 |     query = _encode_invalid_chars(query, QUERY_CHARS)
328 |     if query is not None:
329 |         target += "?" + query
330 |     return target
331 | 
332 | 
333 | def parse_url(url):
334 |     """
335 |     Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
336 |     performed to parse incomplete urls. Fields not provided will be None.
337 |     This parser is RFC 3986 and RFC 6874 compliant.
338 | 
339 |     The parser logic and helper functions are based heavily on
340 |     work done in the ``rfc3986`` module.
341 | 
342 |     :param str url: URL to parse into a :class:`.Url` namedtuple.
343 | 
344 |     Partly backwards-compatible with :mod:`urlparse`.
345 | 
346 |     Example::
347 | 
348 |         >>> parse_url('http://google.com/mail/')
349 |         Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
350 |         >>> parse_url('google.com:80')
351 |         Url(scheme=None, host='google.com', port=80, path=None, ...)
352 |         >>> parse_url('/foo?bar')
353 |         Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
354 |     """
355 |     if not url:
356 |         # Empty
357 |         return Url()
358 | 
359 |     source_url = url
360 |     if not SCHEME_RE.search(url):
361 |         url = "//" + url
362 | 
363 |     try:
364 |         scheme, authority, path, query, fragment = URI_RE.match(url).groups()
365 |         normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES
366 | 
367 |         if scheme:
368 |             scheme = scheme.lower()
369 | 
370 |         if authority:
371 |             auth, _, host_port = authority.rpartition("@")
372 |             auth = auth or None
373 |             host, port = _HOST_PORT_RE.match(host_port).groups()
374 |             if auth and normalize_uri:
375 |                 auth = _encode_invalid_chars(auth, USERINFO_CHARS)
376 |             if port == "":
377 |                 port = None
378 |         else:
379 |             auth, host, port = None, None, None
380 | 
381 |         if port is not None:
382 |             port = int(port)
383 |             if not (0 <= port <= 65535):
384 |                 raise LocationParseError(url)
385 | 
386 |         host = _normalize_host(host, scheme)
387 | 
388 |         if normalize_uri and path:
389 |             path = _remove_path_dot_segments(path)
390 |             path = _encode_invalid_chars(path, PATH_CHARS)
391 |         if normalize_uri and query:
392 |             query = _encode_invalid_chars(query, QUERY_CHARS)
393 |         if normalize_uri and fragment:
394 |             fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS)
395 | 
396 |     except (ValueError, AttributeError):
397 |         return six.raise_from(LocationParseError(source_url), None)
398 | 
399 |     # For the sake of backwards compatibility we put empty
400 |     # string values for path if there are any defined values
401 |     # beyond the path in the URL.
402 |     # TODO: Remove this when we break backwards compatibility.
403 |     if not path:
404 |         if query is not None or fragment is not None:
405 |             path = ""
406 |         else:
407 |             path = None
408 | 
409 |     # Ensure that each part of the URL is a `str` for
410 |     # backwards compatibility.
411 |     if isinstance(url, six.text_type):
412 |         ensure_func = six.ensure_text
413 |     else:
414 |         ensure_func = six.ensure_str
415 | 
416 |     def ensure_type(x):
417 |         return x if x is None else ensure_func(x)
418 | 
419 |     return Url(
420 |         scheme=ensure_type(scheme),
421 |         auth=ensure_type(auth),
422 |         host=ensure_type(host),
423 |         port=port,
424 |         path=ensure_type(path),
425 |         query=ensure_type(query),
426 |         fragment=ensure_type(fragment),
427 |     )
428 | 
429 | 
430 | def get_host(url):
431 |     """
432 |     Deprecated. Use :func:`parse_url` instead.
433 |     """
434 |     p = parse_url(url)
435 |     return p.scheme or "http", p.hostname, p.port
436 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/werkzeug/middleware/lint.py:
--------------------------------------------------------------------------------

```python
  1 | """
  2 | WSGI Protocol Linter
  3 | ====================
  4 | 
  5 | This module provides a middleware that performs sanity checks on the
  6 | behavior of the WSGI server and application. It checks that the
  7 | :pep:`3333` WSGI spec is properly implemented. It also warns on some
  8 | common HTTP errors such as non-empty responses for 304 status codes.
  9 | 
 10 | .. autoclass:: LintMiddleware
 11 | 
 12 | :copyright: 2007 Pallets
 13 | :license: BSD-3-Clause
 14 | """
 15 | 
 16 | from __future__ import annotations
 17 | 
 18 | import typing as t
 19 | from types import TracebackType
 20 | from urllib.parse import urlparse
 21 | from warnings import warn
 22 | 
 23 | from ..datastructures import Headers
 24 | from ..http import is_entity_header
 25 | from ..wsgi import FileWrapper
 26 | 
 27 | if t.TYPE_CHECKING:
 28 |     from _typeshed.wsgi import StartResponse
 29 |     from _typeshed.wsgi import WSGIApplication
 30 |     from _typeshed.wsgi import WSGIEnvironment
 31 | 
 32 | 
 33 | class WSGIWarning(Warning):
 34 |     """Warning class for WSGI warnings."""
 35 | 
 36 | 
 37 | class HTTPWarning(Warning):
 38 |     """Warning class for HTTP warnings."""
 39 | 
 40 | 
 41 | def check_type(context: str, obj: object, need: type = str) -> None:
 42 |     if type(obj) is not need:
 43 |         warn(
 44 |             f"{context!r} requires {need.__name__!r}, got {type(obj).__name__!r}.",
 45 |             WSGIWarning,
 46 |             stacklevel=3,
 47 |         )
 48 | 
 49 | 
 50 | class InputStream:
 51 |     def __init__(self, stream: t.IO[bytes]) -> None:
 52 |         self._stream = stream
 53 | 
 54 |     def read(self, *args: t.Any) -> bytes:
 55 |         if len(args) == 0:
 56 |             warn(
 57 |                 "WSGI does not guarantee an EOF marker on the input stream, thus making"
 58 |                 " calls to 'wsgi.input.read()' unsafe. Conforming servers may never"
 59 |                 " return from this call.",
 60 |                 WSGIWarning,
 61 |                 stacklevel=2,
 62 |             )
 63 |         elif len(args) != 1:
 64 |             warn(
 65 |                 "Too many parameters passed to 'wsgi.input.read()'.",
 66 |                 WSGIWarning,
 67 |                 stacklevel=2,
 68 |             )
 69 |         return self._stream.read(*args)
 70 | 
 71 |     def readline(self, *args: t.Any) -> bytes:
 72 |         if len(args) == 0:
 73 |             warn(
 74 |                 "Calls to 'wsgi.input.readline()' without arguments are unsafe. Use"
 75 |                 " 'wsgi.input.read()' instead.",
 76 |                 WSGIWarning,
 77 |                 stacklevel=2,
 78 |             )
 79 |         elif len(args) == 1:
 80 |             warn(
 81 |                 "'wsgi.input.readline()' was called with a size hint. WSGI does not"
 82 |                 " support this, although it's available on all major servers.",
 83 |                 WSGIWarning,
 84 |                 stacklevel=2,
 85 |             )
 86 |         else:
 87 |             raise TypeError("Too many arguments passed to 'wsgi.input.readline()'.")
 88 |         return self._stream.readline(*args)
 89 | 
 90 |     def __iter__(self) -> t.Iterator[bytes]:
 91 |         try:
 92 |             return iter(self._stream)
 93 |         except TypeError:
 94 |             warn("'wsgi.input' is not iterable.", WSGIWarning, stacklevel=2)
 95 |             return iter(())
 96 | 
 97 |     def close(self) -> None:
 98 |         warn("The application closed the input stream!", WSGIWarning, stacklevel=2)
 99 |         self._stream.close()
100 | 
101 | 
102 | class ErrorStream:
103 |     def __init__(self, stream: t.IO[str]) -> None:
104 |         self._stream = stream
105 | 
106 |     def write(self, s: str) -> None:
107 |         check_type("wsgi.error.write()", s, str)
108 |         self._stream.write(s)
109 | 
110 |     def flush(self) -> None:
111 |         self._stream.flush()
112 | 
113 |     def writelines(self, seq: t.Iterable[str]) -> None:
114 |         for line in seq:
115 |             self.write(line)
116 | 
117 |     def close(self) -> None:
118 |         warn("The application closed the error stream!", WSGIWarning, stacklevel=2)
119 |         self._stream.close()
120 | 
121 | 
122 | class GuardedWrite:
123 |     def __init__(self, write: t.Callable[[bytes], object], chunks: list[int]) -> None:
124 |         self._write = write
125 |         self._chunks = chunks
126 | 
127 |     def __call__(self, s: bytes) -> None:
128 |         check_type("write()", s, bytes)
129 |         self._write(s)
130 |         self._chunks.append(len(s))
131 | 
132 | 
133 | class GuardedIterator:
134 |     def __init__(
135 |         self,
136 |         iterator: t.Iterable[bytes],
137 |         headers_set: tuple[int, Headers],
138 |         chunks: list[int],
139 |     ) -> None:
140 |         self._iterator = iterator
141 |         self._next = iter(iterator).__next__
142 |         self.closed = False
143 |         self.headers_set = headers_set
144 |         self.chunks = chunks
145 | 
146 |     def __iter__(self) -> GuardedIterator:
147 |         return self
148 | 
149 |     def __next__(self) -> bytes:
150 |         if self.closed:
151 |             warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2)
152 | 
153 |         rv = self._next()
154 | 
155 |         if not self.headers_set:
156 |             warn(
157 |                 "The application returned before it started the response.",
158 |                 WSGIWarning,
159 |                 stacklevel=2,
160 |             )
161 | 
162 |         check_type("application iterator items", rv, bytes)
163 |         self.chunks.append(len(rv))
164 |         return rv
165 | 
166 |     def close(self) -> None:
167 |         self.closed = True
168 | 
169 |         if hasattr(self._iterator, "close"):
170 |             self._iterator.close()
171 | 
172 |         if self.headers_set:
173 |             status_code, headers = self.headers_set
174 |             bytes_sent = sum(self.chunks)
175 |             content_length = headers.get("content-length", type=int)
176 | 
177 |             if status_code == 304:
178 |                 for key, _value in headers:
179 |                     key = key.lower()
180 |                     if key not in ("expires", "content-location") and is_entity_header(
181 |                         key
182 |                     ):
183 |                         warn(
184 |                             f"Entity header {key!r} found in 304 response.",
185 |                             HTTPWarning,
186 |                             stacklevel=2,
187 |                         )
188 |                 if bytes_sent:
189 |                     warn(
190 |                         "304 responses must not have a body.",
191 |                         HTTPWarning,
192 |                         stacklevel=2,
193 |                     )
194 |             elif 100 <= status_code < 200 or status_code == 204:
195 |                 if content_length != 0:
196 |                     warn(
197 |                         f"{status_code} responses must have an empty content length.",
198 |                         HTTPWarning,
199 |                         stacklevel=2,
200 |                     )
201 |                 if bytes_sent:
202 |                     warn(
203 |                         f"{status_code} responses must not have a body.",
204 |                         HTTPWarning,
205 |                         stacklevel=2,
206 |                     )
207 |             elif content_length is not None and content_length != bytes_sent:
208 |                 warn(
209 |                     "Content-Length and the number of bytes sent to the"
210 |                     " client do not match.",
211 |                     WSGIWarning,
212 |                     stacklevel=2,
213 |                 )
214 | 
215 |     def __del__(self) -> None:
216 |         if not self.closed:
217 |             try:
218 |                 warn(
219 |                     "Iterator was garbage collected before it was closed.",
220 |                     WSGIWarning,
221 |                     stacklevel=2,
222 |                 )
223 |             except Exception:
224 |                 pass
225 | 
226 | 
227 | class LintMiddleware:
228 |     """Warns about common errors in the WSGI and HTTP behavior of the
229 |     server and wrapped application. Some of the issues it checks are:
230 | 
231 |     -   invalid status codes
232 |     -   non-bytes sent to the WSGI server
233 |     -   strings returned from the WSGI application
234 |     -   non-empty conditional responses
235 |     -   unquoted etags
236 |     -   relative URLs in the Location header
237 |     -   unsafe calls to wsgi.input
238 |     -   unclosed iterators
239 | 
240 |     Error information is emitted using the :mod:`warnings` module.
241 | 
242 |     :param app: The WSGI application to wrap.
243 | 
244 |     .. code-block:: python
245 | 
246 |         from werkzeug.middleware.lint import LintMiddleware
247 |         app = LintMiddleware(app)
248 |     """
249 | 
250 |     def __init__(self, app: WSGIApplication) -> None:
251 |         self.app = app
252 | 
253 |     def check_environ(self, environ: WSGIEnvironment) -> None:
254 |         if type(environ) is not dict:  # noqa: E721
255 |             warn(
256 |                 "WSGI environment is not a standard Python dict.",
257 |                 WSGIWarning,
258 |                 stacklevel=4,
259 |             )
260 |         for key in (
261 |             "REQUEST_METHOD",
262 |             "SERVER_NAME",
263 |             "SERVER_PORT",
264 |             "wsgi.version",
265 |             "wsgi.input",
266 |             "wsgi.errors",
267 |             "wsgi.multithread",
268 |             "wsgi.multiprocess",
269 |             "wsgi.run_once",
270 |         ):
271 |             if key not in environ:
272 |                 warn(
273 |                     f"Required environment key {key!r} not found",
274 |                     WSGIWarning,
275 |                     stacklevel=3,
276 |                 )
277 |         if environ["wsgi.version"] != (1, 0):
278 |             warn("Environ is not a WSGI 1.0 environ.", WSGIWarning, stacklevel=3)
279 | 
280 |         script_name = environ.get("SCRIPT_NAME", "")
281 |         path_info = environ.get("PATH_INFO", "")
282 | 
283 |         if script_name and script_name[0] != "/":
284 |             warn(
285 |                 f"'SCRIPT_NAME' does not start with a slash: {script_name!r}",
286 |                 WSGIWarning,
287 |                 stacklevel=3,
288 |             )
289 | 
290 |         if path_info and path_info[0] != "/":
291 |             warn(
292 |                 f"'PATH_INFO' does not start with a slash: {path_info!r}",
293 |                 WSGIWarning,
294 |                 stacklevel=3,
295 |             )
296 | 
297 |     def check_start_response(
298 |         self,
299 |         status: str,
300 |         headers: list[tuple[str, str]],
301 |         exc_info: None | (tuple[type[BaseException], BaseException, TracebackType]),
302 |     ) -> tuple[int, Headers]:
303 |         check_type("status", status, str)
304 |         status_code_str = status.split(None, 1)[0]
305 | 
306 |         if len(status_code_str) != 3 or not status_code_str.isdecimal():
307 |             warn("Status code must be three digits.", WSGIWarning, stacklevel=3)
308 | 
309 |         if len(status) < 4 or status[3] != " ":
310 |             warn(
311 |                 f"Invalid value for status {status!r}. Valid status strings are three"
312 |                 " digits, a space and a status explanation.",
313 |                 WSGIWarning,
314 |                 stacklevel=3,
315 |             )
316 | 
317 |         status_code = int(status_code_str)
318 | 
319 |         if status_code < 100:
320 |             warn("Status code < 100 detected.", WSGIWarning, stacklevel=3)
321 | 
322 |         if type(headers) is not list:  # noqa: E721
323 |             warn("Header list is not a list.", WSGIWarning, stacklevel=3)
324 | 
325 |         for item in headers:
326 |             if type(item) is not tuple or len(item) != 2:
327 |                 warn("Header items must be 2-item tuples.", WSGIWarning, stacklevel=3)
328 |             name, value = item
329 |             if type(name) is not str or type(value) is not str:  # noqa: E721
330 |                 warn(
331 |                     "Header keys and values must be strings.", WSGIWarning, stacklevel=3
332 |                 )
333 |             if name.lower() == "status":
334 |                 warn(
335 |                     "The status header is not supported due to"
336 |                     " conflicts with the CGI spec.",
337 |                     WSGIWarning,
338 |                     stacklevel=3,
339 |                 )
340 | 
341 |         if exc_info is not None and not isinstance(exc_info, tuple):
342 |             warn("Invalid value for exc_info.", WSGIWarning, stacklevel=3)
343 | 
344 |         headers_obj = Headers(headers)
345 |         self.check_headers(headers_obj)
346 | 
347 |         return status_code, headers_obj
348 | 
349 |     def check_headers(self, headers: Headers) -> None:
350 |         etag = headers.get("etag")
351 | 
352 |         if etag is not None:
353 |             if etag.startswith(("W/", "w/")):
354 |                 if etag.startswith("w/"):
355 |                     warn(
356 |                         "Weak etag indicator should be upper case.",
357 |                         HTTPWarning,
358 |                         stacklevel=4,
359 |                     )
360 | 
361 |                 etag = etag[2:]
362 | 
363 |             if not (etag[:1] == etag[-1:] == '"'):
364 |                 warn("Unquoted etag emitted.", HTTPWarning, stacklevel=4)
365 | 
366 |         location = headers.get("location")
367 | 
368 |         if location is not None:
369 |             if not urlparse(location).netloc:
370 |                 warn(
371 |                     "Absolute URLs required for location header.",
372 |                     HTTPWarning,
373 |                     stacklevel=4,
374 |                 )
375 | 
376 |     def check_iterator(self, app_iter: t.Iterable[bytes]) -> None:
377 |         if isinstance(app_iter, str):
378 |             warn(
379 |                 "The application returned a string. The response will send one"
380 |                 " character at a time to the client, which will kill performance."
381 |                 " Return a list or iterable instead.",
382 |                 WSGIWarning,
383 |                 stacklevel=3,
384 |             )
385 | 
386 |     def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Iterable[bytes]:
387 |         if len(args) != 2:
388 |             warn("A WSGI app takes two arguments.", WSGIWarning, stacklevel=2)
389 | 
390 |         if kwargs:
391 |             warn(
392 |                 "A WSGI app does not take keyword arguments.", WSGIWarning, stacklevel=2
393 |             )
394 | 
395 |         environ: WSGIEnvironment = args[0]
396 |         start_response: StartResponse = args[1]
397 | 
398 |         self.check_environ(environ)
399 |         environ["wsgi.input"] = InputStream(environ["wsgi.input"])
400 |         environ["wsgi.errors"] = ErrorStream(environ["wsgi.errors"])
401 | 
402 |         # Hook our own file wrapper in so that applications will always
403 |         # iterate to the end and we can check the content length.
404 |         environ["wsgi.file_wrapper"] = FileWrapper
405 | 
406 |         headers_set: list[t.Any] = []
407 |         chunks: list[int] = []
408 | 
409 |         def checking_start_response(
410 |             *args: t.Any, **kwargs: t.Any
411 |         ) -> t.Callable[[bytes], None]:
412 |             if len(args) not in {2, 3}:
413 |                 warn(
414 |                     f"Invalid number of arguments: {len(args)}, expected 2 or 3.",
415 |                     WSGIWarning,
416 |                     stacklevel=2,
417 |                 )
418 | 
419 |             if kwargs:
420 |                 warn(
421 |                     "'start_response' does not take keyword arguments.",
422 |                     WSGIWarning,
423 |                     stacklevel=2,
424 |                 )
425 | 
426 |             status: str = args[0]
427 |             headers: list[tuple[str, str]] = args[1]
428 |             exc_info: (
429 |                 None | (tuple[type[BaseException], BaseException, TracebackType])
430 |             ) = args[2] if len(args) == 3 else None
431 | 
432 |             headers_set[:] = self.check_start_response(status, headers, exc_info)
433 |             return GuardedWrite(start_response(status, headers, exc_info), chunks)
434 | 
435 |         app_iter = self.app(environ, t.cast("StartResponse", checking_start_response))
436 |         self.check_iterator(app_iter)
437 |         return GuardedIterator(
438 |             app_iter, t.cast(t.Tuple[int, Headers], headers_set), chunks
439 |         )
440 | 
```
Page 51/168FirstPrevNextLast