#
tokens: 48785/50000 2/808 files (page 93/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 93 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/lxml/html/diff.py:
--------------------------------------------------------------------------------

```python
  1 | # cython: language_level=3
  2 | 
  3 | 
  4 | import difflib
  5 | from lxml import etree
  6 | from lxml.html import fragment_fromstring
  7 | import re
  8 | 
  9 | __all__ = ['html_annotate', 'htmldiff']
 10 | 
 11 | try:
 12 |     from html import escape as html_escape
 13 | except ImportError:
 14 |     from cgi import escape as html_escape
 15 | try:
 16 |     _unicode = unicode
 17 | except NameError:
 18 |     # Python 3
 19 |     _unicode = str
 20 | try:
 21 |     basestring
 22 | except NameError:
 23 |     # Python 3
 24 |     basestring = str
 25 | 
 26 | ############################################################
 27 | ## Annotation
 28 | ############################################################
 29 | 
 30 | def default_markup(text, version):
 31 |     return '<span title="%s">%s</span>' % (
 32 |         html_escape(_unicode(version), 1), text)
 33 | 
 34 | def html_annotate(doclist, markup=default_markup):
 35 |     """
 36 |     doclist should be ordered from oldest to newest, like::
 37 | 
 38 |         >>> version1 = 'Hello World'
 39 |         >>> version2 = 'Goodbye World'
 40 |         >>> print(html_annotate([(version1, 'version 1'),
 41 |         ...                      (version2, 'version 2')]))
 42 |         <span title="version 2">Goodbye</span> <span title="version 1">World</span>
 43 | 
 44 |     The documents must be *fragments* (str/UTF8 or unicode), not
 45 |     complete documents
 46 | 
 47 |     The markup argument is a function to markup the spans of words.
 48 |     This function is called like markup('Hello', 'version 2'), and
 49 |     returns HTML.  The first argument is text and never includes any
 50 |     markup.  The default uses a span with a title:
 51 | 
 52 |         >>> print(default_markup('Some Text', 'by Joe'))
 53 |         <span title="by Joe">Some Text</span>
 54 |     """
 55 |     # The basic strategy we have is to split the documents up into
 56 |     # logical tokens (which are words with attached markup).  We then
 57 |     # do diffs of each of the versions to track when a token first
 58 |     # appeared in the document; the annotation attached to the token
 59 |     # is the version where it first appeared.
 60 |     tokenlist = [tokenize_annotated(doc, version)
 61 |                  for doc, version in doclist]
 62 |     cur_tokens = tokenlist[0]
 63 |     for tokens in tokenlist[1:]:
 64 |         html_annotate_merge_annotations(cur_tokens, tokens)
 65 |         cur_tokens = tokens
 66 | 
 67 |     # After we've tracked all the tokens, we can combine spans of text
 68 |     # that are adjacent and have the same annotation
 69 |     cur_tokens = compress_tokens(cur_tokens)
 70 |     # And finally add markup
 71 |     result = markup_serialize_tokens(cur_tokens, markup)
 72 |     return ''.join(result).strip()
 73 | 
 74 | def tokenize_annotated(doc, annotation): 
 75 |     """Tokenize a document and add an annotation attribute to each token
 76 |     """
 77 |     tokens = tokenize(doc, include_hrefs=False)
 78 |     for tok in tokens: 
 79 |         tok.annotation = annotation
 80 |     return tokens
 81 | 
 82 | def html_annotate_merge_annotations(tokens_old, tokens_new): 
 83 |     """Merge the annotations from tokens_old into tokens_new, when the
 84 |     tokens in the new document already existed in the old document.
 85 |     """
 86 |     s = InsensitiveSequenceMatcher(a=tokens_old, b=tokens_new)
 87 |     commands = s.get_opcodes()
 88 | 
 89 |     for command, i1, i2, j1, j2 in commands:
 90 |         if command == 'equal': 
 91 |             eq_old = tokens_old[i1:i2]
 92 |             eq_new = tokens_new[j1:j2]
 93 |             copy_annotations(eq_old, eq_new)
 94 | 
 95 | def copy_annotations(src, dest): 
 96 |     """
 97 |     Copy annotations from the tokens listed in src to the tokens in dest
 98 |     """
 99 |     assert len(src) == len(dest)
100 |     for src_tok, dest_tok in zip(src, dest): 
101 |         dest_tok.annotation = src_tok.annotation
102 | 
103 | def compress_tokens(tokens):
104 |     """
105 |     Combine adjacent tokens when there is no HTML between the tokens, 
106 |     and they share an annotation
107 |     """
108 |     result = [tokens[0]] 
109 |     for tok in tokens[1:]: 
110 |         if (not result[-1].post_tags and 
111 |             not tok.pre_tags and 
112 |             result[-1].annotation == tok.annotation): 
113 |             compress_merge_back(result, tok)
114 |         else: 
115 |             result.append(tok)
116 |     return result
117 | 
118 | def compress_merge_back(tokens, tok): 
119 |     """ Merge tok into the last element of tokens (modifying the list of
120 |     tokens in-place).  """
121 |     last = tokens[-1]
122 |     if type(last) is not token or type(tok) is not token: 
123 |         tokens.append(tok)
124 |     else:
125 |         text = _unicode(last)
126 |         if last.trailing_whitespace:
127 |             text += last.trailing_whitespace
128 |         text += tok
129 |         merged = token(text,
130 |                        pre_tags=last.pre_tags,
131 |                        post_tags=tok.post_tags,
132 |                        trailing_whitespace=tok.trailing_whitespace)
133 |         merged.annotation = last.annotation
134 |         tokens[-1] = merged
135 |     
136 | def markup_serialize_tokens(tokens, markup_func):
137 |     """
138 |     Serialize the list of tokens into a list of text chunks, calling
139 |     markup_func around text to add annotations.
140 |     """
141 |     for token in tokens:
142 |         yield from token.pre_tags
143 |         html = token.html()
144 |         html = markup_func(html, token.annotation)
145 |         if token.trailing_whitespace:
146 |             html += token.trailing_whitespace
147 |         yield html
148 |         yield from token.post_tags
149 | 
150 | 
151 | ############################################################
152 | ## HTML Diffs
153 | ############################################################
154 | 
155 | def htmldiff(old_html, new_html):
156 |     ## FIXME: this should take parsed documents too, and use their body
157 |     ## or other content.
158 |     """ Do a diff of the old and new document.  The documents are HTML
159 |     *fragments* (str/UTF8 or unicode), they are not complete documents
160 |     (i.e., no <html> tag).
161 | 
162 |     Returns HTML with <ins> and <del> tags added around the
163 |     appropriate text.  
164 | 
165 |     Markup is generally ignored, with the markup from new_html
166 |     preserved, and possibly some markup from old_html (though it is
167 |     considered acceptable to lose some of the old markup).  Only the
168 |     words in the HTML are diffed.  The exception is <img> tags, which
169 |     are treated like words, and the href attribute of <a> tags, which
170 |     are noted inside the tag itself when there are changes.
171 |     """ 
172 |     old_html_tokens = tokenize(old_html)
173 |     new_html_tokens = tokenize(new_html)
174 |     result = htmldiff_tokens(old_html_tokens, new_html_tokens)
175 |     result = ''.join(result).strip()
176 |     return fixup_ins_del_tags(result)
177 | 
178 | def htmldiff_tokens(html1_tokens, html2_tokens):
179 |     """ Does a diff on the tokens themselves, returning a list of text
180 |     chunks (not tokens).
181 |     """
182 |     # There are several passes as we do the differences.  The tokens
183 |     # isolate the portion of the content we care to diff; difflib does
184 |     # all the actual hard work at that point.  
185 |     #
186 |     # Then we must create a valid document from pieces of both the old
187 |     # document and the new document.  We generally prefer to take
188 |     # markup from the new document, and only do a best effort attempt
189 |     # to keep markup from the old document; anything that we can't
190 |     # resolve we throw away.  Also we try to put the deletes as close
191 |     # to the location where we think they would have been -- because
192 |     # we are only keeping the markup from the new document, it can be
193 |     # fuzzy where in the new document the old text would have gone.
194 |     # Again we just do a best effort attempt.
195 |     s = InsensitiveSequenceMatcher(a=html1_tokens, b=html2_tokens)
196 |     commands = s.get_opcodes()
197 |     result = []
198 |     for command, i1, i2, j1, j2 in commands:
199 |         if command == 'equal':
200 |             result.extend(expand_tokens(html2_tokens[j1:j2], equal=True))
201 |             continue
202 |         if command == 'insert' or command == 'replace':
203 |             ins_tokens = expand_tokens(html2_tokens[j1:j2])
204 |             merge_insert(ins_tokens, result)
205 |         if command == 'delete' or command == 'replace':
206 |             del_tokens = expand_tokens(html1_tokens[i1:i2])
207 |             merge_delete(del_tokens, result)
208 |     # If deletes were inserted directly as <del> then we'd have an
209 |     # invalid document at this point.  Instead we put in special
210 |     # markers, and when the complete diffed document has been created
211 |     # we try to move the deletes around and resolve any problems.
212 |     result = cleanup_delete(result)
213 | 
214 |     return result
215 | 
216 | def expand_tokens(tokens, equal=False):
217 |     """Given a list of tokens, return a generator of the chunks of
218 |     text for the data in the tokens.
219 |     """
220 |     for token in tokens:
221 |         yield from token.pre_tags
222 |         if not equal or not token.hide_when_equal:
223 |             if token.trailing_whitespace:
224 |                 yield token.html() + token.trailing_whitespace
225 |             else:
226 |                 yield token.html()
227 |         yield from token.post_tags
228 | 
229 | def merge_insert(ins_chunks, doc):
230 |     """ doc is the already-handled document (as a list of text chunks);
231 |     here we add <ins>ins_chunks</ins> to the end of that.  """
232 |     # Though we don't throw away unbalanced_start or unbalanced_end
233 |     # (we assume there is accompanying markup later or earlier in the
234 |     # document), we only put <ins> around the balanced portion.
235 |     unbalanced_start, balanced, unbalanced_end = split_unbalanced(ins_chunks)
236 |     doc.extend(unbalanced_start)
237 |     if doc and not doc[-1].endswith(' '):
238 |         # Fix up the case where the word before the insert didn't end with 
239 |         # a space
240 |         doc[-1] += ' '
241 |     doc.append('<ins>')
242 |     if balanced and balanced[-1].endswith(' '):
243 |         # We move space outside of </ins>
244 |         balanced[-1] = balanced[-1][:-1]
245 |     doc.extend(balanced)
246 |     doc.append('</ins> ')
247 |     doc.extend(unbalanced_end)
248 | 
249 | # These are sentinels to represent the start and end of a <del>
250 | # segment, until we do the cleanup phase to turn them into proper
251 | # markup:
252 | class DEL_START:
253 |     pass
254 | class DEL_END:
255 |     pass
256 | 
257 | class NoDeletes(Exception):
258 |     """ Raised when the document no longer contains any pending deletes
259 |     (DEL_START/DEL_END) """
260 | 
261 | def merge_delete(del_chunks, doc):
262 |     """ Adds the text chunks in del_chunks to the document doc (another
263 |     list of text chunks) with marker to show it is a delete.
264 |     cleanup_delete later resolves these markers into <del> tags."""
265 |     doc.append(DEL_START)
266 |     doc.extend(del_chunks)
267 |     doc.append(DEL_END)
268 | 
269 | def cleanup_delete(chunks):
270 |     """ Cleans up any DEL_START/DEL_END markers in the document, replacing
271 |     them with <del></del>.  To do this while keeping the document
272 |     valid, it may need to drop some tags (either start or end tags).
273 | 
274 |     It may also move the del into adjacent tags to try to move it to a
275 |     similar location where it was originally located (e.g., moving a
276 |     delete into preceding <div> tag, if the del looks like (DEL_START,
277 |     'Text</div>', DEL_END)"""
278 |     while 1:
279 |         # Find a pending DEL_START/DEL_END, splitting the document
280 |         # into stuff-preceding-DEL_START, stuff-inside, and
281 |         # stuff-following-DEL_END
282 |         try:
283 |             pre_delete, delete, post_delete = split_delete(chunks)
284 |         except NoDeletes:
285 |             # Nothing found, we've cleaned up the entire doc
286 |             break
287 |         # The stuff-inside-DEL_START/END may not be well balanced
288 |         # markup.  First we figure out what unbalanced portions there are:
289 |         unbalanced_start, balanced, unbalanced_end = split_unbalanced(delete)
290 |         # Then we move the span forward and/or backward based on these
291 |         # unbalanced portions:
292 |         locate_unbalanced_start(unbalanced_start, pre_delete, post_delete)
293 |         locate_unbalanced_end(unbalanced_end, pre_delete, post_delete)
294 |         doc = pre_delete
295 |         if doc and not doc[-1].endswith(' '):
296 |             # Fix up case where the word before us didn't have a trailing space
297 |             doc[-1] += ' '
298 |         doc.append('<del>')
299 |         if balanced and balanced[-1].endswith(' '):
300 |             # We move space outside of </del>
301 |             balanced[-1] = balanced[-1][:-1]
302 |         doc.extend(balanced)
303 |         doc.append('</del> ')
304 |         doc.extend(post_delete)
305 |         chunks = doc
306 |     return chunks
307 | 
308 | def split_unbalanced(chunks):
309 |     """Return (unbalanced_start, balanced, unbalanced_end), where each is
310 |     a list of text and tag chunks.
311 | 
312 |     unbalanced_start is a list of all the tags that are opened, but
313 |     not closed in this span.  Similarly, unbalanced_end is a list of
314 |     tags that are closed but were not opened.  Extracting these might
315 |     mean some reordering of the chunks."""
316 |     start = []
317 |     end = []
318 |     tag_stack = []
319 |     balanced = []
320 |     for chunk in chunks:
321 |         if not chunk.startswith('<'):
322 |             balanced.append(chunk)
323 |             continue
324 |         endtag = chunk[1] == '/'
325 |         name = chunk.split()[0].strip('<>/')
326 |         if name in empty_tags:
327 |             balanced.append(chunk)
328 |             continue
329 |         if endtag:
330 |             if tag_stack and tag_stack[-1][0] == name:
331 |                 balanced.append(chunk)
332 |                 name, pos, tag = tag_stack.pop()
333 |                 balanced[pos] = tag
334 |             elif tag_stack:
335 |                 start.extend([tag for name, pos, tag in tag_stack])
336 |                 tag_stack = []
337 |                 end.append(chunk)
338 |             else:
339 |                 end.append(chunk)
340 |         else:
341 |             tag_stack.append((name, len(balanced), chunk))
342 |             balanced.append(None)
343 |     start.extend(
344 |         [chunk for name, pos, chunk in tag_stack])
345 |     balanced = [chunk for chunk in balanced if chunk is not None]
346 |     return start, balanced, end
347 | 
348 | def split_delete(chunks):
349 |     """ Returns (stuff_before_DEL_START, stuff_inside_DEL_START_END,
350 |     stuff_after_DEL_END).  Returns the first case found (there may be
351 |     more DEL_STARTs in stuff_after_DEL_END).  Raises NoDeletes if
352 |     there's no DEL_START found. """
353 |     try:
354 |         pos = chunks.index(DEL_START)
355 |     except ValueError:
356 |         raise NoDeletes
357 |     pos2 = chunks.index(DEL_END)
358 |     return chunks[:pos], chunks[pos+1:pos2], chunks[pos2+1:]
359 | 
360 | def locate_unbalanced_start(unbalanced_start, pre_delete, post_delete):
361 |     """ pre_delete and post_delete implicitly point to a place in the
362 |     document (where the two were split).  This moves that point (by
363 |     popping items from one and pushing them onto the other).  It moves
364 |     the point to try to find a place where unbalanced_start applies.
365 | 
366 |     As an example::
367 | 
368 |         >>> unbalanced_start = ['<div>']
369 |         >>> doc = ['<p>', 'Text', '</p>', '<div>', 'More Text', '</div>']
370 |         >>> pre, post = doc[:3], doc[3:]
371 |         >>> pre, post
372 |         (['<p>', 'Text', '</p>'], ['<div>', 'More Text', '</div>'])
373 |         >>> locate_unbalanced_start(unbalanced_start, pre, post)
374 |         >>> pre, post
375 |         (['<p>', 'Text', '</p>', '<div>'], ['More Text', '</div>'])
376 | 
377 |     As you can see, we moved the point so that the dangling <div> that
378 |     we found will be effectively replaced by the div in the original
379 |     document.  If this doesn't work out, we just throw away
380 |     unbalanced_start without doing anything.
381 |     """
382 |     while 1:
383 |         if not unbalanced_start:
384 |             # We have totally succeeded in finding the position
385 |             break
386 |         finding = unbalanced_start[0]
387 |         finding_name = finding.split()[0].strip('<>')
388 |         if not post_delete:
389 |             break
390 |         next = post_delete[0]
391 |         if next is DEL_START or not next.startswith('<'):
392 |             # Reached a word, we can't move the delete text forward
393 |             break
394 |         if next[1] == '/':
395 |             # Reached a closing tag, can we go further?  Maybe not...
396 |             break
397 |         name = next.split()[0].strip('<>')
398 |         if name == 'ins':
399 |             # Can't move into an insert
400 |             break
401 |         assert name != 'del', (
402 |             "Unexpected delete tag: %r" % next)
403 |         if name == finding_name:
404 |             unbalanced_start.pop(0)
405 |             pre_delete.append(post_delete.pop(0))
406 |         else:
407 |             # Found a tag that doesn't match
408 |             break
409 | 
410 | def locate_unbalanced_end(unbalanced_end, pre_delete, post_delete):
411 |     """ like locate_unbalanced_start, except handling end tags and
412 |     possibly moving the point earlier in the document.  """
413 |     while 1:
414 |         if not unbalanced_end:
415 |             # Success
416 |             break
417 |         finding = unbalanced_end[-1]
418 |         finding_name = finding.split()[0].strip('<>/')
419 |         if not pre_delete:
420 |             break
421 |         next = pre_delete[-1]
422 |         if next is DEL_END or not next.startswith('</'):
423 |             # A word or a start tag
424 |             break
425 |         name = next.split()[0].strip('<>/')
426 |         if name == 'ins' or name == 'del':
427 |             # Can't move into an insert or delete
428 |             break
429 |         if name == finding_name:
430 |             unbalanced_end.pop()
431 |             post_delete.insert(0, pre_delete.pop())
432 |         else:
433 |             # Found a tag that doesn't match
434 |             break
435 | 
436 | class token(_unicode):
437 |     """ Represents a diffable token, generally a word that is displayed to
438 |     the user.  Opening tags are attached to this token when they are
439 |     adjacent (pre_tags) and closing tags that follow the word
440 |     (post_tags).  Some exceptions occur when there are empty tags
441 |     adjacent to a word, so there may be close tags in pre_tags, or
442 |     open tags in post_tags.
443 | 
444 |     We also keep track of whether the word was originally followed by
445 |     whitespace, even though we do not want to treat the word as
446 |     equivalent to a similar word that does not have a trailing
447 |     space."""
448 | 
449 |     # When this is true, the token will be eliminated from the
450 |     # displayed diff if no change has occurred:
451 |     hide_when_equal = False
452 | 
453 |     def __new__(cls, text, pre_tags=None, post_tags=None, trailing_whitespace=""):
454 |         obj = _unicode.__new__(cls, text)
455 | 
456 |         if pre_tags is not None:
457 |             obj.pre_tags = pre_tags
458 |         else:
459 |             obj.pre_tags = []
460 | 
461 |         if post_tags is not None:
462 |             obj.post_tags = post_tags
463 |         else:
464 |             obj.post_tags = []
465 | 
466 |         obj.trailing_whitespace = trailing_whitespace
467 | 
468 |         return obj
469 | 
470 |     def __repr__(self):
471 |         return 'token(%s, %r, %r, %r)' % (_unicode.__repr__(self), self.pre_tags,
472 |                                           self.post_tags, self.trailing_whitespace)
473 | 
474 |     def html(self):
475 |         return _unicode(self)
476 | 
477 | class tag_token(token):
478 | 
479 |     """ Represents a token that is actually a tag.  Currently this is just
480 |     the <img> tag, which takes up visible space just like a word but
481 |     is only represented in a document by a tag.  """
482 | 
483 |     def __new__(cls, tag, data, html_repr, pre_tags=None, 
484 |                 post_tags=None, trailing_whitespace=""):
485 |         obj = token.__new__(cls, "%s: %s" % (type, data), 
486 |                             pre_tags=pre_tags, 
487 |                             post_tags=post_tags, 
488 |                             trailing_whitespace=trailing_whitespace)
489 |         obj.tag = tag
490 |         obj.data = data
491 |         obj.html_repr = html_repr
492 |         return obj
493 | 
494 |     def __repr__(self):
495 |         return 'tag_token(%s, %s, html_repr=%s, post_tags=%r, pre_tags=%r, trailing_whitespace=%r)' % (
496 |             self.tag, 
497 |             self.data, 
498 |             self.html_repr, 
499 |             self.pre_tags, 
500 |             self.post_tags, 
501 |             self.trailing_whitespace)
502 |     def html(self):
503 |         return self.html_repr
504 | 
505 | class href_token(token):
506 | 
507 |     """ Represents the href in an anchor tag.  Unlike other words, we only
508 |     show the href when it changes.  """
509 | 
510 |     hide_when_equal = True
511 | 
512 |     def html(self):
513 |         return ' Link: %s' % self
514 | 
515 | def tokenize(html, include_hrefs=True):
516 |     """
517 |     Parse the given HTML and returns token objects (words with attached tags).
518 | 
519 |     This parses only the content of a page; anything in the head is
520 |     ignored, and the <head> and <body> elements are themselves
521 |     optional.  The content is then parsed by lxml, which ensures the
522 |     validity of the resulting parsed document (though lxml may make
523 |     incorrect guesses when the markup is particular bad).
524 | 
525 |     <ins> and <del> tags are also eliminated from the document, as
526 |     that gets confusing.
527 | 
528 |     If include_hrefs is true, then the href attribute of <a> tags is
529 |     included as a special kind of diffable token."""
530 |     if etree.iselement(html):
531 |         body_el = html
532 |     else:
533 |         body_el = parse_html(html, cleanup=True)
534 |     # Then we split the document into text chunks for each tag, word, and end tag:
535 |     chunks = flatten_el(body_el, skip_tag=True, include_hrefs=include_hrefs)
536 |     # Finally re-joining them into token objects:
537 |     return fixup_chunks(chunks)
538 | 
539 | def parse_html(html, cleanup=True):
540 |     """
541 |     Parses an HTML fragment, returning an lxml element.  Note that the HTML will be
542 |     wrapped in a <div> tag that was not in the original document.
543 | 
544 |     If cleanup is true, make sure there's no <head> or <body>, and get
545 |     rid of any <ins> and <del> tags.
546 |     """
547 |     if cleanup:
548 |         # This removes any extra markup or structure like <head>:
549 |         html = cleanup_html(html)
550 |     return fragment_fromstring(html, create_parent=True)
551 | 
552 | _body_re = re.compile(r'<body.*?>', re.I|re.S)
553 | _end_body_re = re.compile(r'</body.*?>', re.I|re.S)
554 | _ins_del_re = re.compile(r'</?(ins|del).*?>', re.I|re.S)
555 | 
556 | def cleanup_html(html):
557 |     """ This 'cleans' the HTML, meaning that any page structure is removed
558 |     (only the contents of <body> are used, if there is any <body).
559 |     Also <ins> and <del> tags are removed.  """
560 |     match = _body_re.search(html)
561 |     if match:
562 |         html = html[match.end():]
563 |     match = _end_body_re.search(html)
564 |     if match:
565 |         html = html[:match.start()]
566 |     html = _ins_del_re.sub('', html)
567 |     return html
568 |     
569 | 
570 | end_whitespace_re = re.compile(r'[ \t\n\r]$')
571 | 
572 | def split_trailing_whitespace(word):
573 |     """
574 |     This function takes a word, such as 'test\n\n' and returns ('test','\n\n')
575 |     """
576 |     stripped_length = len(word.rstrip())
577 |     return word[0:stripped_length], word[stripped_length:]
578 | 
579 | 
580 | def fixup_chunks(chunks):
581 |     """
582 |     This function takes a list of chunks and produces a list of tokens.
583 |     """
584 |     tag_accum = []
585 |     cur_word = None
586 |     result = []
587 |     for chunk in chunks:
588 |         if isinstance(chunk, tuple):
589 |             if chunk[0] == 'img':
590 |                 src = chunk[1]
591 |                 tag, trailing_whitespace = split_trailing_whitespace(chunk[2])
592 |                 cur_word = tag_token('img', src, html_repr=tag,
593 |                                      pre_tags=tag_accum,
594 |                                      trailing_whitespace=trailing_whitespace)
595 |                 tag_accum = []
596 |                 result.append(cur_word)
597 | 
598 |             elif chunk[0] == 'href':
599 |                 href = chunk[1]
600 |                 cur_word = href_token(href, pre_tags=tag_accum, trailing_whitespace=" ")
601 |                 tag_accum = []
602 |                 result.append(cur_word)
603 |             continue
604 | 
605 |         if is_word(chunk):
606 |             chunk, trailing_whitespace = split_trailing_whitespace(chunk)
607 |             cur_word = token(chunk, pre_tags=tag_accum, trailing_whitespace=trailing_whitespace)
608 |             tag_accum = []
609 |             result.append(cur_word)
610 | 
611 |         elif is_start_tag(chunk):
612 |             tag_accum.append(chunk)
613 | 
614 |         elif is_end_tag(chunk):
615 |             if tag_accum:
616 |                 tag_accum.append(chunk)
617 |             else:
618 |                 assert cur_word, (
619 |                     "Weird state, cur_word=%r, result=%r, chunks=%r of %r"
620 |                     % (cur_word, result, chunk, chunks))
621 |                 cur_word.post_tags.append(chunk)
622 |         else:
623 |             assert False
624 | 
625 |     if not result:
626 |         return [token('', pre_tags=tag_accum)]
627 |     else:
628 |         result[-1].post_tags.extend(tag_accum)
629 | 
630 |     return result
631 | 
632 | 
633 | # All the tags in HTML that don't require end tags:
634 | empty_tags = (
635 |     'param', 'img', 'area', 'br', 'basefont', 'input',
636 |     'base', 'meta', 'link', 'col')
637 | 
638 | block_level_tags = (
639 |     'address',
640 |     'blockquote',
641 |     'center',
642 |     'dir',
643 |     'div',
644 |     'dl',
645 |     'fieldset',
646 |     'form',
647 |     'h1',
648 |     'h2',
649 |     'h3',
650 |     'h4',
651 |     'h5',
652 |     'h6',
653 |     'hr',
654 |     'isindex',
655 |     'menu',
656 |     'noframes',
657 |     'noscript',
658 |     'ol',
659 |     'p',
660 |     'pre',
661 |     'table',
662 |     'ul',
663 |     )
664 | 
665 | block_level_container_tags = (
666 |     'dd',
667 |     'dt',
668 |     'frameset',
669 |     'li',
670 |     'tbody',
671 |     'td',
672 |     'tfoot',
673 |     'th',
674 |     'thead',
675 |     'tr',
676 |     )
677 | 
678 | 
679 | def flatten_el(el, include_hrefs, skip_tag=False):
680 |     """ Takes an lxml element el, and generates all the text chunks for
681 |     that tag.  Each start tag is a chunk, each word is a chunk, and each
682 |     end tag is a chunk.
683 | 
684 |     If skip_tag is true, then the outermost container tag is
685 |     not returned (just its contents)."""
686 |     if not skip_tag:
687 |         if el.tag == 'img':
688 |             yield ('img', el.get('src'), start_tag(el))
689 |         else:
690 |             yield start_tag(el)
691 |     if el.tag in empty_tags and not el.text and not len(el) and not el.tail:
692 |         return
693 |     start_words = split_words(el.text)
694 |     for word in start_words:
695 |         yield html_escape(word)
696 |     for child in el:
697 |         yield from flatten_el(child, include_hrefs=include_hrefs)
698 |     if el.tag == 'a' and el.get('href') and include_hrefs:
699 |         yield ('href', el.get('href'))
700 |     if not skip_tag:
701 |         yield end_tag(el)
702 |         end_words = split_words(el.tail)
703 |         for word in end_words:
704 |             yield html_escape(word)
705 | 
706 | split_words_re = re.compile(r'\S+(?:\s+|$)', re.U)
707 | 
708 | def split_words(text):
709 |     """ Splits some text into words. Includes trailing whitespace
710 |     on each word when appropriate.  """
711 |     if not text or not text.strip():
712 |         return []
713 | 
714 |     words = split_words_re.findall(text)
715 |     return words
716 | 
717 | start_whitespace_re = re.compile(r'^[ \t\n\r]')
718 | 
719 | def start_tag(el):
720 |     """
721 |     The text representation of the start tag for a tag.
722 |     """
723 |     return '<%s%s>' % (
724 |         el.tag, ''.join([' %s="%s"' % (name, html_escape(value, True))
725 |                          for name, value in el.attrib.items()]))
726 | 
727 | def end_tag(el):
728 |     """ The text representation of an end tag for a tag.  Includes
729 |     trailing whitespace when appropriate.  """
730 |     if el.tail and start_whitespace_re.search(el.tail):
731 |         extra = ' '
732 |     else:
733 |         extra = ''
734 |     return '</%s>%s' % (el.tag, extra)
735 | 
736 | def is_word(tok):
737 |     return not tok.startswith('<')
738 | 
739 | def is_end_tag(tok):
740 |     return tok.startswith('</')
741 | 
742 | def is_start_tag(tok):
743 |     return tok.startswith('<') and not tok.startswith('</')
744 | 
745 | def fixup_ins_del_tags(html):
746 |     """ Given an html string, move any <ins> or <del> tags inside of any
747 |     block-level elements, e.g. transform <ins><p>word</p></ins> to
748 |     <p><ins>word</ins></p> """
749 |     doc = parse_html(html, cleanup=False)
750 |     _fixup_ins_del_tags(doc)
751 |     html = serialize_html_fragment(doc, skip_outer=True)
752 |     return html
753 | 
754 | def serialize_html_fragment(el, skip_outer=False):
755 |     """ Serialize a single lxml element as HTML.  The serialized form
756 |     includes the elements tail.  
757 | 
758 |     If skip_outer is true, then don't serialize the outermost tag
759 |     """
760 |     assert not isinstance(el, basestring), (
761 |         "You should pass in an element, not a string like %r" % el)
762 |     html = etree.tostring(el, method="html", encoding=_unicode)
763 |     if skip_outer:
764 |         # Get rid of the extra starting tag:
765 |         html = html[html.find('>')+1:]
766 |         # Get rid of the extra end tag:
767 |         html = html[:html.rfind('<')]
768 |         return html.strip()
769 |     else:
770 |         return html
771 | 
772 | def _fixup_ins_del_tags(doc):
773 |     """fixup_ins_del_tags that works on an lxml document in-place
774 |     """
775 |     for tag in ['ins', 'del']:
776 |         for el in doc.xpath('descendant-or-self::%s' % tag):
777 |             if not _contains_block_level_tag(el):
778 |                 continue
779 |             _move_el_inside_block(el, tag=tag)
780 |             el.drop_tag()
781 |             #_merge_element_contents(el)
782 | 
783 | def _contains_block_level_tag(el):
784 |     """True if the element contains any block-level elements, like <p>, <td>, etc.
785 |     """
786 |     if el.tag in block_level_tags or el.tag in block_level_container_tags:
787 |         return True
788 |     for child in el:
789 |         if _contains_block_level_tag(child):
790 |             return True
791 |     return False
792 | 
793 | def _move_el_inside_block(el, tag):
794 |     """ helper for _fixup_ins_del_tags; actually takes the <ins> etc tags
795 |     and moves them inside any block-level tags.  """
796 |     for child in el:
797 |         if _contains_block_level_tag(child):
798 |             break
799 |     else:
800 |         # No block-level tags in any child
801 |         children_tag = etree.Element(tag)
802 |         children_tag.text = el.text
803 |         el.text = None
804 |         children_tag.extend(list(el))
805 |         el[:] = [children_tag]
806 |         return
807 |     for child in list(el):
808 |         if _contains_block_level_tag(child):
809 |             _move_el_inside_block(child, tag)
810 |             if child.tail:
811 |                 tail_tag = etree.Element(tag)
812 |                 tail_tag.text = child.tail
813 |                 child.tail = None
814 |                 el.insert(el.index(child)+1, tail_tag)
815 |         else:
816 |             child_tag = etree.Element(tag)
817 |             el.replace(child, child_tag)
818 |             child_tag.append(child)
819 |     if el.text:
820 |         text_tag = etree.Element(tag)
821 |         text_tag.text = el.text
822 |         el.text = None
823 |         el.insert(0, text_tag)
824 |             
825 | def _merge_element_contents(el):
826 |     """
827 |     Removes an element, but merges its contents into its place, e.g.,
828 |     given <p>Hi <i>there!</i></p>, if you remove the <i> element you get
829 |     <p>Hi there!</p>
830 |     """
831 |     parent = el.getparent()
832 |     text = el.text or ''
833 |     if el.tail:
834 |         if not len(el):
835 |             text += el.tail
836 |         else:
837 |             if el[-1].tail:
838 |                 el[-1].tail += el.tail
839 |             else:
840 |                 el[-1].tail = el.tail
841 |     index = parent.index(el)
842 |     if text:
843 |         if index == 0:
844 |             previous = None
845 |         else:
846 |             previous = parent[index-1]
847 |         if previous is None:
848 |             if parent.text:
849 |                 parent.text += text
850 |             else:
851 |                 parent.text = text
852 |         else:
853 |             if previous.tail:
854 |                 previous.tail += text
855 |             else:
856 |                 previous.tail = text
857 |     parent[index:index+1] = el.getchildren()
858 | 
859 | class InsensitiveSequenceMatcher(difflib.SequenceMatcher):
860 |     """
861 |     Acts like SequenceMatcher, but tries not to find very small equal
862 |     blocks amidst large spans of changes
863 |     """
864 | 
865 |     threshold = 2
866 |     
867 |     def get_matching_blocks(self):
868 |         size = min(len(self.b), len(self.b))
869 |         threshold = min(self.threshold, size / 4)
870 |         actual = difflib.SequenceMatcher.get_matching_blocks(self)
871 |         return [item for item in actual
872 |                 if item[2] > threshold
873 |                 or not item[2]]
874 | 
875 | if __name__ == '__main__':
876 |     from lxml.html import _diffcommand
877 |     _diffcommand.main()
878 |     
879 | 
```

--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/requests/sessions.py:
--------------------------------------------------------------------------------

```python
  1 | """
  2 | requests.sessions
  3 | ~~~~~~~~~~~~~~~~~
  4 | 
  5 | This module provides a Session object to manage and persist settings across
  6 | requests (cookies, auth, proxies).
  7 | """
  8 | import os
  9 | import sys
 10 | import time
 11 | from collections import OrderedDict
 12 | from datetime import timedelta
 13 | 
 14 | from ._internal_utils import to_native_string
 15 | from .adapters import HTTPAdapter
 16 | from .auth import _basic_auth_str
 17 | from .compat import Mapping, cookielib, urljoin, urlparse
 18 | from .cookies import (
 19 |     RequestsCookieJar,
 20 |     cookiejar_from_dict,
 21 |     extract_cookies_to_jar,
 22 |     merge_cookies,
 23 | )
 24 | from .exceptions import (
 25 |     ChunkedEncodingError,
 26 |     ContentDecodingError,
 27 |     InvalidSchema,
 28 |     TooManyRedirects,
 29 | )
 30 | from .hooks import default_hooks, dispatch_hook
 31 | 
 32 | # formerly defined here, reexposed here for backward compatibility
 33 | from .models import (  # noqa: F401
 34 |     DEFAULT_REDIRECT_LIMIT,
 35 |     REDIRECT_STATI,
 36 |     PreparedRequest,
 37 |     Request,
 38 | )
 39 | from .status_codes import codes
 40 | from .structures import CaseInsensitiveDict
 41 | from .utils import (  # noqa: F401
 42 |     DEFAULT_PORTS,
 43 |     default_headers,
 44 |     get_auth_from_url,
 45 |     get_environ_proxies,
 46 |     get_netrc_auth,
 47 |     requote_uri,
 48 |     resolve_proxies,
 49 |     rewind_body,
 50 |     should_bypass_proxies,
 51 |     to_key_val_list,
 52 | )
 53 | 
 54 | # Preferred clock, based on which one is more accurate on a given system.
 55 | if sys.platform == "win32":
 56 |     preferred_clock = time.perf_counter
 57 | else:
 58 |     preferred_clock = time.time
 59 | 
 60 | 
 61 | def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
 62 |     """Determines appropriate setting for a given request, taking into account
 63 |     the explicit setting on that request, and the setting in the session. If a
 64 |     setting is a dictionary, they will be merged together using `dict_class`
 65 |     """
 66 | 
 67 |     if session_setting is None:
 68 |         return request_setting
 69 | 
 70 |     if request_setting is None:
 71 |         return session_setting
 72 | 
 73 |     # Bypass if not a dictionary (e.g. verify)
 74 |     if not (
 75 |         isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
 76 |     ):
 77 |         return request_setting
 78 | 
 79 |     merged_setting = dict_class(to_key_val_list(session_setting))
 80 |     merged_setting.update(to_key_val_list(request_setting))
 81 | 
 82 |     # Remove keys that are set to None. Extract keys first to avoid altering
 83 |     # the dictionary during iteration.
 84 |     none_keys = [k for (k, v) in merged_setting.items() if v is None]
 85 |     for key in none_keys:
 86 |         del merged_setting[key]
 87 | 
 88 |     return merged_setting
 89 | 
 90 | 
 91 | def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
 92 |     """Properly merges both requests and session hooks.
 93 | 
 94 |     This is necessary because when request_hooks == {'response': []}, the
 95 |     merge breaks Session hooks entirely.
 96 |     """
 97 |     if session_hooks is None or session_hooks.get("response") == []:
 98 |         return request_hooks
 99 | 
100 |     if request_hooks is None or request_hooks.get("response") == []:
101 |         return session_hooks
102 | 
103 |     return merge_setting(request_hooks, session_hooks, dict_class)
104 | 
105 | 
106 | class SessionRedirectMixin:
107 |     def get_redirect_target(self, resp):
108 |         """Receives a Response. Returns a redirect URI or ``None``"""
109 |         # Due to the nature of how requests processes redirects this method will
110 |         # be called at least once upon the original response and at least twice
111 |         # on each subsequent redirect response (if any).
112 |         # If a custom mixin is used to handle this logic, it may be advantageous
113 |         # to cache the redirect location onto the response object as a private
114 |         # attribute.
115 |         if resp.is_redirect:
116 |             location = resp.headers["location"]
117 |             # Currently the underlying http module on py3 decode headers
118 |             # in latin1, but empirical evidence suggests that latin1 is very
119 |             # rarely used with non-ASCII characters in HTTP headers.
120 |             # It is more likely to get UTF8 header rather than latin1.
121 |             # This causes incorrect handling of UTF8 encoded location headers.
122 |             # To solve this, we re-encode the location in latin1.
123 |             location = location.encode("latin1")
124 |             return to_native_string(location, "utf8")
125 |         return None
126 | 
127 |     def should_strip_auth(self, old_url, new_url):
128 |         """Decide whether Authorization header should be removed when redirecting"""
129 |         old_parsed = urlparse(old_url)
130 |         new_parsed = urlparse(new_url)
131 |         if old_parsed.hostname != new_parsed.hostname:
132 |             return True
133 |         # Special case: allow http -> https redirect when using the standard
134 |         # ports. This isn't specified by RFC 7235, but is kept to avoid
135 |         # breaking backwards compatibility with older versions of requests
136 |         # that allowed any redirects on the same host.
137 |         if (
138 |             old_parsed.scheme == "http"
139 |             and old_parsed.port in (80, None)
140 |             and new_parsed.scheme == "https"
141 |             and new_parsed.port in (443, None)
142 |         ):
143 |             return False
144 | 
145 |         # Handle default port usage corresponding to scheme.
146 |         changed_port = old_parsed.port != new_parsed.port
147 |         changed_scheme = old_parsed.scheme != new_parsed.scheme
148 |         default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
149 |         if (
150 |             not changed_scheme
151 |             and old_parsed.port in default_port
152 |             and new_parsed.port in default_port
153 |         ):
154 |             return False
155 | 
156 |         # Standard case: root URI must match
157 |         return changed_port or changed_scheme
158 | 
159 |     def resolve_redirects(
160 |         self,
161 |         resp,
162 |         req,
163 |         stream=False,
164 |         timeout=None,
165 |         verify=True,
166 |         cert=None,
167 |         proxies=None,
168 |         yield_requests=False,
169 |         **adapter_kwargs,
170 |     ):
171 |         """Receives a Response. Returns a generator of Responses or Requests."""
172 | 
173 |         hist = []  # keep track of history
174 | 
175 |         url = self.get_redirect_target(resp)
176 |         previous_fragment = urlparse(req.url).fragment
177 |         while url:
178 |             prepared_request = req.copy()
179 | 
180 |             # Update history and keep track of redirects.
181 |             # resp.history must ignore the original request in this loop
182 |             hist.append(resp)
183 |             resp.history = hist[1:]
184 | 
185 |             try:
186 |                 resp.content  # Consume socket so it can be released
187 |             except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
188 |                 resp.raw.read(decode_content=False)
189 | 
190 |             if len(resp.history) >= self.max_redirects:
191 |                 raise TooManyRedirects(
192 |                     f"Exceeded {self.max_redirects} redirects.", response=resp
193 |                 )
194 | 
195 |             # Release the connection back into the pool.
196 |             resp.close()
197 | 
198 |             # Handle redirection without scheme (see: RFC 1808 Section 4)
199 |             if url.startswith("//"):
200 |                 parsed_rurl = urlparse(resp.url)
201 |                 url = ":".join([to_native_string(parsed_rurl.scheme), url])
202 | 
203 |             # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
204 |             parsed = urlparse(url)
205 |             if parsed.fragment == "" and previous_fragment:
206 |                 parsed = parsed._replace(fragment=previous_fragment)
207 |             elif parsed.fragment:
208 |                 previous_fragment = parsed.fragment
209 |             url = parsed.geturl()
210 | 
211 |             # Facilitate relative 'location' headers, as allowed by RFC 7231.
212 |             # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
213 |             # Compliant with RFC3986, we percent encode the url.
214 |             if not parsed.netloc:
215 |                 url = urljoin(resp.url, requote_uri(url))
216 |             else:
217 |                 url = requote_uri(url)
218 | 
219 |             prepared_request.url = to_native_string(url)
220 | 
221 |             self.rebuild_method(prepared_request, resp)
222 | 
223 |             # https://github.com/psf/requests/issues/1084
224 |             if resp.status_code not in (
225 |                 codes.temporary_redirect,
226 |                 codes.permanent_redirect,
227 |             ):
228 |                 # https://github.com/psf/requests/issues/3490
229 |                 purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding")
230 |                 for header in purged_headers:
231 |                     prepared_request.headers.pop(header, None)
232 |                 prepared_request.body = None
233 | 
234 |             headers = prepared_request.headers
235 |             headers.pop("Cookie", None)
236 | 
237 |             # Extract any cookies sent on the response to the cookiejar
238 |             # in the new request. Because we've mutated our copied prepared
239 |             # request, use the old one that we haven't yet touched.
240 |             extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)
241 |             merge_cookies(prepared_request._cookies, self.cookies)
242 |             prepared_request.prepare_cookies(prepared_request._cookies)
243 | 
244 |             # Rebuild auth and proxy information.
245 |             proxies = self.rebuild_proxies(prepared_request, proxies)
246 |             self.rebuild_auth(prepared_request, resp)
247 | 
248 |             # A failed tell() sets `_body_position` to `object()`. This non-None
249 |             # value ensures `rewindable` will be True, allowing us to raise an
250 |             # UnrewindableBodyError, instead of hanging the connection.
251 |             rewindable = prepared_request._body_position is not None and (
252 |                 "Content-Length" in headers or "Transfer-Encoding" in headers
253 |             )
254 | 
255 |             # Attempt to rewind consumed file-like object.
256 |             if rewindable:
257 |                 rewind_body(prepared_request)
258 | 
259 |             # Override the original request.
260 |             req = prepared_request
261 | 
262 |             if yield_requests:
263 |                 yield req
264 |             else:
265 |                 resp = self.send(
266 |                     req,
267 |                     stream=stream,
268 |                     timeout=timeout,
269 |                     verify=verify,
270 |                     cert=cert,
271 |                     proxies=proxies,
272 |                     allow_redirects=False,
273 |                     **adapter_kwargs,
274 |                 )
275 | 
276 |                 extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
277 | 
278 |                 # extract redirect url, if any, for the next loop
279 |                 url = self.get_redirect_target(resp)
280 |                 yield resp
281 | 
282 |     def rebuild_auth(self, prepared_request, response):
283 |         """When being redirected we may want to strip authentication from the
284 |         request to avoid leaking credentials. This method intelligently removes
285 |         and reapplies authentication where possible to avoid credential loss.
286 |         """
287 |         headers = prepared_request.headers
288 |         url = prepared_request.url
289 | 
290 |         if "Authorization" in headers and self.should_strip_auth(
291 |             response.request.url, url
292 |         ):
293 |             # If we get redirected to a new host, we should strip out any
294 |             # authentication headers.
295 |             del headers["Authorization"]
296 | 
297 |         # .netrc might have more auth for us on our new host.
298 |         new_auth = get_netrc_auth(url) if self.trust_env else None
299 |         if new_auth is not None:
300 |             prepared_request.prepare_auth(new_auth)
301 | 
302 |     def rebuild_proxies(self, prepared_request, proxies):
303 |         """This method re-evaluates the proxy configuration by considering the
304 |         environment variables. If we are redirected to a URL covered by
305 |         NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
306 |         proxy keys for this URL (in case they were stripped by a previous
307 |         redirect).
308 | 
309 |         This method also replaces the Proxy-Authorization header where
310 |         necessary.
311 | 
312 |         :rtype: dict
313 |         """
314 |         headers = prepared_request.headers
315 |         scheme = urlparse(prepared_request.url).scheme
316 |         new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
317 | 
318 |         if "Proxy-Authorization" in headers:
319 |             del headers["Proxy-Authorization"]
320 | 
321 |         try:
322 |             username, password = get_auth_from_url(new_proxies[scheme])
323 |         except KeyError:
324 |             username, password = None, None
325 | 
326 |         # urllib3 handles proxy authorization for us in the standard adapter.
327 |         # Avoid appending this to TLS tunneled requests where it may be leaked.
328 |         if not scheme.startswith("https") and username and password:
329 |             headers["Proxy-Authorization"] = _basic_auth_str(username, password)
330 | 
331 |         return new_proxies
332 | 
333 |     def rebuild_method(self, prepared_request, response):
334 |         """When being redirected we may want to change the method of the request
335 |         based on certain specs or browser behavior.
336 |         """
337 |         method = prepared_request.method
338 | 
339 |         # https://tools.ietf.org/html/rfc7231#section-6.4.4
340 |         if response.status_code == codes.see_other and method != "HEAD":
341 |             method = "GET"
342 | 
343 |         # Do what the browsers do, despite standards...
344 |         # First, turn 302s into GETs.
345 |         if response.status_code == codes.found and method != "HEAD":
346 |             method = "GET"
347 | 
348 |         # Second, if a POST is responded to with a 301, turn it into a GET.
349 |         # This bizarre behaviour is explained in Issue 1704.
350 |         if response.status_code == codes.moved and method == "POST":
351 |             method = "GET"
352 | 
353 |         prepared_request.method = method
354 | 
355 | 
356 | class Session(SessionRedirectMixin):
357 |     """A Requests session.
358 | 
359 |     Provides cookie persistence, connection-pooling, and configuration.
360 | 
361 |     Basic Usage::
362 | 
363 |       >>> import requests
364 |       >>> s = requests.Session()
365 |       >>> s.get('https://httpbin.org/get')
366 |       <Response [200]>
367 | 
368 |     Or as a context manager::
369 | 
370 |       >>> with requests.Session() as s:
371 |       ...     s.get('https://httpbin.org/get')
372 |       <Response [200]>
373 |     """
374 | 
375 |     __attrs__ = [
376 |         "headers",
377 |         "cookies",
378 |         "auth",
379 |         "proxies",
380 |         "hooks",
381 |         "params",
382 |         "verify",
383 |         "cert",
384 |         "adapters",
385 |         "stream",
386 |         "trust_env",
387 |         "max_redirects",
388 |     ]
389 | 
390 |     def __init__(self):
391 |         #: A case-insensitive dictionary of headers to be sent on each
392 |         #: :class:`Request <Request>` sent from this
393 |         #: :class:`Session <Session>`.
394 |         self.headers = default_headers()
395 | 
396 |         #: Default Authentication tuple or object to attach to
397 |         #: :class:`Request <Request>`.
398 |         self.auth = None
399 | 
400 |         #: Dictionary mapping protocol or protocol and host to the URL of the proxy
401 |         #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
402 |         #: be used on each :class:`Request <Request>`.
403 |         self.proxies = {}
404 | 
405 |         #: Event-handling hooks.
406 |         self.hooks = default_hooks()
407 | 
408 |         #: Dictionary of querystring data to attach to each
409 |         #: :class:`Request <Request>`. The dictionary values may be lists for
410 |         #: representing multivalued query parameters.
411 |         self.params = {}
412 | 
413 |         #: Stream response content default.
414 |         self.stream = False
415 | 
416 |         #: SSL Verification default.
417 |         #: Defaults to `True`, requiring requests to verify the TLS certificate at the
418 |         #: remote end.
419 |         #: If verify is set to `False`, requests will accept any TLS certificate
420 |         #: presented by the server, and will ignore hostname mismatches and/or
421 |         #: expired certificates, which will make your application vulnerable to
422 |         #: man-in-the-middle (MitM) attacks.
423 |         #: Only set this to `False` for testing.
424 |         self.verify = True
425 | 
426 |         #: SSL client certificate default, if String, path to ssl client
427 |         #: cert file (.pem). If Tuple, ('cert', 'key') pair.
428 |         self.cert = None
429 | 
430 |         #: Maximum number of redirects allowed. If the request exceeds this
431 |         #: limit, a :class:`TooManyRedirects` exception is raised.
432 |         #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
433 |         #: 30.
434 |         self.max_redirects = DEFAULT_REDIRECT_LIMIT
435 | 
436 |         #: Trust environment settings for proxy configuration, default
437 |         #: authentication and similar.
438 |         self.trust_env = True
439 | 
440 |         #: A CookieJar containing all currently outstanding cookies set on this
441 |         #: session. By default it is a
442 |         #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but
443 |         #: may be any other ``cookielib.CookieJar`` compatible object.
444 |         self.cookies = cookiejar_from_dict({})
445 | 
446 |         # Default connection adapters.
447 |         self.adapters = OrderedDict()
448 |         self.mount("https://", HTTPAdapter())
449 |         self.mount("http://", HTTPAdapter())
450 | 
451 |     def __enter__(self):
452 |         return self
453 | 
454 |     def __exit__(self, *args):
455 |         self.close()
456 | 
457 |     def prepare_request(self, request):
458 |         """Constructs a :class:`PreparedRequest <PreparedRequest>` for
459 |         transmission and returns it. The :class:`PreparedRequest` has settings
460 |         merged from the :class:`Request <Request>` instance and those of the
461 |         :class:`Session`.
462 | 
463 |         :param request: :class:`Request` instance to prepare with this
464 |             session's settings.
465 |         :rtype: requests.PreparedRequest
466 |         """
467 |         cookies = request.cookies or {}
468 | 
469 |         # Bootstrap CookieJar.
470 |         if not isinstance(cookies, cookielib.CookieJar):
471 |             cookies = cookiejar_from_dict(cookies)
472 | 
473 |         # Merge with session cookies
474 |         merged_cookies = merge_cookies(
475 |             merge_cookies(RequestsCookieJar(), self.cookies), cookies
476 |         )
477 | 
478 |         # Set environment's basic authentication if not explicitly set.
479 |         auth = request.auth
480 |         if self.trust_env and not auth and not self.auth:
481 |             auth = get_netrc_auth(request.url)
482 | 
483 |         p = PreparedRequest()
484 |         p.prepare(
485 |             method=request.method.upper(),
486 |             url=request.url,
487 |             files=request.files,
488 |             data=request.data,
489 |             json=request.json,
490 |             headers=merge_setting(
491 |                 request.headers, self.headers, dict_class=CaseInsensitiveDict
492 |             ),
493 |             params=merge_setting(request.params, self.params),
494 |             auth=merge_setting(auth, self.auth),
495 |             cookies=merged_cookies,
496 |             hooks=merge_hooks(request.hooks, self.hooks),
497 |         )
498 |         return p
499 | 
500 |     def request(
501 |         self,
502 |         method,
503 |         url,
504 |         params=None,
505 |         data=None,
506 |         headers=None,
507 |         cookies=None,
508 |         files=None,
509 |         auth=None,
510 |         timeout=None,
511 |         allow_redirects=True,
512 |         proxies=None,
513 |         hooks=None,
514 |         stream=None,
515 |         verify=None,
516 |         cert=None,
517 |         json=None,
518 |     ):
519 |         """Constructs a :class:`Request <Request>`, prepares it and sends it.
520 |         Returns :class:`Response <Response>` object.
521 | 
522 |         :param method: method for the new :class:`Request` object.
523 |         :param url: URL for the new :class:`Request` object.
524 |         :param params: (optional) Dictionary or bytes to be sent in the query
525 |             string for the :class:`Request`.
526 |         :param data: (optional) Dictionary, list of tuples, bytes, or file-like
527 |             object to send in the body of the :class:`Request`.
528 |         :param json: (optional) json to send in the body of the
529 |             :class:`Request`.
530 |         :param headers: (optional) Dictionary of HTTP Headers to send with the
531 |             :class:`Request`.
532 |         :param cookies: (optional) Dict or CookieJar object to send with the
533 |             :class:`Request`.
534 |         :param files: (optional) Dictionary of ``'filename': file-like-objects``
535 |             for multipart encoding upload.
536 |         :param auth: (optional) Auth tuple or callable to enable
537 |             Basic/Digest/Custom HTTP Auth.
538 |         :param timeout: (optional) How long to wait for the server to send
539 |             data before giving up, as a float, or a :ref:`(connect timeout,
540 |             read timeout) <timeouts>` tuple.
541 |         :type timeout: float or tuple
542 |         :param allow_redirects: (optional) Set to True by default.
543 |         :type allow_redirects: bool
544 |         :param proxies: (optional) Dictionary mapping protocol or protocol and
545 |             hostname to the URL of the proxy.
546 |         :param hooks: (optional) Dictionary mapping hook name to one event or
547 |             list of events, event must be callable.
548 |         :param stream: (optional) whether to immediately download the response
549 |             content. Defaults to ``False``.
550 |         :param verify: (optional) Either a boolean, in which case it controls whether we verify
551 |             the server's TLS certificate, or a string, in which case it must be a path
552 |             to a CA bundle to use. Defaults to ``True``. When set to
553 |             ``False``, requests will accept any TLS certificate presented by
554 |             the server, and will ignore hostname mismatches and/or expired
555 |             certificates, which will make your application vulnerable to
556 |             man-in-the-middle (MitM) attacks. Setting verify to ``False``
557 |             may be useful during local development or testing.
558 |         :param cert: (optional) if String, path to ssl client cert file (.pem).
559 |             If Tuple, ('cert', 'key') pair.
560 |         :rtype: requests.Response
561 |         """
562 |         # Create the Request.
563 |         req = Request(
564 |             method=method.upper(),
565 |             url=url,
566 |             headers=headers,
567 |             files=files,
568 |             data=data or {},
569 |             json=json,
570 |             params=params or {},
571 |             auth=auth,
572 |             cookies=cookies,
573 |             hooks=hooks,
574 |         )
575 |         prep = self.prepare_request(req)
576 | 
577 |         proxies = proxies or {}
578 | 
579 |         settings = self.merge_environment_settings(
580 |             prep.url, proxies, stream, verify, cert
581 |         )
582 | 
583 |         # Send the request.
584 |         send_kwargs = {
585 |             "timeout": timeout,
586 |             "allow_redirects": allow_redirects,
587 |         }
588 |         send_kwargs.update(settings)
589 |         resp = self.send(prep, **send_kwargs)
590 | 
591 |         return resp
592 | 
593 |     def get(self, url, **kwargs):
594 |         r"""Sends a GET request. Returns :class:`Response` object.
595 | 
596 |         :param url: URL for the new :class:`Request` object.
597 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
598 |         :rtype: requests.Response
599 |         """
600 | 
601 |         kwargs.setdefault("allow_redirects", True)
602 |         return self.request("GET", url, **kwargs)
603 | 
604 |     def options(self, url, **kwargs):
605 |         r"""Sends a OPTIONS request. Returns :class:`Response` object.
606 | 
607 |         :param url: URL for the new :class:`Request` object.
608 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
609 |         :rtype: requests.Response
610 |         """
611 | 
612 |         kwargs.setdefault("allow_redirects", True)
613 |         return self.request("OPTIONS", url, **kwargs)
614 | 
615 |     def head(self, url, **kwargs):
616 |         r"""Sends a HEAD request. Returns :class:`Response` object.
617 | 
618 |         :param url: URL for the new :class:`Request` object.
619 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
620 |         :rtype: requests.Response
621 |         """
622 | 
623 |         kwargs.setdefault("allow_redirects", False)
624 |         return self.request("HEAD", url, **kwargs)
625 | 
626 |     def post(self, url, data=None, json=None, **kwargs):
627 |         r"""Sends a POST request. Returns :class:`Response` object.
628 | 
629 |         :param url: URL for the new :class:`Request` object.
630 |         :param data: (optional) Dictionary, list of tuples, bytes, or file-like
631 |             object to send in the body of the :class:`Request`.
632 |         :param json: (optional) json to send in the body of the :class:`Request`.
633 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
634 |         :rtype: requests.Response
635 |         """
636 | 
637 |         return self.request("POST", url, data=data, json=json, **kwargs)
638 | 
639 |     def put(self, url, data=None, **kwargs):
640 |         r"""Sends a PUT request. Returns :class:`Response` object.
641 | 
642 |         :param url: URL for the new :class:`Request` object.
643 |         :param data: (optional) Dictionary, list of tuples, bytes, or file-like
644 |             object to send in the body of the :class:`Request`.
645 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
646 |         :rtype: requests.Response
647 |         """
648 | 
649 |         return self.request("PUT", url, data=data, **kwargs)
650 | 
651 |     def patch(self, url, data=None, **kwargs):
652 |         r"""Sends a PATCH request. Returns :class:`Response` object.
653 | 
654 |         :param url: URL for the new :class:`Request` object.
655 |         :param data: (optional) Dictionary, list of tuples, bytes, or file-like
656 |             object to send in the body of the :class:`Request`.
657 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
658 |         :rtype: requests.Response
659 |         """
660 | 
661 |         return self.request("PATCH", url, data=data, **kwargs)
662 | 
663 |     def delete(self, url, **kwargs):
664 |         r"""Sends a DELETE request. Returns :class:`Response` object.
665 | 
666 |         :param url: URL for the new :class:`Request` object.
667 |         :param \*\*kwargs: Optional arguments that ``request`` takes.
668 |         :rtype: requests.Response
669 |         """
670 | 
671 |         return self.request("DELETE", url, **kwargs)
672 | 
673 |     def send(self, request, **kwargs):
674 |         """Send a given PreparedRequest.
675 | 
676 |         :rtype: requests.Response
677 |         """
678 |         # Set defaults that the hooks can utilize to ensure they always have
679 |         # the correct parameters to reproduce the previous request.
680 |         kwargs.setdefault("stream", self.stream)
681 |         kwargs.setdefault("verify", self.verify)
682 |         kwargs.setdefault("cert", self.cert)
683 |         if "proxies" not in kwargs:
684 |             kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
685 | 
686 |         # It's possible that users might accidentally send a Request object.
687 |         # Guard against that specific failure case.
688 |         if isinstance(request, Request):
689 |             raise ValueError("You can only send PreparedRequests.")
690 | 
691 |         # Set up variables needed for resolve_redirects and dispatching of hooks
692 |         allow_redirects = kwargs.pop("allow_redirects", True)
693 |         stream = kwargs.get("stream")
694 |         hooks = request.hooks
695 | 
696 |         # Get the appropriate adapter to use
697 |         adapter = self.get_adapter(url=request.url)
698 | 
699 |         # Start time (approximately) of the request
700 |         start = preferred_clock()
701 | 
702 |         # Send the request
703 |         r = adapter.send(request, **kwargs)
704 | 
705 |         # Total elapsed time of the request (approximately)
706 |         elapsed = preferred_clock() - start
707 |         r.elapsed = timedelta(seconds=elapsed)
708 | 
709 |         # Response manipulation hooks
710 |         r = dispatch_hook("response", hooks, r, **kwargs)
711 | 
712 |         # Persist cookies
713 |         if r.history:
714 |             # If the hooks create history then we want those cookies too
715 |             for resp in r.history:
716 |                 extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
717 | 
718 |         extract_cookies_to_jar(self.cookies, request, r.raw)
719 | 
720 |         # Resolve redirects if allowed.
721 |         if allow_redirects:
722 |             # Redirect resolving generator.
723 |             gen = self.resolve_redirects(r, request, **kwargs)
724 |             history = [resp for resp in gen]
725 |         else:
726 |             history = []
727 | 
728 |         # Shuffle things around if there's history.
729 |         if history:
730 |             # Insert the first (original) request at the start
731 |             history.insert(0, r)
732 |             # Get the last request made
733 |             r = history.pop()
734 |             r.history = history
735 | 
736 |         # If redirects aren't being followed, store the response on the Request for Response.next().
737 |         if not allow_redirects:
738 |             try:
739 |                 r._next = next(
740 |                     self.resolve_redirects(r, request, yield_requests=True, **kwargs)
741 |                 )
742 |             except StopIteration:
743 |                 pass
744 | 
745 |         if not stream:
746 |             r.content
747 | 
748 |         return r
749 | 
750 |     def merge_environment_settings(self, url, proxies, stream, verify, cert):
751 |         """
752 |         Check the environment and merge it with some settings.
753 | 
754 |         :rtype: dict
755 |         """
756 |         # Gather clues from the surrounding environment.
757 |         if self.trust_env:
758 |             # Set environment's proxies.
759 |             no_proxy = proxies.get("no_proxy") if proxies is not None else None
760 |             env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
761 |             for k, v in env_proxies.items():
762 |                 proxies.setdefault(k, v)
763 | 
764 |             # Look for requests environment configuration
765 |             # and be compatible with cURL.
766 |             if verify is True or verify is None:
767 |                 verify = (
768 |                     os.environ.get("REQUESTS_CA_BUNDLE")
769 |                     or os.environ.get("CURL_CA_BUNDLE")
770 |                     or verify
771 |                 )
772 | 
773 |         # Merge all the kwargs.
774 |         proxies = merge_setting(proxies, self.proxies)
775 |         stream = merge_setting(stream, self.stream)
776 |         verify = merge_setting(verify, self.verify)
777 |         cert = merge_setting(cert, self.cert)
778 | 
779 |         return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
780 | 
781 |     def get_adapter(self, url):
782 |         """
783 |         Returns the appropriate connection adapter for the given URL.
784 | 
785 |         :rtype: requests.adapters.BaseAdapter
786 |         """
787 |         for prefix, adapter in self.adapters.items():
788 |             if url.lower().startswith(prefix.lower()):
789 |                 return adapter
790 | 
791 |         # Nothing matches :-/
792 |         raise InvalidSchema(f"No connection adapters were found for {url!r}")
793 | 
794 |     def close(self):
795 |         """Closes all adapters and as such the session"""
796 |         for v in self.adapters.values():
797 |             v.close()
798 | 
799 |     def mount(self, prefix, adapter):
800 |         """Registers a connection adapter to a prefix.
801 | 
802 |         Adapters are sorted in descending order by prefix length.
803 |         """
804 |         self.adapters[prefix] = adapter
805 |         keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
806 | 
807 |         for key in keys_to_move:
808 |             self.adapters[key] = self.adapters.pop(key)
809 | 
810 |     def __getstate__(self):
811 |         state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
812 |         return state
813 | 
814 |     def __setstate__(self, state):
815 |         for attr, value in state.items():
816 |             setattr(self, attr, value)
817 | 
818 | 
819 | def session():
820 |     """
821 |     Returns a :class:`Session` for context-management.
822 | 
823 |     .. deprecated:: 1.0.0
824 | 
825 |         This method has been deprecated since version 1.0.0 and is only kept for
826 |         backwards compatibility. New code should use :class:`~requests.sessions.Session`
827 |         to create a session. This may be removed at a future date.
828 | 
829 |     :rtype: Session
830 |     """
831 |     return Session()
832 | 
```
Page 93/168FirstPrevNextLast