#
tokens: 49678/50000 3/808 files (page 69/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 69 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/charset_normalizer/md.py:
--------------------------------------------------------------------------------

```python
  1 | from functools import lru_cache
  2 | from logging import getLogger
  3 | from typing import List, Optional
  4 | 
  5 | from .constant import (
  6 |     COMMON_SAFE_ASCII_CHARACTERS,
  7 |     TRACE,
  8 |     UNICODE_SECONDARY_RANGE_KEYWORD,
  9 | )
 10 | from .utils import (
 11 |     is_accentuated,
 12 |     is_arabic,
 13 |     is_arabic_isolated_form,
 14 |     is_case_variable,
 15 |     is_cjk,
 16 |     is_emoticon,
 17 |     is_hangul,
 18 |     is_hiragana,
 19 |     is_katakana,
 20 |     is_latin,
 21 |     is_punctuation,
 22 |     is_separator,
 23 |     is_symbol,
 24 |     is_thai,
 25 |     is_unprintable,
 26 |     remove_accent,
 27 |     unicode_range,
 28 | )
 29 | 
 30 | 
 31 | class MessDetectorPlugin:
 32 |     """
 33 |     Base abstract class used for mess detection plugins.
 34 |     All detectors MUST extend and implement given methods.
 35 |     """
 36 | 
 37 |     def eligible(self, character: str) -> bool:
 38 |         """
 39 |         Determine if given character should be fed in.
 40 |         """
 41 |         raise NotImplementedError  # pragma: nocover
 42 | 
 43 |     def feed(self, character: str) -> None:
 44 |         """
 45 |         The main routine to be executed upon character.
 46 |         Insert the logic in witch the text would be considered chaotic.
 47 |         """
 48 |         raise NotImplementedError  # pragma: nocover
 49 | 
 50 |     def reset(self) -> None:  # pragma: no cover
 51 |         """
 52 |         Permit to reset the plugin to the initial state.
 53 |         """
 54 |         raise NotImplementedError
 55 | 
 56 |     @property
 57 |     def ratio(self) -> float:
 58 |         """
 59 |         Compute the chaos ratio based on what your feed() has seen.
 60 |         Must NOT be lower than 0.; No restriction gt 0.
 61 |         """
 62 |         raise NotImplementedError  # pragma: nocover
 63 | 
 64 | 
 65 | class TooManySymbolOrPunctuationPlugin(MessDetectorPlugin):
 66 |     def __init__(self) -> None:
 67 |         self._punctuation_count: int = 0
 68 |         self._symbol_count: int = 0
 69 |         self._character_count: int = 0
 70 | 
 71 |         self._last_printable_char: Optional[str] = None
 72 |         self._frenzy_symbol_in_word: bool = False
 73 | 
 74 |     def eligible(self, character: str) -> bool:
 75 |         return character.isprintable()
 76 | 
 77 |     def feed(self, character: str) -> None:
 78 |         self._character_count += 1
 79 | 
 80 |         if (
 81 |             character != self._last_printable_char
 82 |             and character not in COMMON_SAFE_ASCII_CHARACTERS
 83 |         ):
 84 |             if is_punctuation(character):
 85 |                 self._punctuation_count += 1
 86 |             elif (
 87 |                 character.isdigit() is False
 88 |                 and is_symbol(character)
 89 |                 and is_emoticon(character) is False
 90 |             ):
 91 |                 self._symbol_count += 2
 92 | 
 93 |         self._last_printable_char = character
 94 | 
 95 |     def reset(self) -> None:  # pragma: no cover
 96 |         self._punctuation_count = 0
 97 |         self._character_count = 0
 98 |         self._symbol_count = 0
 99 | 
100 |     @property
101 |     def ratio(self) -> float:
102 |         if self._character_count == 0:
103 |             return 0.0
104 | 
105 |         ratio_of_punctuation: float = (
106 |             self._punctuation_count + self._symbol_count
107 |         ) / self._character_count
108 | 
109 |         return ratio_of_punctuation if ratio_of_punctuation >= 0.3 else 0.0
110 | 
111 | 
112 | class TooManyAccentuatedPlugin(MessDetectorPlugin):
113 |     def __init__(self) -> None:
114 |         self._character_count: int = 0
115 |         self._accentuated_count: int = 0
116 | 
117 |     def eligible(self, character: str) -> bool:
118 |         return character.isalpha()
119 | 
120 |     def feed(self, character: str) -> None:
121 |         self._character_count += 1
122 | 
123 |         if is_accentuated(character):
124 |             self._accentuated_count += 1
125 | 
126 |     def reset(self) -> None:  # pragma: no cover
127 |         self._character_count = 0
128 |         self._accentuated_count = 0
129 | 
130 |     @property
131 |     def ratio(self) -> float:
132 |         if self._character_count < 8:
133 |             return 0.0
134 | 
135 |         ratio_of_accentuation: float = self._accentuated_count / self._character_count
136 |         return ratio_of_accentuation if ratio_of_accentuation >= 0.35 else 0.0
137 | 
138 | 
139 | class UnprintablePlugin(MessDetectorPlugin):
140 |     def __init__(self) -> None:
141 |         self._unprintable_count: int = 0
142 |         self._character_count: int = 0
143 | 
144 |     def eligible(self, character: str) -> bool:
145 |         return True
146 | 
147 |     def feed(self, character: str) -> None:
148 |         if is_unprintable(character):
149 |             self._unprintable_count += 1
150 |         self._character_count += 1
151 | 
152 |     def reset(self) -> None:  # pragma: no cover
153 |         self._unprintable_count = 0
154 | 
155 |     @property
156 |     def ratio(self) -> float:
157 |         if self._character_count == 0:
158 |             return 0.0
159 | 
160 |         return (self._unprintable_count * 8) / self._character_count
161 | 
162 | 
163 | class SuspiciousDuplicateAccentPlugin(MessDetectorPlugin):
164 |     def __init__(self) -> None:
165 |         self._successive_count: int = 0
166 |         self._character_count: int = 0
167 | 
168 |         self._last_latin_character: Optional[str] = None
169 | 
170 |     def eligible(self, character: str) -> bool:
171 |         return character.isalpha() and is_latin(character)
172 | 
173 |     def feed(self, character: str) -> None:
174 |         self._character_count += 1
175 |         if (
176 |             self._last_latin_character is not None
177 |             and is_accentuated(character)
178 |             and is_accentuated(self._last_latin_character)
179 |         ):
180 |             if character.isupper() and self._last_latin_character.isupper():
181 |                 self._successive_count += 1
182 |             # Worse if its the same char duplicated with different accent.
183 |             if remove_accent(character) == remove_accent(self._last_latin_character):
184 |                 self._successive_count += 1
185 |         self._last_latin_character = character
186 | 
187 |     def reset(self) -> None:  # pragma: no cover
188 |         self._successive_count = 0
189 |         self._character_count = 0
190 |         self._last_latin_character = None
191 | 
192 |     @property
193 |     def ratio(self) -> float:
194 |         if self._character_count == 0:
195 |             return 0.0
196 | 
197 |         return (self._successive_count * 2) / self._character_count
198 | 
199 | 
200 | class SuspiciousRange(MessDetectorPlugin):
201 |     def __init__(self) -> None:
202 |         self._suspicious_successive_range_count: int = 0
203 |         self._character_count: int = 0
204 |         self._last_printable_seen: Optional[str] = None
205 | 
206 |     def eligible(self, character: str) -> bool:
207 |         return character.isprintable()
208 | 
209 |     def feed(self, character: str) -> None:
210 |         self._character_count += 1
211 | 
212 |         if (
213 |             character.isspace()
214 |             or is_punctuation(character)
215 |             or character in COMMON_SAFE_ASCII_CHARACTERS
216 |         ):
217 |             self._last_printable_seen = None
218 |             return
219 | 
220 |         if self._last_printable_seen is None:
221 |             self._last_printable_seen = character
222 |             return
223 | 
224 |         unicode_range_a: Optional[str] = unicode_range(self._last_printable_seen)
225 |         unicode_range_b: Optional[str] = unicode_range(character)
226 | 
227 |         if is_suspiciously_successive_range(unicode_range_a, unicode_range_b):
228 |             self._suspicious_successive_range_count += 1
229 | 
230 |         self._last_printable_seen = character
231 | 
232 |     def reset(self) -> None:  # pragma: no cover
233 |         self._character_count = 0
234 |         self._suspicious_successive_range_count = 0
235 |         self._last_printable_seen = None
236 | 
237 |     @property
238 |     def ratio(self) -> float:
239 |         if self._character_count <= 13:
240 |             return 0.0
241 | 
242 |         ratio_of_suspicious_range_usage: float = (
243 |             self._suspicious_successive_range_count * 2
244 |         ) / self._character_count
245 | 
246 |         return ratio_of_suspicious_range_usage
247 | 
248 | 
249 | class SuperWeirdWordPlugin(MessDetectorPlugin):
250 |     def __init__(self) -> None:
251 |         self._word_count: int = 0
252 |         self._bad_word_count: int = 0
253 |         self._foreign_long_count: int = 0
254 | 
255 |         self._is_current_word_bad: bool = False
256 |         self._foreign_long_watch: bool = False
257 | 
258 |         self._character_count: int = 0
259 |         self._bad_character_count: int = 0
260 | 
261 |         self._buffer: str = ""
262 |         self._buffer_accent_count: int = 0
263 |         self._buffer_glyph_count: int = 0
264 | 
265 |     def eligible(self, character: str) -> bool:
266 |         return True
267 | 
268 |     def feed(self, character: str) -> None:
269 |         if character.isalpha():
270 |             self._buffer += character
271 |             if is_accentuated(character):
272 |                 self._buffer_accent_count += 1
273 |             if (
274 |                 self._foreign_long_watch is False
275 |                 and (is_latin(character) is False or is_accentuated(character))
276 |                 and is_cjk(character) is False
277 |                 and is_hangul(character) is False
278 |                 and is_katakana(character) is False
279 |                 and is_hiragana(character) is False
280 |                 and is_thai(character) is False
281 |             ):
282 |                 self._foreign_long_watch = True
283 |             if (
284 |                 is_cjk(character)
285 |                 or is_hangul(character)
286 |                 or is_katakana(character)
287 |                 or is_hiragana(character)
288 |                 or is_thai(character)
289 |             ):
290 |                 self._buffer_glyph_count += 1
291 |             return
292 |         if not self._buffer:
293 |             return
294 |         if (
295 |             character.isspace() or is_punctuation(character) or is_separator(character)
296 |         ) and self._buffer:
297 |             self._word_count += 1
298 |             buffer_length: int = len(self._buffer)
299 | 
300 |             self._character_count += buffer_length
301 | 
302 |             if buffer_length >= 4:
303 |                 if self._buffer_accent_count / buffer_length >= 0.5:
304 |                     self._is_current_word_bad = True
305 |                 # Word/Buffer ending with an upper case accentuated letter are so rare,
306 |                 # that we will consider them all as suspicious. Same weight as foreign_long suspicious.
307 |                 elif (
308 |                     is_accentuated(self._buffer[-1])
309 |                     and self._buffer[-1].isupper()
310 |                     and all(_.isupper() for _ in self._buffer) is False
311 |                 ):
312 |                     self._foreign_long_count += 1
313 |                     self._is_current_word_bad = True
314 |                 elif self._buffer_glyph_count == 1:
315 |                     self._is_current_word_bad = True
316 |                     self._foreign_long_count += 1
317 |             if buffer_length >= 24 and self._foreign_long_watch:
318 |                 camel_case_dst = [
319 |                     i
320 |                     for c, i in zip(self._buffer, range(0, buffer_length))
321 |                     if c.isupper()
322 |                 ]
323 |                 probable_camel_cased: bool = False
324 | 
325 |                 if camel_case_dst and (len(camel_case_dst) / buffer_length <= 0.3):
326 |                     probable_camel_cased = True
327 | 
328 |                 if not probable_camel_cased:
329 |                     self._foreign_long_count += 1
330 |                     self._is_current_word_bad = True
331 | 
332 |             if self._is_current_word_bad:
333 |                 self._bad_word_count += 1
334 |                 self._bad_character_count += len(self._buffer)
335 |                 self._is_current_word_bad = False
336 | 
337 |             self._foreign_long_watch = False
338 |             self._buffer = ""
339 |             self._buffer_accent_count = 0
340 |             self._buffer_glyph_count = 0
341 |         elif (
342 |             character not in {"<", ">", "-", "=", "~", "|", "_"}
343 |             and character.isdigit() is False
344 |             and is_symbol(character)
345 |         ):
346 |             self._is_current_word_bad = True
347 |             self._buffer += character
348 | 
349 |     def reset(self) -> None:  # pragma: no cover
350 |         self._buffer = ""
351 |         self._is_current_word_bad = False
352 |         self._foreign_long_watch = False
353 |         self._bad_word_count = 0
354 |         self._word_count = 0
355 |         self._character_count = 0
356 |         self._bad_character_count = 0
357 |         self._foreign_long_count = 0
358 | 
359 |     @property
360 |     def ratio(self) -> float:
361 |         if self._word_count <= 10 and self._foreign_long_count == 0:
362 |             return 0.0
363 | 
364 |         return self._bad_character_count / self._character_count
365 | 
366 | 
367 | class CjkInvalidStopPlugin(MessDetectorPlugin):
368 |     """
369 |     GB(Chinese) based encoding often render the stop incorrectly when the content does not fit and
370 |     can be easily detected. Searching for the overuse of '丅' and '丄'.
371 |     """
372 | 
373 |     def __init__(self) -> None:
374 |         self._wrong_stop_count: int = 0
375 |         self._cjk_character_count: int = 0
376 | 
377 |     def eligible(self, character: str) -> bool:
378 |         return True
379 | 
380 |     def feed(self, character: str) -> None:
381 |         if character in {"丅", "丄"}:
382 |             self._wrong_stop_count += 1
383 |             return
384 |         if is_cjk(character):
385 |             self._cjk_character_count += 1
386 | 
387 |     def reset(self) -> None:  # pragma: no cover
388 |         self._wrong_stop_count = 0
389 |         self._cjk_character_count = 0
390 | 
391 |     @property
392 |     def ratio(self) -> float:
393 |         if self._cjk_character_count < 16:
394 |             return 0.0
395 |         return self._wrong_stop_count / self._cjk_character_count
396 | 
397 | 
398 | class ArchaicUpperLowerPlugin(MessDetectorPlugin):
399 |     def __init__(self) -> None:
400 |         self._buf: bool = False
401 | 
402 |         self._character_count_since_last_sep: int = 0
403 | 
404 |         self._successive_upper_lower_count: int = 0
405 |         self._successive_upper_lower_count_final: int = 0
406 | 
407 |         self._character_count: int = 0
408 | 
409 |         self._last_alpha_seen: Optional[str] = None
410 |         self._current_ascii_only: bool = True
411 | 
412 |     def eligible(self, character: str) -> bool:
413 |         return True
414 | 
415 |     def feed(self, character: str) -> None:
416 |         is_concerned = character.isalpha() and is_case_variable(character)
417 |         chunk_sep = is_concerned is False
418 | 
419 |         if chunk_sep and self._character_count_since_last_sep > 0:
420 |             if (
421 |                 self._character_count_since_last_sep <= 64
422 |                 and character.isdigit() is False
423 |                 and self._current_ascii_only is False
424 |             ):
425 |                 self._successive_upper_lower_count_final += (
426 |                     self._successive_upper_lower_count
427 |                 )
428 | 
429 |             self._successive_upper_lower_count = 0
430 |             self._character_count_since_last_sep = 0
431 |             self._last_alpha_seen = None
432 |             self._buf = False
433 |             self._character_count += 1
434 |             self._current_ascii_only = True
435 | 
436 |             return
437 | 
438 |         if self._current_ascii_only is True and character.isascii() is False:
439 |             self._current_ascii_only = False
440 | 
441 |         if self._last_alpha_seen is not None:
442 |             if (character.isupper() and self._last_alpha_seen.islower()) or (
443 |                 character.islower() and self._last_alpha_seen.isupper()
444 |             ):
445 |                 if self._buf is True:
446 |                     self._successive_upper_lower_count += 2
447 |                     self._buf = False
448 |                 else:
449 |                     self._buf = True
450 |             else:
451 |                 self._buf = False
452 | 
453 |         self._character_count += 1
454 |         self._character_count_since_last_sep += 1
455 |         self._last_alpha_seen = character
456 | 
457 |     def reset(self) -> None:  # pragma: no cover
458 |         self._character_count = 0
459 |         self._character_count_since_last_sep = 0
460 |         self._successive_upper_lower_count = 0
461 |         self._successive_upper_lower_count_final = 0
462 |         self._last_alpha_seen = None
463 |         self._buf = False
464 |         self._current_ascii_only = True
465 | 
466 |     @property
467 |     def ratio(self) -> float:
468 |         if self._character_count == 0:
469 |             return 0.0
470 | 
471 |         return self._successive_upper_lower_count_final / self._character_count
472 | 
473 | 
474 | class ArabicIsolatedFormPlugin(MessDetectorPlugin):
475 |     def __init__(self) -> None:
476 |         self._character_count: int = 0
477 |         self._isolated_form_count: int = 0
478 | 
479 |     def reset(self) -> None:  # pragma: no cover
480 |         self._character_count = 0
481 |         self._isolated_form_count = 0
482 | 
483 |     def eligible(self, character: str) -> bool:
484 |         return is_arabic(character)
485 | 
486 |     def feed(self, character: str) -> None:
487 |         self._character_count += 1
488 | 
489 |         if is_arabic_isolated_form(character):
490 |             self._isolated_form_count += 1
491 | 
492 |     @property
493 |     def ratio(self) -> float:
494 |         if self._character_count < 8:
495 |             return 0.0
496 | 
497 |         isolated_form_usage: float = self._isolated_form_count / self._character_count
498 | 
499 |         return isolated_form_usage
500 | 
501 | 
502 | @lru_cache(maxsize=1024)
503 | def is_suspiciously_successive_range(
504 |     unicode_range_a: Optional[str], unicode_range_b: Optional[str]
505 | ) -> bool:
506 |     """
507 |     Determine if two Unicode range seen next to each other can be considered as suspicious.
508 |     """
509 |     if unicode_range_a is None or unicode_range_b is None:
510 |         return True
511 | 
512 |     if unicode_range_a == unicode_range_b:
513 |         return False
514 | 
515 |     if "Latin" in unicode_range_a and "Latin" in unicode_range_b:
516 |         return False
517 | 
518 |     if "Emoticons" in unicode_range_a or "Emoticons" in unicode_range_b:
519 |         return False
520 | 
521 |     # Latin characters can be accompanied with a combining diacritical mark
522 |     # eg. Vietnamese.
523 |     if ("Latin" in unicode_range_a or "Latin" in unicode_range_b) and (
524 |         "Combining" in unicode_range_a or "Combining" in unicode_range_b
525 |     ):
526 |         return False
527 | 
528 |     keywords_range_a, keywords_range_b = unicode_range_a.split(
529 |         " "
530 |     ), unicode_range_b.split(" ")
531 | 
532 |     for el in keywords_range_a:
533 |         if el in UNICODE_SECONDARY_RANGE_KEYWORD:
534 |             continue
535 |         if el in keywords_range_b:
536 |             return False
537 | 
538 |     # Japanese Exception
539 |     range_a_jp_chars, range_b_jp_chars = (
540 |         unicode_range_a
541 |         in (
542 |             "Hiragana",
543 |             "Katakana",
544 |         ),
545 |         unicode_range_b in ("Hiragana", "Katakana"),
546 |     )
547 |     if (range_a_jp_chars or range_b_jp_chars) and (
548 |         "CJK" in unicode_range_a or "CJK" in unicode_range_b
549 |     ):
550 |         return False
551 |     if range_a_jp_chars and range_b_jp_chars:
552 |         return False
553 | 
554 |     if "Hangul" in unicode_range_a or "Hangul" in unicode_range_b:
555 |         if "CJK" in unicode_range_a or "CJK" in unicode_range_b:
556 |             return False
557 |         if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin":
558 |             return False
559 | 
560 |     # Chinese/Japanese use dedicated range for punctuation and/or separators.
561 |     if ("CJK" in unicode_range_a or "CJK" in unicode_range_b) or (
562 |         unicode_range_a in ["Katakana", "Hiragana"]
563 |         and unicode_range_b in ["Katakana", "Hiragana"]
564 |     ):
565 |         if "Punctuation" in unicode_range_a or "Punctuation" in unicode_range_b:
566 |             return False
567 |         if "Forms" in unicode_range_a or "Forms" in unicode_range_b:
568 |             return False
569 |         if unicode_range_a == "Basic Latin" or unicode_range_b == "Basic Latin":
570 |             return False
571 | 
572 |     return True
573 | 
574 | 
575 | @lru_cache(maxsize=2048)
576 | def mess_ratio(
577 |     decoded_sequence: str, maximum_threshold: float = 0.2, debug: bool = False
578 | ) -> float:
579 |     """
580 |     Compute a mess ratio given a decoded bytes sequence. The maximum threshold does stop the computation earlier.
581 |     """
582 | 
583 |     detectors: List[MessDetectorPlugin] = [
584 |         md_class() for md_class in MessDetectorPlugin.__subclasses__()
585 |     ]
586 | 
587 |     length: int = len(decoded_sequence) + 1
588 | 
589 |     mean_mess_ratio: float = 0.0
590 | 
591 |     if length < 512:
592 |         intermediary_mean_mess_ratio_calc: int = 32
593 |     elif length <= 1024:
594 |         intermediary_mean_mess_ratio_calc = 64
595 |     else:
596 |         intermediary_mean_mess_ratio_calc = 128
597 | 
598 |     for character, index in zip(decoded_sequence + "\n", range(length)):
599 |         for detector in detectors:
600 |             if detector.eligible(character):
601 |                 detector.feed(character)
602 | 
603 |         if (
604 |             index > 0 and index % intermediary_mean_mess_ratio_calc == 0
605 |         ) or index == length - 1:
606 |             mean_mess_ratio = sum(dt.ratio for dt in detectors)
607 | 
608 |             if mean_mess_ratio >= maximum_threshold:
609 |                 break
610 | 
611 |     if debug:
612 |         logger = getLogger("charset_normalizer")
613 | 
614 |         logger.log(
615 |             TRACE,
616 |             "Mess-detector extended-analysis start. "
617 |             f"intermediary_mean_mess_ratio_calc={intermediary_mean_mess_ratio_calc} mean_mess_ratio={mean_mess_ratio} "
618 |             f"maximum_threshold={maximum_threshold}",
619 |         )
620 | 
621 |         if len(decoded_sequence) > 16:
622 |             logger.log(TRACE, f"Starting with: {decoded_sequence[:16]}")
623 |             logger.log(TRACE, f"Ending with: {decoded_sequence[-16::]}")
624 | 
625 |         for dt in detectors:  # pragma: nocover
626 |             logger.log(TRACE, f"{dt.__class__}: {dt.ratio}")
627 | 
628 |     return round(mean_mess_ratio, 3)
629 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/click/utils.py:
--------------------------------------------------------------------------------

```python
  1 | import os
  2 | import re
  3 | import sys
  4 | import typing as t
  5 | from functools import update_wrapper
  6 | from types import ModuleType
  7 | from types import TracebackType
  8 | 
  9 | from ._compat import _default_text_stderr
 10 | from ._compat import _default_text_stdout
 11 | from ._compat import _find_binary_writer
 12 | from ._compat import auto_wrap_for_ansi
 13 | from ._compat import binary_streams
 14 | from ._compat import open_stream
 15 | from ._compat import should_strip_ansi
 16 | from ._compat import strip_ansi
 17 | from ._compat import text_streams
 18 | from ._compat import WIN
 19 | from .globals import resolve_color_default
 20 | 
 21 | if t.TYPE_CHECKING:
 22 |     import typing_extensions as te
 23 | 
 24 |     P = te.ParamSpec("P")
 25 | 
 26 | R = t.TypeVar("R")
 27 | 
 28 | 
 29 | def _posixify(name: str) -> str:
 30 |     return "-".join(name.split()).lower()
 31 | 
 32 | 
 33 | def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]":
 34 |     """Wraps a function so that it swallows exceptions."""
 35 | 
 36 |     def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]:
 37 |         try:
 38 |             return func(*args, **kwargs)
 39 |         except Exception:
 40 |             pass
 41 |         return None
 42 | 
 43 |     return update_wrapper(wrapper, func)
 44 | 
 45 | 
 46 | def make_str(value: t.Any) -> str:
 47 |     """Converts a value into a valid string."""
 48 |     if isinstance(value, bytes):
 49 |         try:
 50 |             return value.decode(sys.getfilesystemencoding())
 51 |         except UnicodeError:
 52 |             return value.decode("utf-8", "replace")
 53 |     return str(value)
 54 | 
 55 | 
 56 | def make_default_short_help(help: str, max_length: int = 45) -> str:
 57 |     """Returns a condensed version of help string."""
 58 |     # Consider only the first paragraph.
 59 |     paragraph_end = help.find("\n\n")
 60 | 
 61 |     if paragraph_end != -1:
 62 |         help = help[:paragraph_end]
 63 | 
 64 |     # Collapse newlines, tabs, and spaces.
 65 |     words = help.split()
 66 | 
 67 |     if not words:
 68 |         return ""
 69 | 
 70 |     # The first paragraph started with a "no rewrap" marker, ignore it.
 71 |     if words[0] == "\b":
 72 |         words = words[1:]
 73 | 
 74 |     total_length = 0
 75 |     last_index = len(words) - 1
 76 | 
 77 |     for i, word in enumerate(words):
 78 |         total_length += len(word) + (i > 0)
 79 | 
 80 |         if total_length > max_length:  # too long, truncate
 81 |             break
 82 | 
 83 |         if word[-1] == ".":  # sentence end, truncate without "..."
 84 |             return " ".join(words[: i + 1])
 85 | 
 86 |         if total_length == max_length and i != last_index:
 87 |             break  # not at sentence end, truncate with "..."
 88 |     else:
 89 |         return " ".join(words)  # no truncation needed
 90 | 
 91 |     # Account for the length of the suffix.
 92 |     total_length += len("...")
 93 | 
 94 |     # remove words until the length is short enough
 95 |     while i > 0:
 96 |         total_length -= len(words[i]) + (i > 0)
 97 | 
 98 |         if total_length <= max_length:
 99 |             break
100 | 
101 |         i -= 1
102 | 
103 |     return " ".join(words[:i]) + "..."
104 | 
105 | 
106 | class LazyFile:
107 |     """A lazy file works like a regular file but it does not fully open
108 |     the file but it does perform some basic checks early to see if the
109 |     filename parameter does make sense.  This is useful for safely opening
110 |     files for writing.
111 |     """
112 | 
113 |     def __init__(
114 |         self,
115 |         filename: t.Union[str, "os.PathLike[str]"],
116 |         mode: str = "r",
117 |         encoding: t.Optional[str] = None,
118 |         errors: t.Optional[str] = "strict",
119 |         atomic: bool = False,
120 |     ):
121 |         self.name: str = os.fspath(filename)
122 |         self.mode = mode
123 |         self.encoding = encoding
124 |         self.errors = errors
125 |         self.atomic = atomic
126 |         self._f: t.Optional[t.IO[t.Any]]
127 |         self.should_close: bool
128 | 
129 |         if self.name == "-":
130 |             self._f, self.should_close = open_stream(filename, mode, encoding, errors)
131 |         else:
132 |             if "r" in mode:
133 |                 # Open and close the file in case we're opening it for
134 |                 # reading so that we can catch at least some errors in
135 |                 # some cases early.
136 |                 open(filename, mode).close()
137 |             self._f = None
138 |             self.should_close = True
139 | 
140 |     def __getattr__(self, name: str) -> t.Any:
141 |         return getattr(self.open(), name)
142 | 
143 |     def __repr__(self) -> str:
144 |         if self._f is not None:
145 |             return repr(self._f)
146 |         return f"<unopened file '{format_filename(self.name)}' {self.mode}>"
147 | 
148 |     def open(self) -> t.IO[t.Any]:
149 |         """Opens the file if it's not yet open.  This call might fail with
150 |         a :exc:`FileError`.  Not handling this error will produce an error
151 |         that Click shows.
152 |         """
153 |         if self._f is not None:
154 |             return self._f
155 |         try:
156 |             rv, self.should_close = open_stream(
157 |                 self.name, self.mode, self.encoding, self.errors, atomic=self.atomic
158 |             )
159 |         except OSError as e:  # noqa: E402
160 |             from .exceptions import FileError
161 | 
162 |             raise FileError(self.name, hint=e.strerror) from e
163 |         self._f = rv
164 |         return rv
165 | 
166 |     def close(self) -> None:
167 |         """Closes the underlying file, no matter what."""
168 |         if self._f is not None:
169 |             self._f.close()
170 | 
171 |     def close_intelligently(self) -> None:
172 |         """This function only closes the file if it was opened by the lazy
173 |         file wrapper.  For instance this will never close stdin.
174 |         """
175 |         if self.should_close:
176 |             self.close()
177 | 
178 |     def __enter__(self) -> "LazyFile":
179 |         return self
180 | 
181 |     def __exit__(
182 |         self,
183 |         exc_type: t.Optional[t.Type[BaseException]],
184 |         exc_value: t.Optional[BaseException],
185 |         tb: t.Optional[TracebackType],
186 |     ) -> None:
187 |         self.close_intelligently()
188 | 
189 |     def __iter__(self) -> t.Iterator[t.AnyStr]:
190 |         self.open()
191 |         return iter(self._f)  # type: ignore
192 | 
193 | 
194 | class KeepOpenFile:
195 |     def __init__(self, file: t.IO[t.Any]) -> None:
196 |         self._file: t.IO[t.Any] = file
197 | 
198 |     def __getattr__(self, name: str) -> t.Any:
199 |         return getattr(self._file, name)
200 | 
201 |     def __enter__(self) -> "KeepOpenFile":
202 |         return self
203 | 
204 |     def __exit__(
205 |         self,
206 |         exc_type: t.Optional[t.Type[BaseException]],
207 |         exc_value: t.Optional[BaseException],
208 |         tb: t.Optional[TracebackType],
209 |     ) -> None:
210 |         pass
211 | 
212 |     def __repr__(self) -> str:
213 |         return repr(self._file)
214 | 
215 |     def __iter__(self) -> t.Iterator[t.AnyStr]:
216 |         return iter(self._file)
217 | 
218 | 
219 | def echo(
220 |     message: t.Optional[t.Any] = None,
221 |     file: t.Optional[t.IO[t.Any]] = None,
222 |     nl: bool = True,
223 |     err: bool = False,
224 |     color: t.Optional[bool] = None,
225 | ) -> None:
226 |     """Print a message and newline to stdout or a file. This should be
227 |     used instead of :func:`print` because it provides better support
228 |     for different data, files, and environments.
229 | 
230 |     Compared to :func:`print`, this does the following:
231 | 
232 |     -   Ensures that the output encoding is not misconfigured on Linux.
233 |     -   Supports Unicode in the Windows console.
234 |     -   Supports writing to binary outputs, and supports writing bytes
235 |         to text outputs.
236 |     -   Supports colors and styles on Windows.
237 |     -   Removes ANSI color and style codes if the output does not look
238 |         like an interactive terminal.
239 |     -   Always flushes the output.
240 | 
241 |     :param message: The string or bytes to output. Other objects are
242 |         converted to strings.
243 |     :param file: The file to write to. Defaults to ``stdout``.
244 |     :param err: Write to ``stderr`` instead of ``stdout``.
245 |     :param nl: Print a newline after the message. Enabled by default.
246 |     :param color: Force showing or hiding colors and other styles. By
247 |         default Click will remove color if the output does not look like
248 |         an interactive terminal.
249 | 
250 |     .. versionchanged:: 6.0
251 |         Support Unicode output on the Windows console. Click does not
252 |         modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()``
253 |         will still not support Unicode.
254 | 
255 |     .. versionchanged:: 4.0
256 |         Added the ``color`` parameter.
257 | 
258 |     .. versionadded:: 3.0
259 |         Added the ``err`` parameter.
260 | 
261 |     .. versionchanged:: 2.0
262 |         Support colors on Windows if colorama is installed.
263 |     """
264 |     if file is None:
265 |         if err:
266 |             file = _default_text_stderr()
267 |         else:
268 |             file = _default_text_stdout()
269 | 
270 |         # There are no standard streams attached to write to. For example,
271 |         # pythonw on Windows.
272 |         if file is None:
273 |             return
274 | 
275 |     # Convert non bytes/text into the native string type.
276 |     if message is not None and not isinstance(message, (str, bytes, bytearray)):
277 |         out: t.Optional[t.Union[str, bytes]] = str(message)
278 |     else:
279 |         out = message
280 | 
281 |     if nl:
282 |         out = out or ""
283 |         if isinstance(out, str):
284 |             out += "\n"
285 |         else:
286 |             out += b"\n"
287 | 
288 |     if not out:
289 |         file.flush()
290 |         return
291 | 
292 |     # If there is a message and the value looks like bytes, we manually
293 |     # need to find the binary stream and write the message in there.
294 |     # This is done separately so that most stream types will work as you
295 |     # would expect. Eg: you can write to StringIO for other cases.
296 |     if isinstance(out, (bytes, bytearray)):
297 |         binary_file = _find_binary_writer(file)
298 | 
299 |         if binary_file is not None:
300 |             file.flush()
301 |             binary_file.write(out)
302 |             binary_file.flush()
303 |             return
304 | 
305 |     # ANSI style code support. For no message or bytes, nothing happens.
306 |     # When outputting to a file instead of a terminal, strip codes.
307 |     else:
308 |         color = resolve_color_default(color)
309 | 
310 |         if should_strip_ansi(file, color):
311 |             out = strip_ansi(out)
312 |         elif WIN:
313 |             if auto_wrap_for_ansi is not None:
314 |                 file = auto_wrap_for_ansi(file)  # type: ignore
315 |             elif not color:
316 |                 out = strip_ansi(out)
317 | 
318 |     file.write(out)  # type: ignore
319 |     file.flush()
320 | 
321 | 
322 | def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO:
323 |     """Returns a system stream for byte processing.
324 | 
325 |     :param name: the name of the stream to open.  Valid names are ``'stdin'``,
326 |                  ``'stdout'`` and ``'stderr'``
327 |     """
328 |     opener = binary_streams.get(name)
329 |     if opener is None:
330 |         raise TypeError(f"Unknown standard stream '{name}'")
331 |     return opener()
332 | 
333 | 
334 | def get_text_stream(
335 |     name: "te.Literal['stdin', 'stdout', 'stderr']",
336 |     encoding: t.Optional[str] = None,
337 |     errors: t.Optional[str] = "strict",
338 | ) -> t.TextIO:
339 |     """Returns a system stream for text processing.  This usually returns
340 |     a wrapped stream around a binary stream returned from
341 |     :func:`get_binary_stream` but it also can take shortcuts for already
342 |     correctly configured streams.
343 | 
344 |     :param name: the name of the stream to open.  Valid names are ``'stdin'``,
345 |                  ``'stdout'`` and ``'stderr'``
346 |     :param encoding: overrides the detected default encoding.
347 |     :param errors: overrides the default error mode.
348 |     """
349 |     opener = text_streams.get(name)
350 |     if opener is None:
351 |         raise TypeError(f"Unknown standard stream '{name}'")
352 |     return opener(encoding, errors)
353 | 
354 | 
355 | def open_file(
356 |     filename: str,
357 |     mode: str = "r",
358 |     encoding: t.Optional[str] = None,
359 |     errors: t.Optional[str] = "strict",
360 |     lazy: bool = False,
361 |     atomic: bool = False,
362 | ) -> t.IO[t.Any]:
363 |     """Open a file, with extra behavior to handle ``'-'`` to indicate
364 |     a standard stream, lazy open on write, and atomic write. Similar to
365 |     the behavior of the :class:`~click.File` param type.
366 | 
367 |     If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is
368 |     wrapped so that using it in a context manager will not close it.
369 |     This makes it possible to use the function without accidentally
370 |     closing a standard stream:
371 | 
372 |     .. code-block:: python
373 | 
374 |         with open_file(filename) as f:
375 |             ...
376 | 
377 |     :param filename: The name of the file to open, or ``'-'`` for
378 |         ``stdin``/``stdout``.
379 |     :param mode: The mode in which to open the file.
380 |     :param encoding: The encoding to decode or encode a file opened in
381 |         text mode.
382 |     :param errors: The error handling mode.
383 |     :param lazy: Wait to open the file until it is accessed. For read
384 |         mode, the file is temporarily opened to raise access errors
385 |         early, then closed until it is read again.
386 |     :param atomic: Write to a temporary file and replace the given file
387 |         on close.
388 | 
389 |     .. versionadded:: 3.0
390 |     """
391 |     if lazy:
392 |         return t.cast(
393 |             t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic)
394 |         )
395 | 
396 |     f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic)
397 | 
398 |     if not should_close:
399 |         f = t.cast(t.IO[t.Any], KeepOpenFile(f))
400 | 
401 |     return f
402 | 
403 | 
404 | def format_filename(
405 |     filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]",
406 |     shorten: bool = False,
407 | ) -> str:
408 |     """Format a filename as a string for display. Ensures the filename can be
409 |     displayed by replacing any invalid bytes or surrogate escapes in the name
410 |     with the replacement character ``�``.
411 | 
412 |     Invalid bytes or surrogate escapes will raise an error when written to a
413 |     stream with ``errors="strict". This will typically happen with ``stdout``
414 |     when the locale is something like ``en_GB.UTF-8``.
415 | 
416 |     Many scenarios *are* safe to write surrogates though, due to PEP 538 and
417 |     PEP 540, including:
418 | 
419 |     -   Writing to ``stderr``, which uses ``errors="backslashreplace"``.
420 |     -   The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens
421 |         stdout and stderr with ``errors="surrogateescape"``.
422 |     -   None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``.
423 |     -   Python is started in UTF-8 mode  with  ``PYTHONUTF8=1`` or ``-X utf8``.
424 |         Python opens stdout and stderr with ``errors="surrogateescape"``.
425 | 
426 |     :param filename: formats a filename for UI display.  This will also convert
427 |                      the filename into unicode without failing.
428 |     :param shorten: this optionally shortens the filename to strip of the
429 |                     path that leads up to it.
430 |     """
431 |     if shorten:
432 |         filename = os.path.basename(filename)
433 |     else:
434 |         filename = os.fspath(filename)
435 | 
436 |     if isinstance(filename, bytes):
437 |         filename = filename.decode(sys.getfilesystemencoding(), "replace")
438 |     else:
439 |         filename = filename.encode("utf-8", "surrogateescape").decode(
440 |             "utf-8", "replace"
441 |         )
442 | 
443 |     return filename
444 | 
445 | 
446 | def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str:
447 |     r"""Returns the config folder for the application.  The default behavior
448 |     is to return whatever is most appropriate for the operating system.
449 | 
450 |     To give you an idea, for an app called ``"Foo Bar"``, something like
451 |     the following folders could be returned:
452 | 
453 |     Mac OS X:
454 |       ``~/Library/Application Support/Foo Bar``
455 |     Mac OS X (POSIX):
456 |       ``~/.foo-bar``
457 |     Unix:
458 |       ``~/.config/foo-bar``
459 |     Unix (POSIX):
460 |       ``~/.foo-bar``
461 |     Windows (roaming):
462 |       ``C:\Users\<user>\AppData\Roaming\Foo Bar``
463 |     Windows (not roaming):
464 |       ``C:\Users\<user>\AppData\Local\Foo Bar``
465 | 
466 |     .. versionadded:: 2.0
467 | 
468 |     :param app_name: the application name.  This should be properly capitalized
469 |                      and can contain whitespace.
470 |     :param roaming: controls if the folder should be roaming or not on Windows.
471 |                     Has no effect otherwise.
472 |     :param force_posix: if this is set to `True` then on any POSIX system the
473 |                         folder will be stored in the home folder with a leading
474 |                         dot instead of the XDG config home or darwin's
475 |                         application support folder.
476 |     """
477 |     if WIN:
478 |         key = "APPDATA" if roaming else "LOCALAPPDATA"
479 |         folder = os.environ.get(key)
480 |         if folder is None:
481 |             folder = os.path.expanduser("~")
482 |         return os.path.join(folder, app_name)
483 |     if force_posix:
484 |         return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}"))
485 |     if sys.platform == "darwin":
486 |         return os.path.join(
487 |             os.path.expanduser("~/Library/Application Support"), app_name
488 |         )
489 |     return os.path.join(
490 |         os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")),
491 |         _posixify(app_name),
492 |     )
493 | 
494 | 
495 | class PacifyFlushWrapper:
496 |     """This wrapper is used to catch and suppress BrokenPipeErrors resulting
497 |     from ``.flush()`` being called on broken pipe during the shutdown/final-GC
498 |     of the Python interpreter. Notably ``.flush()`` is always called on
499 |     ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any
500 |     other cleanup code, and the case where the underlying file is not a broken
501 |     pipe, all calls and attributes are proxied.
502 |     """
503 | 
504 |     def __init__(self, wrapped: t.IO[t.Any]) -> None:
505 |         self.wrapped = wrapped
506 | 
507 |     def flush(self) -> None:
508 |         try:
509 |             self.wrapped.flush()
510 |         except OSError as e:
511 |             import errno
512 | 
513 |             if e.errno != errno.EPIPE:
514 |                 raise
515 | 
516 |     def __getattr__(self, attr: str) -> t.Any:
517 |         return getattr(self.wrapped, attr)
518 | 
519 | 
520 | def _detect_program_name(
521 |     path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None
522 | ) -> str:
523 |     """Determine the command used to run the program, for use in help
524 |     text. If a file or entry point was executed, the file name is
525 |     returned. If ``python -m`` was used to execute a module or package,
526 |     ``python -m name`` is returned.
527 | 
528 |     This doesn't try to be too precise, the goal is to give a concise
529 |     name for help text. Files are only shown as their name without the
530 |     path. ``python`` is only shown for modules, and the full path to
531 |     ``sys.executable`` is not shown.
532 | 
533 |     :param path: The Python file being executed. Python puts this in
534 |         ``sys.argv[0]``, which is used by default.
535 |     :param _main: The ``__main__`` module. This should only be passed
536 |         during internal testing.
537 | 
538 |     .. versionadded:: 8.0
539 |         Based on command args detection in the Werkzeug reloader.
540 | 
541 |     :meta private:
542 |     """
543 |     if _main is None:
544 |         _main = sys.modules["__main__"]
545 | 
546 |     if not path:
547 |         path = sys.argv[0]
548 | 
549 |     # The value of __package__ indicates how Python was called. It may
550 |     # not exist if a setuptools script is installed as an egg. It may be
551 |     # set incorrectly for entry points created with pip on Windows.
552 |     # It is set to "" inside a Shiv or PEX zipapp.
553 |     if getattr(_main, "__package__", None) in {None, ""} or (
554 |         os.name == "nt"
555 |         and _main.__package__ == ""
556 |         and not os.path.exists(path)
557 |         and os.path.exists(f"{path}.exe")
558 |     ):
559 |         # Executed a file, like "python app.py".
560 |         return os.path.basename(path)
561 | 
562 |     # Executed a module, like "python -m example".
563 |     # Rewritten by Python from "-m script" to "/path/to/script.py".
564 |     # Need to look at main module to determine how it was executed.
565 |     py_module = t.cast(str, _main.__package__)
566 |     name = os.path.splitext(os.path.basename(path))[0]
567 | 
568 |     # A submodule like "example.cli".
569 |     if name != "__main__":
570 |         py_module = f"{py_module}.{name}"
571 | 
572 |     return f"python -m {py_module.lstrip('.')}"
573 | 
574 | 
575 | def _expand_args(
576 |     args: t.Iterable[str],
577 |     *,
578 |     user: bool = True,
579 |     env: bool = True,
580 |     glob_recursive: bool = True,
581 | ) -> t.List[str]:
582 |     """Simulate Unix shell expansion with Python functions.
583 | 
584 |     See :func:`glob.glob`, :func:`os.path.expanduser`, and
585 |     :func:`os.path.expandvars`.
586 | 
587 |     This is intended for use on Windows, where the shell does not do any
588 |     expansion. It may not exactly match what a Unix shell would do.
589 | 
590 |     :param args: List of command line arguments to expand.
591 |     :param user: Expand user home directory.
592 |     :param env: Expand environment variables.
593 |     :param glob_recursive: ``**`` matches directories recursively.
594 | 
595 |     .. versionchanged:: 8.1
596 |         Invalid glob patterns are treated as empty expansions rather
597 |         than raising an error.
598 | 
599 |     .. versionadded:: 8.0
600 | 
601 |     :meta private:
602 |     """
603 |     from glob import glob
604 | 
605 |     out = []
606 | 
607 |     for arg in args:
608 |         if user:
609 |             arg = os.path.expanduser(arg)
610 | 
611 |         if env:
612 |             arg = os.path.expandvars(arg)
613 | 
614 |         try:
615 |             matches = glob(arg, recursive=glob_recursive)
616 |         except re.error:
617 |             matches = []
618 | 
619 |         if not matches:
620 |             out.append(arg)
621 |         else:
622 |             out.extend(matches)
623 | 
624 |     return out
625 | 
```

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

```python
  1 | from __future__ import absolute_import
  2 | 
  3 | import datetime
  4 | import logging
  5 | import os
  6 | import re
  7 | import socket
  8 | import warnings
  9 | from socket import error as SocketError
 10 | from socket import timeout as SocketTimeout
 11 | 
 12 | from .packages import six
 13 | from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection
 14 | from .packages.six.moves.http_client import HTTPException  # noqa: F401
 15 | from .util.proxy import create_proxy_ssl_context
 16 | 
 17 | try:  # Compiled with SSL?
 18 |     import ssl
 19 | 
 20 |     BaseSSLError = ssl.SSLError
 21 | except (ImportError, AttributeError):  # Platform-specific: No SSL.
 22 |     ssl = None
 23 | 
 24 |     class BaseSSLError(BaseException):
 25 |         pass
 26 | 
 27 | 
 28 | try:
 29 |     # Python 3: not a no-op, we're adding this to the namespace so it can be imported.
 30 |     ConnectionError = ConnectionError
 31 | except NameError:
 32 |     # Python 2
 33 |     class ConnectionError(Exception):
 34 |         pass
 35 | 
 36 | 
 37 | try:  # Python 3:
 38 |     # Not a no-op, we're adding this to the namespace so it can be imported.
 39 |     BrokenPipeError = BrokenPipeError
 40 | except NameError:  # Python 2:
 41 | 
 42 |     class BrokenPipeError(Exception):
 43 |         pass
 44 | 
 45 | 
 46 | from ._collections import HTTPHeaderDict  # noqa (historical, removed in v2)
 47 | from ._version import __version__
 48 | from .exceptions import (
 49 |     ConnectTimeoutError,
 50 |     NewConnectionError,
 51 |     SubjectAltNameWarning,
 52 |     SystemTimeWarning,
 53 | )
 54 | from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection
 55 | from .util.ssl_ import (
 56 |     assert_fingerprint,
 57 |     create_urllib3_context,
 58 |     is_ipaddress,
 59 |     resolve_cert_reqs,
 60 |     resolve_ssl_version,
 61 |     ssl_wrap_socket,
 62 | )
 63 | from .util.ssl_match_hostname import CertificateError, match_hostname
 64 | 
 65 | log = logging.getLogger(__name__)
 66 | 
 67 | port_by_scheme = {"http": 80, "https": 443}
 68 | 
 69 | # When it comes time to update this value as a part of regular maintenance
 70 | # (ie test_recent_date is failing) update it to ~6 months before the current date.
 71 | RECENT_DATE = datetime.date(2022, 1, 1)
 72 | 
 73 | _CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
 74 | 
 75 | 
 76 | class HTTPConnection(_HTTPConnection, object):
 77 |     """
 78 |     Based on :class:`http.client.HTTPConnection` but provides an extra constructor
 79 |     backwards-compatibility layer between older and newer Pythons.
 80 | 
 81 |     Additional keyword parameters are used to configure attributes of the connection.
 82 |     Accepted parameters include:
 83 | 
 84 |     - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
 85 |     - ``source_address``: Set the source address for the current connection.
 86 |     - ``socket_options``: Set specific options on the underlying socket. If not specified, then
 87 |       defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
 88 |       Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
 89 | 
 90 |       For example, if you wish to enable TCP Keep Alive in addition to the defaults,
 91 |       you might pass:
 92 | 
 93 |       .. code-block:: python
 94 | 
 95 |          HTTPConnection.default_socket_options + [
 96 |              (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
 97 |          ]
 98 | 
 99 |       Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
100 |     """
101 | 
102 |     default_port = port_by_scheme["http"]
103 | 
104 |     #: Disable Nagle's algorithm by default.
105 |     #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``
106 |     default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
107 | 
108 |     #: Whether this connection verifies the host's certificate.
109 |     is_verified = False
110 | 
111 |     #: Whether this proxy connection (if used) verifies the proxy host's
112 |     #: certificate.
113 |     proxy_is_verified = None
114 | 
115 |     def __init__(self, *args, **kw):
116 |         if not six.PY2:
117 |             kw.pop("strict", None)
118 | 
119 |         # Pre-set source_address.
120 |         self.source_address = kw.get("source_address")
121 | 
122 |         #: The socket options provided by the user. If no options are
123 |         #: provided, we use the default options.
124 |         self.socket_options = kw.pop("socket_options", self.default_socket_options)
125 | 
126 |         # Proxy options provided by the user.
127 |         self.proxy = kw.pop("proxy", None)
128 |         self.proxy_config = kw.pop("proxy_config", None)
129 | 
130 |         _HTTPConnection.__init__(self, *args, **kw)
131 | 
132 |     @property
133 |     def host(self):
134 |         """
135 |         Getter method to remove any trailing dots that indicate the hostname is an FQDN.
136 | 
137 |         In general, SSL certificates don't include the trailing dot indicating a
138 |         fully-qualified domain name, and thus, they don't validate properly when
139 |         checked against a domain name that includes the dot. In addition, some
140 |         servers may not expect to receive the trailing dot when provided.
141 | 
142 |         However, the hostname with trailing dot is critical to DNS resolution; doing a
143 |         lookup with the trailing dot will properly only resolve the appropriate FQDN,
144 |         whereas a lookup without a trailing dot will search the system's search domain
145 |         list. Thus, it's important to keep the original host around for use only in
146 |         those cases where it's appropriate (i.e., when doing DNS lookup to establish the
147 |         actual TCP connection across which we're going to send HTTP requests).
148 |         """
149 |         return self._dns_host.rstrip(".")
150 | 
151 |     @host.setter
152 |     def host(self, value):
153 |         """
154 |         Setter for the `host` property.
155 | 
156 |         We assume that only urllib3 uses the _dns_host attribute; httplib itself
157 |         only uses `host`, and it seems reasonable that other libraries follow suit.
158 |         """
159 |         self._dns_host = value
160 | 
161 |     def _new_conn(self):
162 |         """Establish a socket connection and set nodelay settings on it.
163 | 
164 |         :return: New socket connection.
165 |         """
166 |         extra_kw = {}
167 |         if self.source_address:
168 |             extra_kw["source_address"] = self.source_address
169 | 
170 |         if self.socket_options:
171 |             extra_kw["socket_options"] = self.socket_options
172 | 
173 |         try:
174 |             conn = connection.create_connection(
175 |                 (self._dns_host, self.port), self.timeout, **extra_kw
176 |             )
177 | 
178 |         except SocketTimeout:
179 |             raise ConnectTimeoutError(
180 |                 self,
181 |                 "Connection to %s timed out. (connect timeout=%s)"
182 |                 % (self.host, self.timeout),
183 |             )
184 | 
185 |         except SocketError as e:
186 |             raise NewConnectionError(
187 |                 self, "Failed to establish a new connection: %s" % e
188 |             )
189 | 
190 |         return conn
191 | 
192 |     def _is_using_tunnel(self):
193 |         # Google App Engine's httplib does not define _tunnel_host
194 |         return getattr(self, "_tunnel_host", None)
195 | 
196 |     def _prepare_conn(self, conn):
197 |         self.sock = conn
198 |         if self._is_using_tunnel():
199 |             # TODO: Fix tunnel so it doesn't depend on self.sock state.
200 |             self._tunnel()
201 |             # Mark this connection as not reusable
202 |             self.auto_open = 0
203 | 
204 |     def connect(self):
205 |         conn = self._new_conn()
206 |         self._prepare_conn(conn)
207 | 
208 |     def putrequest(self, method, url, *args, **kwargs):
209 |         """ """
210 |         # Empty docstring because the indentation of CPython's implementation
211 |         # is broken but we don't want this method in our documentation.
212 |         match = _CONTAINS_CONTROL_CHAR_RE.search(method)
213 |         if match:
214 |             raise ValueError(
215 |                 "Method cannot contain non-token characters %r (found at least %r)"
216 |                 % (method, match.group())
217 |             )
218 | 
219 |         return _HTTPConnection.putrequest(self, method, url, *args, **kwargs)
220 | 
221 |     def putheader(self, header, *values):
222 |         """ """
223 |         if not any(isinstance(v, str) and v == SKIP_HEADER for v in values):
224 |             _HTTPConnection.putheader(self, header, *values)
225 |         elif six.ensure_str(header.lower()) not in SKIPPABLE_HEADERS:
226 |             raise ValueError(
227 |                 "urllib3.util.SKIP_HEADER only supports '%s'"
228 |                 % ("', '".join(map(str.title, sorted(SKIPPABLE_HEADERS))),)
229 |             )
230 | 
231 |     def request(self, method, url, body=None, headers=None):
232 |         # Update the inner socket's timeout value to send the request.
233 |         # This only triggers if the connection is re-used.
234 |         if getattr(self, "sock", None) is not None:
235 |             self.sock.settimeout(self.timeout)
236 | 
237 |         if headers is None:
238 |             headers = {}
239 |         else:
240 |             # Avoid modifying the headers passed into .request()
241 |             headers = headers.copy()
242 |         if "user-agent" not in (six.ensure_str(k.lower()) for k in headers):
243 |             headers["User-Agent"] = _get_default_user_agent()
244 |         super(HTTPConnection, self).request(method, url, body=body, headers=headers)
245 | 
246 |     def request_chunked(self, method, url, body=None, headers=None):
247 |         """
248 |         Alternative to the common request method, which sends the
249 |         body with chunked encoding and not as one block
250 |         """
251 |         headers = headers or {}
252 |         header_keys = set([six.ensure_str(k.lower()) for k in headers])
253 |         skip_accept_encoding = "accept-encoding" in header_keys
254 |         skip_host = "host" in header_keys
255 |         self.putrequest(
256 |             method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host
257 |         )
258 |         if "user-agent" not in header_keys:
259 |             self.putheader("User-Agent", _get_default_user_agent())
260 |         for header, value in headers.items():
261 |             self.putheader(header, value)
262 |         if "transfer-encoding" not in header_keys:
263 |             self.putheader("Transfer-Encoding", "chunked")
264 |         self.endheaders()
265 | 
266 |         if body is not None:
267 |             stringish_types = six.string_types + (bytes,)
268 |             if isinstance(body, stringish_types):
269 |                 body = (body,)
270 |             for chunk in body:
271 |                 if not chunk:
272 |                     continue
273 |                 if not isinstance(chunk, bytes):
274 |                     chunk = chunk.encode("utf8")
275 |                 len_str = hex(len(chunk))[2:]
276 |                 to_send = bytearray(len_str.encode())
277 |                 to_send += b"\r\n"
278 |                 to_send += chunk
279 |                 to_send += b"\r\n"
280 |                 self.send(to_send)
281 | 
282 |         # After the if clause, to always have a closed body
283 |         self.send(b"0\r\n\r\n")
284 | 
285 | 
286 | class HTTPSConnection(HTTPConnection):
287 |     """
288 |     Many of the parameters to this constructor are passed to the underlying SSL
289 |     socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.
290 |     """
291 | 
292 |     default_port = port_by_scheme["https"]
293 | 
294 |     cert_reqs = None
295 |     ca_certs = None
296 |     ca_cert_dir = None
297 |     ca_cert_data = None
298 |     ssl_version = None
299 |     assert_fingerprint = None
300 |     tls_in_tls_required = False
301 | 
302 |     def __init__(
303 |         self,
304 |         host,
305 |         port=None,
306 |         key_file=None,
307 |         cert_file=None,
308 |         key_password=None,
309 |         strict=None,
310 |         timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
311 |         ssl_context=None,
312 |         server_hostname=None,
313 |         **kw
314 |     ):
315 | 
316 |         HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw)
317 | 
318 |         self.key_file = key_file
319 |         self.cert_file = cert_file
320 |         self.key_password = key_password
321 |         self.ssl_context = ssl_context
322 |         self.server_hostname = server_hostname
323 | 
324 |         # Required property for Google AppEngine 1.9.0 which otherwise causes
325 |         # HTTPS requests to go out as HTTP. (See Issue #356)
326 |         self._protocol = "https"
327 | 
328 |     def set_cert(
329 |         self,
330 |         key_file=None,
331 |         cert_file=None,
332 |         cert_reqs=None,
333 |         key_password=None,
334 |         ca_certs=None,
335 |         assert_hostname=None,
336 |         assert_fingerprint=None,
337 |         ca_cert_dir=None,
338 |         ca_cert_data=None,
339 |     ):
340 |         """
341 |         This method should only be called once, before the connection is used.
342 |         """
343 |         # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also
344 |         # have an SSLContext object in which case we'll use its verify_mode.
345 |         if cert_reqs is None:
346 |             if self.ssl_context is not None:
347 |                 cert_reqs = self.ssl_context.verify_mode
348 |             else:
349 |                 cert_reqs = resolve_cert_reqs(None)
350 | 
351 |         self.key_file = key_file
352 |         self.cert_file = cert_file
353 |         self.cert_reqs = cert_reqs
354 |         self.key_password = key_password
355 |         self.assert_hostname = assert_hostname
356 |         self.assert_fingerprint = assert_fingerprint
357 |         self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
358 |         self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
359 |         self.ca_cert_data = ca_cert_data
360 | 
361 |     def connect(self):
362 |         # Add certificate verification
363 |         self.sock = conn = self._new_conn()
364 |         hostname = self.host
365 |         tls_in_tls = False
366 | 
367 |         if self._is_using_tunnel():
368 |             if self.tls_in_tls_required:
369 |                 self.sock = conn = self._connect_tls_proxy(hostname, conn)
370 |                 tls_in_tls = True
371 | 
372 |             # Calls self._set_hostport(), so self.host is
373 |             # self._tunnel_host below.
374 |             self._tunnel()
375 |             # Mark this connection as not reusable
376 |             self.auto_open = 0
377 | 
378 |             # Override the host with the one we're requesting data from.
379 |             hostname = self._tunnel_host
380 | 
381 |         server_hostname = hostname
382 |         if self.server_hostname is not None:
383 |             server_hostname = self.server_hostname
384 | 
385 |         is_time_off = datetime.date.today() < RECENT_DATE
386 |         if is_time_off:
387 |             warnings.warn(
388 |                 (
389 |                     "System time is way off (before {0}). This will probably "
390 |                     "lead to SSL verification errors"
391 |                 ).format(RECENT_DATE),
392 |                 SystemTimeWarning,
393 |             )
394 | 
395 |         # Wrap socket using verification with the root certs in
396 |         # trusted_root_certs
397 |         default_ssl_context = False
398 |         if self.ssl_context is None:
399 |             default_ssl_context = True
400 |             self.ssl_context = create_urllib3_context(
401 |                 ssl_version=resolve_ssl_version(self.ssl_version),
402 |                 cert_reqs=resolve_cert_reqs(self.cert_reqs),
403 |             )
404 | 
405 |         context = self.ssl_context
406 |         context.verify_mode = resolve_cert_reqs(self.cert_reqs)
407 | 
408 |         # Try to load OS default certs if none are given.
409 |         # Works well on Windows (requires Python3.4+)
410 |         if (
411 |             not self.ca_certs
412 |             and not self.ca_cert_dir
413 |             and not self.ca_cert_data
414 |             and default_ssl_context
415 |             and hasattr(context, "load_default_certs")
416 |         ):
417 |             context.load_default_certs()
418 | 
419 |         self.sock = ssl_wrap_socket(
420 |             sock=conn,
421 |             keyfile=self.key_file,
422 |             certfile=self.cert_file,
423 |             key_password=self.key_password,
424 |             ca_certs=self.ca_certs,
425 |             ca_cert_dir=self.ca_cert_dir,
426 |             ca_cert_data=self.ca_cert_data,
427 |             server_hostname=server_hostname,
428 |             ssl_context=context,
429 |             tls_in_tls=tls_in_tls,
430 |         )
431 | 
432 |         # If we're using all defaults and the connection
433 |         # is TLSv1 or TLSv1.1 we throw a DeprecationWarning
434 |         # for the host.
435 |         if (
436 |             default_ssl_context
437 |             and self.ssl_version is None
438 |             and hasattr(self.sock, "version")
439 |             and self.sock.version() in {"TLSv1", "TLSv1.1"}
440 |         ):
441 |             warnings.warn(
442 |                 "Negotiating TLSv1/TLSv1.1 by default is deprecated "
443 |                 "and will be disabled in urllib3 v2.0.0. Connecting to "
444 |                 "'%s' with '%s' can be enabled by explicitly opting-in "
445 |                 "with 'ssl_version'" % (self.host, self.sock.version()),
446 |                 DeprecationWarning,
447 |             )
448 | 
449 |         if self.assert_fingerprint:
450 |             assert_fingerprint(
451 |                 self.sock.getpeercert(binary_form=True), self.assert_fingerprint
452 |             )
453 |         elif (
454 |             context.verify_mode != ssl.CERT_NONE
455 |             and not getattr(context, "check_hostname", False)
456 |             and self.assert_hostname is not False
457 |         ):
458 |             # While urllib3 attempts to always turn off hostname matching from
459 |             # the TLS library, this cannot always be done. So we check whether
460 |             # the TLS Library still thinks it's matching hostnames.
461 |             cert = self.sock.getpeercert()
462 |             if not cert.get("subjectAltName", ()):
463 |                 warnings.warn(
464 |                     (
465 |                         "Certificate for {0} has no `subjectAltName`, falling back to check for a "
466 |                         "`commonName` for now. This feature is being removed by major browsers and "
467 |                         "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
468 |                         "for details.)".format(hostname)
469 |                     ),
470 |                     SubjectAltNameWarning,
471 |                 )
472 |             _match_hostname(cert, self.assert_hostname or server_hostname)
473 | 
474 |         self.is_verified = (
475 |             context.verify_mode == ssl.CERT_REQUIRED
476 |             or self.assert_fingerprint is not None
477 |         )
478 | 
479 |     def _connect_tls_proxy(self, hostname, conn):
480 |         """
481 |         Establish a TLS connection to the proxy using the provided SSL context.
482 |         """
483 |         proxy_config = self.proxy_config
484 |         ssl_context = proxy_config.ssl_context
485 |         if ssl_context:
486 |             # If the user provided a proxy context, we assume CA and client
487 |             # certificates have already been set
488 |             return ssl_wrap_socket(
489 |                 sock=conn,
490 |                 server_hostname=hostname,
491 |                 ssl_context=ssl_context,
492 |             )
493 | 
494 |         ssl_context = create_proxy_ssl_context(
495 |             self.ssl_version,
496 |             self.cert_reqs,
497 |             self.ca_certs,
498 |             self.ca_cert_dir,
499 |             self.ca_cert_data,
500 |         )
501 | 
502 |         # If no cert was provided, use only the default options for server
503 |         # certificate validation
504 |         socket = ssl_wrap_socket(
505 |             sock=conn,
506 |             ca_certs=self.ca_certs,
507 |             ca_cert_dir=self.ca_cert_dir,
508 |             ca_cert_data=self.ca_cert_data,
509 |             server_hostname=hostname,
510 |             ssl_context=ssl_context,
511 |         )
512 | 
513 |         if ssl_context.verify_mode != ssl.CERT_NONE and not getattr(
514 |             ssl_context, "check_hostname", False
515 |         ):
516 |             # While urllib3 attempts to always turn off hostname matching from
517 |             # the TLS library, this cannot always be done. So we check whether
518 |             # the TLS Library still thinks it's matching hostnames.
519 |             cert = socket.getpeercert()
520 |             if not cert.get("subjectAltName", ()):
521 |                 warnings.warn(
522 |                     (
523 |                         "Certificate for {0} has no `subjectAltName`, falling back to check for a "
524 |                         "`commonName` for now. This feature is being removed by major browsers and "
525 |                         "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
526 |                         "for details.)".format(hostname)
527 |                     ),
528 |                     SubjectAltNameWarning,
529 |                 )
530 |             _match_hostname(cert, hostname)
531 | 
532 |         self.proxy_is_verified = ssl_context.verify_mode == ssl.CERT_REQUIRED
533 |         return socket
534 | 
535 | 
536 | def _match_hostname(cert, asserted_hostname):
537 |     # Our upstream implementation of ssl.match_hostname()
538 |     # only applies this normalization to IP addresses so it doesn't
539 |     # match DNS SANs so we do the same thing!
540 |     stripped_hostname = asserted_hostname.strip("u[]")
541 |     if is_ipaddress(stripped_hostname):
542 |         asserted_hostname = stripped_hostname
543 | 
544 |     try:
545 |         match_hostname(cert, asserted_hostname)
546 |     except CertificateError as e:
547 |         log.warning(
548 |             "Certificate did not match expected hostname: %s. Certificate: %s",
549 |             asserted_hostname,
550 |             cert,
551 |         )
552 |         # Add cert to exception and reraise so client code can inspect
553 |         # the cert when catching the exception, if they want to
554 |         e._peer_cert = cert
555 |         raise
556 | 
557 | 
558 | def _get_default_user_agent():
559 |     return "python-urllib3/%s" % __version__
560 | 
561 | 
562 | class DummyConnection(object):
563 |     """Used to detect a failed ConnectionCls import."""
564 | 
565 |     pass
566 | 
567 | 
568 | if not ssl:
569 |     HTTPSConnection = DummyConnection  # noqa: F811
570 | 
571 | 
572 | VerifiedHTTPSConnection = HTTPSConnection
573 | 
```
Page 69/168FirstPrevNextLast