This is page 29 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .venv
│ ├── __pycache__
│ │ └── hello.cpython-312.pyc
│ ├── bin
│ │ ├── activate
│ │ ├── activate.csh
│ │ ├── activate.fish
│ │ ├── Activate.ps1
│ │ ├── flask
│ │ ├── normalizer
│ │ ├── pip
│ │ ├── pip3
│ │ ├── pip3.12
│ │ ├── python
│ │ ├── python3
│ │ └── python3.12
│ ├── hello.py
│ ├── lib
│ │ └── python3.12
│ │ └── site-packages
│ │ ├── beautifulsoup4-4.12.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ ├── AUTHORS
│ │ │ │ └── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── blinker
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _utilities.cpython-312.pyc
│ │ │ │ └── base.cpython-312.pyc
│ │ │ ├── _utilities.py
│ │ │ ├── base.py
│ │ │ └── py.typed
│ │ ├── blinker-1.8.2.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── bs4
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── css.cpython-312.pyc
│ │ │ │ ├── dammit.cpython-312.pyc
│ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ ├── element.cpython-312.pyc
│ │ │ │ └── formatter.cpython-312.pyc
│ │ │ ├── builder
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _html5lib.cpython-312.pyc
│ │ │ │ │ ├── _htmlparser.cpython-312.pyc
│ │ │ │ │ └── _lxml.cpython-312.pyc
│ │ │ │ ├── _html5lib.py
│ │ │ │ ├── _htmlparser.py
│ │ │ │ └── _lxml.py
│ │ │ ├── css.py
│ │ │ ├── dammit.py
│ │ │ ├── diagnose.py
│ │ │ ├── element.py
│ │ │ ├── formatter.py
│ │ │ └── tests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── test_builder_registry.cpython-312.pyc
│ │ │ │ ├── test_builder.cpython-312.pyc
│ │ │ │ ├── test_css.cpython-312.pyc
│ │ │ │ ├── test_dammit.cpython-312.pyc
│ │ │ │ ├── test_docs.cpython-312.pyc
│ │ │ │ ├── test_element.cpython-312.pyc
│ │ │ │ ├── test_formatter.cpython-312.pyc
│ │ │ │ ├── test_fuzz.cpython-312.pyc
│ │ │ │ ├── test_html5lib.cpython-312.pyc
│ │ │ │ ├── test_htmlparser.cpython-312.pyc
│ │ │ │ ├── test_lxml.cpython-312.pyc
│ │ │ │ ├── test_navigablestring.cpython-312.pyc
│ │ │ │ ├── test_pageelement.cpython-312.pyc
│ │ │ │ ├── test_soup.cpython-312.pyc
│ │ │ │ ├── test_tag.cpython-312.pyc
│ │ │ │ └── test_tree.cpython-312.pyc
│ │ │ ├── fuzz
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│ │ │ │ ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│ │ │ │ ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│ │ │ │ └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│ │ │ ├── test_builder_registry.py
│ │ │ ├── test_builder.py
│ │ │ ├── test_css.py
│ │ │ ├── test_dammit.py
│ │ │ ├── test_docs.py
│ │ │ ├── test_element.py
│ │ │ ├── test_formatter.py
│ │ │ ├── test_fuzz.py
│ │ │ ├── test_html5lib.py
│ │ │ ├── test_htmlparser.py
│ │ │ ├── test_lxml.py
│ │ │ ├── test_navigablestring.py
│ │ │ ├── test_pageelement.py
│ │ │ ├── test_soup.py
│ │ │ ├── test_tag.py
│ │ │ └── test_tree.py
│ │ ├── certifi
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── core.cpython-312.pyc
│ │ │ ├── cacert.pem
│ │ │ ├── core.py
│ │ │ └── py.typed
│ │ ├── certifi-2024.8.30.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── charset_normalizer
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── cd.cpython-312.pyc
│ │ │ │ ├── constant.cpython-312.pyc
│ │ │ │ ├── legacy.cpython-312.pyc
│ │ │ │ ├── md.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── version.cpython-312.pyc
│ │ │ ├── api.py
│ │ │ ├── cd.py
│ │ │ ├── cli
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── __main__.cpython-312.pyc
│ │ │ ├── constant.py
│ │ │ ├── legacy.py
│ │ │ ├── md__mypyc.cpython-312-darwin.so
│ │ │ ├── md.cpython-312-darwin.so
│ │ │ ├── md.py
│ │ │ ├── models.py
│ │ │ ├── py.typed
│ │ │ ├── utils.py
│ │ │ └── version.py
│ │ ├── charset_normalizer-3.4.0.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── click
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ ├── _termui_impl.cpython-312.pyc
│ │ │ │ ├── _textwrap.cpython-312.pyc
│ │ │ │ ├── _winconsole.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── decorators.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formatting.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── shell_completion.cpython-312.pyc
│ │ │ │ ├── termui.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── types.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── _compat.py
│ │ │ ├── _termui_impl.py
│ │ │ ├── _textwrap.py
│ │ │ ├── _winconsole.py
│ │ │ ├── core.py
│ │ │ ├── decorators.py
│ │ │ ├── exceptions.py
│ │ │ ├── formatting.py
│ │ │ ├── globals.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── shell_completion.py
│ │ │ ├── termui.py
│ │ │ ├── testing.py
│ │ │ ├── types.py
│ │ │ └── utils.py
│ │ ├── click-8.1.7.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.rst
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── fake_useragent
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ ├── fake.cpython-312.pyc
│ │ │ │ ├── log.cpython-312.pyc
│ │ │ │ ├── settings.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── data
│ │ │ │ └── browsers.json
│ │ │ ├── errors.py
│ │ │ ├── fake.py
│ │ │ ├── log.py
│ │ │ ├── settings.py
│ │ │ └── utils.py
│ │ ├── fake_useragent-1.5.1.dist-info
│ │ │ ├── AUTHORS
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── flask
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ ├── cli.cpython-312.pyc
│ │ │ │ ├── config.cpython-312.pyc
│ │ │ │ ├── ctx.cpython-312.pyc
│ │ │ │ ├── debughelpers.cpython-312.pyc
│ │ │ │ ├── globals.cpython-312.pyc
│ │ │ │ ├── helpers.cpython-312.pyc
│ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── signals.cpython-312.pyc
│ │ │ │ ├── templating.cpython-312.pyc
│ │ │ │ ├── testing.cpython-312.pyc
│ │ │ │ ├── typing.cpython-312.pyc
│ │ │ │ ├── views.cpython-312.pyc
│ │ │ │ └── wrappers.cpython-312.pyc
│ │ │ ├── app.py
│ │ │ ├── blueprints.py
│ │ │ ├── cli.py
│ │ │ ├── config.py
│ │ │ ├── ctx.py
│ │ │ ├── debughelpers.py
│ │ │ ├── globals.py
│ │ │ ├── helpers.py
│ │ │ ├── json
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ └── tag.cpython-312.pyc
│ │ │ │ ├── provider.py
│ │ │ │ └── tag.py
│ │ │ ├── logging.py
│ │ │ ├── py.typed
│ │ │ ├── sansio
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── app.cpython-312.pyc
│ │ │ │ │ ├── blueprints.cpython-312.pyc
│ │ │ │ │ └── scaffold.cpython-312.pyc
│ │ │ │ ├── app.py
│ │ │ │ ├── blueprints.py
│ │ │ │ ├── README.md
│ │ │ │ └── scaffold.py
│ │ │ ├── sessions.py
│ │ │ ├── signals.py
│ │ │ ├── templating.py
│ │ │ ├── testing.py
│ │ │ ├── typing.py
│ │ │ ├── views.py
│ │ │ └── wrappers.py
│ │ ├── flask-3.0.3.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ └── WHEEL
│ │ ├── idna
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ ├── codec.py
│ │ │ ├── compat.py
│ │ │ ├── core.py
│ │ │ ├── idnadata.py
│ │ │ ├── intranges.py
│ │ │ ├── package_data.py
│ │ │ ├── py.typed
│ │ │ └── uts46data.py
│ │ ├── idna-3.10.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── itsdangerous
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ ├── exc.cpython-312.pyc
│ │ │ │ ├── serializer.cpython-312.pyc
│ │ │ │ ├── signer.cpython-312.pyc
│ │ │ │ ├── timed.cpython-312.pyc
│ │ │ │ └── url_safe.cpython-312.pyc
│ │ │ ├── _json.py
│ │ │ ├── encoding.py
│ │ │ ├── exc.py
│ │ │ ├── py.typed
│ │ │ ├── serializer.py
│ │ │ ├── signer.py
│ │ │ ├── timed.py
│ │ │ └── url_safe.py
│ │ ├── itsdangerous-2.2.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── jinja2
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _identifier.cpython-312.pyc
│ │ │ │ ├── async_utils.cpython-312.pyc
│ │ │ │ ├── bccache.cpython-312.pyc
│ │ │ │ ├── compiler.cpython-312.pyc
│ │ │ │ ├── constants.cpython-312.pyc
│ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ ├── defaults.cpython-312.pyc
│ │ │ │ ├── environment.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ ├── filters.cpython-312.pyc
│ │ │ │ ├── idtracking.cpython-312.pyc
│ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ ├── loaders.cpython-312.pyc
│ │ │ │ ├── meta.cpython-312.pyc
│ │ │ │ ├── nativetypes.cpython-312.pyc
│ │ │ │ ├── nodes.cpython-312.pyc
│ │ │ │ ├── optimizer.cpython-312.pyc
│ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ ├── runtime.cpython-312.pyc
│ │ │ │ ├── sandbox.cpython-312.pyc
│ │ │ │ ├── tests.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── visitor.cpython-312.pyc
│ │ │ ├── _identifier.py
│ │ │ ├── async_utils.py
│ │ │ ├── bccache.py
│ │ │ ├── compiler.py
│ │ │ ├── constants.py
│ │ │ ├── debug.py
│ │ │ ├── defaults.py
│ │ │ ├── environment.py
│ │ │ ├── exceptions.py
│ │ │ ├── ext.py
│ │ │ ├── filters.py
│ │ │ ├── idtracking.py
│ │ │ ├── lexer.py
│ │ │ ├── loaders.py
│ │ │ ├── meta.py
│ │ │ ├── nativetypes.py
│ │ │ ├── nodes.py
│ │ │ ├── optimizer.py
│ │ │ ├── parser.py
│ │ │ ├── py.typed
│ │ │ ├── runtime.py
│ │ │ ├── sandbox.py
│ │ │ ├── tests.py
│ │ │ ├── utils.py
│ │ │ └── visitor.py
│ │ ├── jinja2-3.1.4.dist-info
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── lxml
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _elementpath.cpython-312.pyc
│ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ ├── cssselect.cpython-312.pyc
│ │ │ │ ├── doctestcompare.cpython-312.pyc
│ │ │ │ ├── ElementInclude.cpython-312.pyc
│ │ │ │ ├── pyclasslookup.cpython-312.pyc
│ │ │ │ ├── sax.cpython-312.pyc
│ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ ├── _elementpath.cpython-312-darwin.so
│ │ │ ├── _elementpath.py
│ │ │ ├── apihelpers.pxi
│ │ │ ├── builder.cpython-312-darwin.so
│ │ │ ├── builder.py
│ │ │ ├── classlookup.pxi
│ │ │ ├── cleanup.pxi
│ │ │ ├── cssselect.py
│ │ │ ├── debug.pxi
│ │ │ ├── docloader.pxi
│ │ │ ├── doctestcompare.py
│ │ │ ├── dtd.pxi
│ │ │ ├── ElementInclude.py
│ │ │ ├── etree_api.h
│ │ │ ├── etree.cpython-312-darwin.so
│ │ │ ├── etree.h
│ │ │ ├── etree.pyx
│ │ │ ├── extensions.pxi
│ │ │ ├── html
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── _diffcommand.cpython-312.pyc
│ │ │ │ │ ├── _html5builder.cpython-312.pyc
│ │ │ │ │ ├── _setmixin.cpython-312.pyc
│ │ │ │ │ ├── builder.cpython-312.pyc
│ │ │ │ │ ├── clean.cpython-312.pyc
│ │ │ │ │ ├── defs.cpython-312.pyc
│ │ │ │ │ ├── diff.cpython-312.pyc
│ │ │ │ │ ├── ElementSoup.cpython-312.pyc
│ │ │ │ │ ├── formfill.cpython-312.pyc
│ │ │ │ │ ├── html5parser.cpython-312.pyc
│ │ │ │ │ ├── soupparser.cpython-312.pyc
│ │ │ │ │ └── usedoctest.cpython-312.pyc
│ │ │ │ ├── _diffcommand.py
│ │ │ │ ├── _html5builder.py
│ │ │ │ ├── _setmixin.py
│ │ │ │ ├── builder.py
│ │ │ │ ├── clean.py
│ │ │ │ ├── defs.py
│ │ │ │ ├── diff.cpython-312-darwin.so
│ │ │ │ ├── diff.py
│ │ │ │ ├── ElementSoup.py
│ │ │ │ ├── formfill.py
│ │ │ │ ├── html5parser.py
│ │ │ │ ├── soupparser.py
│ │ │ │ └── usedoctest.py
│ │ │ ├── includes
│ │ │ │ ├── __init__.pxd
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── c14n.pxd
│ │ │ │ ├── config.pxd
│ │ │ │ ├── dtdvalid.pxd
│ │ │ │ ├── etree_defs.h
│ │ │ │ ├── etreepublic.pxd
│ │ │ │ ├── extlibs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── libcharset.h
│ │ │ │ │ ├── localcharset.h
│ │ │ │ │ ├── zconf.h
│ │ │ │ │ └── zlib.h
│ │ │ │ ├── htmlparser.pxd
│ │ │ │ ├── libexslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── exslt.h
│ │ │ │ │ ├── exsltconfig.h
│ │ │ │ │ └── exsltexports.h
│ │ │ │ ├── libxml
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── c14n.h
│ │ │ │ │ ├── catalog.h
│ │ │ │ │ ├── chvalid.h
│ │ │ │ │ ├── debugXML.h
│ │ │ │ │ ├── dict.h
│ │ │ │ │ ├── encoding.h
│ │ │ │ │ ├── entities.h
│ │ │ │ │ ├── globals.h
│ │ │ │ │ ├── hash.h
│ │ │ │ │ ├── HTMLparser.h
│ │ │ │ │ ├── HTMLtree.h
│ │ │ │ │ ├── list.h
│ │ │ │ │ ├── nanoftp.h
│ │ │ │ │ ├── nanohttp.h
│ │ │ │ │ ├── parser.h
│ │ │ │ │ ├── parserInternals.h
│ │ │ │ │ ├── relaxng.h
│ │ │ │ │ ├── SAX.h
│ │ │ │ │ ├── SAX2.h
│ │ │ │ │ ├── schemasInternals.h
│ │ │ │ │ ├── schematron.h
│ │ │ │ │ ├── threads.h
│ │ │ │ │ ├── tree.h
│ │ │ │ │ ├── uri.h
│ │ │ │ │ ├── valid.h
│ │ │ │ │ ├── xinclude.h
│ │ │ │ │ ├── xlink.h
│ │ │ │ │ ├── xmlautomata.h
│ │ │ │ │ ├── xmlerror.h
│ │ │ │ │ ├── xmlexports.h
│ │ │ │ │ ├── xmlIO.h
│ │ │ │ │ ├── xmlmemory.h
│ │ │ │ │ ├── xmlmodule.h
│ │ │ │ │ ├── xmlreader.h
│ │ │ │ │ ├── xmlregexp.h
│ │ │ │ │ ├── xmlsave.h
│ │ │ │ │ ├── xmlschemas.h
│ │ │ │ │ ├── xmlschemastypes.h
│ │ │ │ │ ├── xmlstring.h
│ │ │ │ │ ├── xmlunicode.h
│ │ │ │ │ ├── xmlversion.h
│ │ │ │ │ ├── xmlwriter.h
│ │ │ │ │ ├── xpath.h
│ │ │ │ │ ├── xpathInternals.h
│ │ │ │ │ └── xpointer.h
│ │ │ │ ├── libxslt
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── attributes.h
│ │ │ │ │ ├── documents.h
│ │ │ │ │ ├── extensions.h
│ │ │ │ │ ├── extra.h
│ │ │ │ │ ├── functions.h
│ │ │ │ │ ├── imports.h
│ │ │ │ │ ├── keys.h
│ │ │ │ │ ├── namespaces.h
│ │ │ │ │ ├── numbersInternals.h
│ │ │ │ │ ├── pattern.h
│ │ │ │ │ ├── preproc.h
│ │ │ │ │ ├── security.h
│ │ │ │ │ ├── templates.h
│ │ │ │ │ ├── transform.h
│ │ │ │ │ ├── variables.h
│ │ │ │ │ ├── xslt.h
│ │ │ │ │ ├── xsltconfig.h
│ │ │ │ │ ├── xsltexports.h
│ │ │ │ │ ├── xsltInternals.h
│ │ │ │ │ ├── xsltlocale.h
│ │ │ │ │ └── xsltutils.h
│ │ │ │ ├── lxml-version.h
│ │ │ │ ├── relaxng.pxd
│ │ │ │ ├── schematron.pxd
│ │ │ │ ├── tree.pxd
│ │ │ │ ├── uri.pxd
│ │ │ │ ├── xinclude.pxd
│ │ │ │ ├── xmlerror.pxd
│ │ │ │ ├── xmlparser.pxd
│ │ │ │ ├── xmlschema.pxd
│ │ │ │ ├── xpath.pxd
│ │ │ │ └── xslt.pxd
│ │ │ ├── isoschematron
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ └── resources
│ │ │ │ ├── rng
│ │ │ │ │ └── iso-schematron.rng
│ │ │ │ └── xsl
│ │ │ │ ├── iso-schematron-xslt1
│ │ │ │ │ ├── iso_abstract_expand.xsl
│ │ │ │ │ ├── iso_dsdl_include.xsl
│ │ │ │ │ ├── iso_schematron_message.xsl
│ │ │ │ │ ├── iso_schematron_skeleton_for_xslt1.xsl
│ │ │ │ │ ├── iso_svrl_for_xslt1.xsl
│ │ │ │ │ └── readme.txt
│ │ │ │ ├── RNG2Schtrn.xsl
│ │ │ │ └── XSD2Schtrn.xsl
│ │ │ ├── iterparse.pxi
│ │ │ ├── lxml.etree_api.h
│ │ │ ├── lxml.etree.h
│ │ │ ├── nsclasses.pxi
│ │ │ ├── objectify.cpython-312-darwin.so
│ │ │ ├── objectify.pyx
│ │ │ ├── objectpath.pxi
│ │ │ ├── parser.pxi
│ │ │ ├── parsertarget.pxi
│ │ │ ├── proxy.pxi
│ │ │ ├── public-api.pxi
│ │ │ ├── pyclasslookup.py
│ │ │ ├── readonlytree.pxi
│ │ │ ├── relaxng.pxi
│ │ │ ├── sax.cpython-312-darwin.so
│ │ │ ├── sax.py
│ │ │ ├── saxparser.pxi
│ │ │ ├── schematron.pxi
│ │ │ ├── serializer.pxi
│ │ │ ├── usedoctest.py
│ │ │ ├── xinclude.pxi
│ │ │ ├── xmlerror.pxi
│ │ │ ├── xmlid.pxi
│ │ │ ├── xmlschema.pxi
│ │ │ ├── xpath.pxi
│ │ │ ├── xslt.pxi
│ │ │ └── xsltext.pxi
│ │ ├── lxml-5.3.0.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── LICENSES.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── markupsafe
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ └── _native.cpython-312.pyc
│ │ │ ├── _native.py
│ │ │ ├── _speedups.c
│ │ │ ├── _speedups.cpython-312-darwin.so
│ │ │ ├── _speedups.pyi
│ │ │ └── py.typed
│ │ ├── MarkupSafe-3.0.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── pip
│ │ │ ├── __init__.py
│ │ │ ├── __main__.py
│ │ │ ├── __pip-runner__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ └── __pip-runner__.cpython-312.pyc
│ │ │ ├── _internal
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── build_env.cpython-312.pyc
│ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ ├── pyproject.cpython-312.pyc
│ │ │ │ │ ├── self_outdated_check.cpython-312.pyc
│ │ │ │ │ └── wheel_builder.cpython-312.pyc
│ │ │ │ ├── build_env.py
│ │ │ │ ├── cache.py
│ │ │ │ ├── cli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── autocompletion.cpython-312.pyc
│ │ │ │ │ │ ├── base_command.cpython-312.pyc
│ │ │ │ │ │ ├── cmdoptions.cpython-312.pyc
│ │ │ │ │ │ ├── command_context.cpython-312.pyc
│ │ │ │ │ │ ├── index_command.cpython-312.pyc
│ │ │ │ │ │ ├── main_parser.cpython-312.pyc
│ │ │ │ │ │ ├── main.cpython-312.pyc
│ │ │ │ │ │ ├── parser.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bars.cpython-312.pyc
│ │ │ │ │ │ ├── req_command.cpython-312.pyc
│ │ │ │ │ │ ├── spinners.cpython-312.pyc
│ │ │ │ │ │ └── status_codes.cpython-312.pyc
│ │ │ │ │ ├── autocompletion.py
│ │ │ │ │ ├── base_command.py
│ │ │ │ │ ├── cmdoptions.py
│ │ │ │ │ ├── command_context.py
│ │ │ │ │ ├── index_command.py
│ │ │ │ │ ├── main_parser.py
│ │ │ │ │ ├── main.py
│ │ │ │ │ ├── parser.py
│ │ │ │ │ ├── progress_bars.py
│ │ │ │ │ ├── req_command.py
│ │ │ │ │ ├── spinners.py
│ │ │ │ │ └── status_codes.py
│ │ │ │ ├── commands
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── completion.cpython-312.pyc
│ │ │ │ │ │ ├── configuration.cpython-312.pyc
│ │ │ │ │ │ ├── debug.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ ├── hash.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── inspect.cpython-312.pyc
│ │ │ │ │ │ ├── install.cpython-312.pyc
│ │ │ │ │ │ ├── list.cpython-312.pyc
│ │ │ │ │ │ ├── search.cpython-312.pyc
│ │ │ │ │ │ ├── show.cpython-312.pyc
│ │ │ │ │ │ ├── uninstall.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── completion.py
│ │ │ │ │ ├── configuration.py
│ │ │ │ │ ├── debug.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── hash.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── inspect.py
│ │ │ │ │ ├── install.py
│ │ │ │ │ ├── list.py
│ │ │ │ │ ├── search.py
│ │ │ │ │ ├── show.py
│ │ │ │ │ ├── uninstall.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── configuration.py
│ │ │ │ ├── distributions
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── installed.cpython-312.pyc
│ │ │ │ │ │ ├── sdist.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── installed.py
│ │ │ │ │ ├── sdist.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── index
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── collector.cpython-312.pyc
│ │ │ │ │ │ ├── package_finder.cpython-312.pyc
│ │ │ │ │ │ └── sources.cpython-312.pyc
│ │ │ │ │ ├── collector.py
│ │ │ │ │ ├── package_finder.py
│ │ │ │ │ └── sources.py
│ │ │ │ ├── locations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _distutils.cpython-312.pyc
│ │ │ │ │ │ ├── _sysconfig.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── _distutils.py
│ │ │ │ │ ├── _sysconfig.py
│ │ │ │ │ └── base.py
│ │ │ │ ├── main.py
│ │ │ │ ├── metadata
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _json.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ └── pkg_resources.cpython-312.pyc
│ │ │ │ │ ├── _json.py
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── importlib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ │ ├── _dists.cpython-312.pyc
│ │ │ │ │ │ │ └── _envs.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.py
│ │ │ │ │ │ ├── _dists.py
│ │ │ │ │ │ └── _envs.py
│ │ │ │ │ └── pkg_resources.py
│ │ │ │ ├── models
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── candidate.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url.cpython-312.pyc
│ │ │ │ │ │ ├── format_control.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── installation_report.cpython-312.pyc
│ │ │ │ │ │ ├── link.cpython-312.pyc
│ │ │ │ │ │ ├── scheme.cpython-312.pyc
│ │ │ │ │ │ ├── search_scope.cpython-312.pyc
│ │ │ │ │ │ ├── selection_prefs.cpython-312.pyc
│ │ │ │ │ │ ├── target_python.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── candidate.py
│ │ │ │ │ ├── direct_url.py
│ │ │ │ │ ├── format_control.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── installation_report.py
│ │ │ │ │ ├── link.py
│ │ │ │ │ ├── scheme.py
│ │ │ │ │ ├── search_scope.py
│ │ │ │ │ ├── selection_prefs.py
│ │ │ │ │ ├── target_python.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── network
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── download.cpython-312.pyc
│ │ │ │ │ │ ├── lazy_wheel.cpython-312.pyc
│ │ │ │ │ │ ├── session.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── xmlrpc.cpython-312.pyc
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── download.py
│ │ │ │ │ ├── lazy_wheel.py
│ │ │ │ │ ├── session.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── xmlrpc.py
│ │ │ │ ├── operations
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── check.cpython-312.pyc
│ │ │ │ │ │ ├── freeze.cpython-312.pyc
│ │ │ │ │ │ └── prepare.cpython-312.pyc
│ │ │ │ │ ├── build
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── build_tracker.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata_legacy.cpython-312.pyc
│ │ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_editable.cpython-312.pyc
│ │ │ │ │ │ │ ├── wheel_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── build_tracker.py
│ │ │ │ │ │ ├── metadata_editable.py
│ │ │ │ │ │ ├── metadata_legacy.py
│ │ │ │ │ │ ├── metadata.py
│ │ │ │ │ │ ├── wheel_editable.py
│ │ │ │ │ │ ├── wheel_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ ├── check.py
│ │ │ │ │ ├── freeze.py
│ │ │ │ │ ├── install
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── editable_legacy.cpython-312.pyc
│ │ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ │ ├── editable_legacy.py
│ │ │ │ │ │ └── wheel.py
│ │ │ │ │ └── prepare.py
│ │ │ │ ├── pyproject.py
│ │ │ │ ├── req
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── constructors.cpython-312.pyc
│ │ │ │ │ │ ├── req_file.cpython-312.pyc
│ │ │ │ │ │ ├── req_install.cpython-312.pyc
│ │ │ │ │ │ ├── req_set.cpython-312.pyc
│ │ │ │ │ │ └── req_uninstall.cpython-312.pyc
│ │ │ │ │ ├── constructors.py
│ │ │ │ │ ├── req_file.py
│ │ │ │ │ ├── req_install.py
│ │ │ │ │ ├── req_set.py
│ │ │ │ │ └── req_uninstall.py
│ │ │ │ ├── resolution
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── base.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── legacy
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ │ └── resolver.py
│ │ │ │ │ └── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── base.cpython-312.pyc
│ │ │ │ │ │ ├── candidates.cpython-312.pyc
│ │ │ │ │ │ ├── factory.cpython-312.pyc
│ │ │ │ │ │ ├── found_candidates.cpython-312.pyc
│ │ │ │ │ │ ├── provider.cpython-312.pyc
│ │ │ │ │ │ ├── reporter.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ └── resolver.cpython-312.pyc
│ │ │ │ │ ├── base.py
│ │ │ │ │ ├── candidates.py
│ │ │ │ │ ├── factory.py
│ │ │ │ │ ├── found_candidates.py
│ │ │ │ │ ├── provider.py
│ │ │ │ │ ├── reporter.py
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ └── resolver.py
│ │ │ │ ├── self_outdated_check.py
│ │ │ │ ├── utils
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _jaraco_text.cpython-312.pyc
│ │ │ │ │ │ ├── _log.cpython-312.pyc
│ │ │ │ │ │ ├── appdirs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── compatibility_tags.cpython-312.pyc
│ │ │ │ │ │ ├── datetime.cpython-312.pyc
│ │ │ │ │ │ ├── deprecation.cpython-312.pyc
│ │ │ │ │ │ ├── direct_url_helpers.cpython-312.pyc
│ │ │ │ │ │ ├── egg_link.cpython-312.pyc
│ │ │ │ │ │ ├── encoding.cpython-312.pyc
│ │ │ │ │ │ ├── entrypoints.cpython-312.pyc
│ │ │ │ │ │ ├── filesystem.cpython-312.pyc
│ │ │ │ │ │ ├── filetypes.cpython-312.pyc
│ │ │ │ │ │ ├── glibc.cpython-312.pyc
│ │ │ │ │ │ ├── hashes.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── misc.cpython-312.pyc
│ │ │ │ │ │ ├── packaging.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── setuptools_build.cpython-312.pyc
│ │ │ │ │ │ ├── subprocess.cpython-312.pyc
│ │ │ │ │ │ ├── temp_dir.cpython-312.pyc
│ │ │ │ │ │ ├── unpacking.cpython-312.pyc
│ │ │ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ │ │ ├── virtualenv.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── _jaraco_text.py
│ │ │ │ │ ├── _log.py
│ │ │ │ │ ├── appdirs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── compatibility_tags.py
│ │ │ │ │ ├── datetime.py
│ │ │ │ │ ├── deprecation.py
│ │ │ │ │ ├── direct_url_helpers.py
│ │ │ │ │ ├── egg_link.py
│ │ │ │ │ ├── encoding.py
│ │ │ │ │ ├── entrypoints.py
│ │ │ │ │ ├── filesystem.py
│ │ │ │ │ ├── filetypes.py
│ │ │ │ │ ├── glibc.py
│ │ │ │ │ ├── hashes.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── misc.py
│ │ │ │ │ ├── packaging.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── setuptools_build.py
│ │ │ │ │ ├── subprocess.py
│ │ │ │ │ ├── temp_dir.py
│ │ │ │ │ ├── unpacking.py
│ │ │ │ │ ├── urls.py
│ │ │ │ │ ├── virtualenv.py
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── vcs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── bazaar.cpython-312.pyc
│ │ │ │ │ │ ├── git.cpython-312.pyc
│ │ │ │ │ │ ├── mercurial.cpython-312.pyc
│ │ │ │ │ │ ├── subversion.cpython-312.pyc
│ │ │ │ │ │ └── versioncontrol.cpython-312.pyc
│ │ │ │ │ ├── bazaar.py
│ │ │ │ │ ├── git.py
│ │ │ │ │ ├── mercurial.py
│ │ │ │ │ ├── subversion.py
│ │ │ │ │ └── versioncontrol.py
│ │ │ │ └── wheel_builder.py
│ │ │ ├── _vendor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ └── typing_extensions.cpython-312.pyc
│ │ │ │ ├── cachecontrol
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _cmd.cpython-312.pyc
│ │ │ │ │ │ ├── adapter.cpython-312.pyc
│ │ │ │ │ │ ├── cache.cpython-312.pyc
│ │ │ │ │ │ ├── controller.cpython-312.pyc
│ │ │ │ │ │ ├── filewrapper.cpython-312.pyc
│ │ │ │ │ │ ├── heuristics.cpython-312.pyc
│ │ │ │ │ │ ├── serialize.cpython-312.pyc
│ │ │ │ │ │ └── wrapper.cpython-312.pyc
│ │ │ │ │ ├── _cmd.py
│ │ │ │ │ ├── adapter.py
│ │ │ │ │ ├── cache.py
│ │ │ │ │ ├── caches
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── file_cache.cpython-312.pyc
│ │ │ │ │ │ │ └── redis_cache.cpython-312.pyc
│ │ │ │ │ │ ├── file_cache.py
│ │ │ │ │ │ └── redis_cache.py
│ │ │ │ │ ├── controller.py
│ │ │ │ │ ├── filewrapper.py
│ │ │ │ │ ├── heuristics.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── serialize.py
│ │ │ │ │ └── wrapper.py
│ │ │ │ ├── certifi
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── core.cpython-312.pyc
│ │ │ │ │ ├── cacert.pem
│ │ │ │ │ ├── core.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── distlib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── database.cpython-312.pyc
│ │ │ │ │ │ ├── index.cpython-312.pyc
│ │ │ │ │ │ ├── locators.cpython-312.pyc
│ │ │ │ │ │ ├── manifest.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── resources.cpython-312.pyc
│ │ │ │ │ │ ├── scripts.cpython-312.pyc
│ │ │ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── wheel.cpython-312.pyc
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── database.py
│ │ │ │ │ ├── index.py
│ │ │ │ │ ├── locators.py
│ │ │ │ │ ├── manifest.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── resources.py
│ │ │ │ │ ├── scripts.py
│ │ │ │ │ ├── t32.exe
│ │ │ │ │ ├── t64-arm.exe
│ │ │ │ │ ├── t64.exe
│ │ │ │ │ ├── util.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ ├── w32.exe
│ │ │ │ │ ├── w64-arm.exe
│ │ │ │ │ ├── w64.exe
│ │ │ │ │ └── wheel.py
│ │ │ │ ├── distro
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ └── distro.cpython-312.pyc
│ │ │ │ │ ├── distro.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── idna
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── codec.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── core.cpython-312.pyc
│ │ │ │ │ │ ├── idnadata.cpython-312.pyc
│ │ │ │ │ │ ├── intranges.cpython-312.pyc
│ │ │ │ │ │ ├── package_data.cpython-312.pyc
│ │ │ │ │ │ └── uts46data.cpython-312.pyc
│ │ │ │ │ ├── codec.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── core.py
│ │ │ │ │ ├── idnadata.py
│ │ │ │ │ ├── intranges.py
│ │ │ │ │ ├── package_data.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ └── uts46data.py
│ │ │ │ ├── msgpack
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── ext.cpython-312.pyc
│ │ │ │ │ │ └── fallback.cpython-312.pyc
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── ext.py
│ │ │ │ │ └── fallback.py
│ │ │ │ ├── packaging
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _elffile.cpython-312.pyc
│ │ │ │ │ │ ├── _manylinux.cpython-312.pyc
│ │ │ │ │ │ ├── _musllinux.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _structures.cpython-312.pyc
│ │ │ │ │ │ ├── _tokenizer.cpython-312.pyc
│ │ │ │ │ │ ├── markers.cpython-312.pyc
│ │ │ │ │ │ ├── metadata.cpython-312.pyc
│ │ │ │ │ │ ├── requirements.cpython-312.pyc
│ │ │ │ │ │ ├── specifiers.cpython-312.pyc
│ │ │ │ │ │ ├── tags.cpython-312.pyc
│ │ │ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ │ │ └── version.cpython-312.pyc
│ │ │ │ │ ├── _elffile.py
│ │ │ │ │ ├── _manylinux.py
│ │ │ │ │ ├── _musllinux.py
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _structures.py
│ │ │ │ │ ├── _tokenizer.py
│ │ │ │ │ ├── markers.py
│ │ │ │ │ ├── metadata.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── requirements.py
│ │ │ │ │ ├── specifiers.py
│ │ │ │ │ ├── tags.py
│ │ │ │ │ ├── utils.py
│ │ │ │ │ └── version.py
│ │ │ │ ├── pkg_resources
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── __pycache__
│ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ ├── platformdirs
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── android.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── macos.cpython-312.pyc
│ │ │ │ │ │ ├── unix.cpython-312.pyc
│ │ │ │ │ │ ├── version.cpython-312.pyc
│ │ │ │ │ │ └── windows.cpython-312.pyc
│ │ │ │ │ ├── android.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── macos.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── unix.py
│ │ │ │ │ ├── version.py
│ │ │ │ │ └── windows.py
│ │ │ │ ├── pygments
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── cmdline.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── filter.cpython-312.pyc
│ │ │ │ │ │ ├── formatter.cpython-312.pyc
│ │ │ │ │ │ ├── lexer.cpython-312.pyc
│ │ │ │ │ │ ├── modeline.cpython-312.pyc
│ │ │ │ │ │ ├── plugin.cpython-312.pyc
│ │ │ │ │ │ ├── regexopt.cpython-312.pyc
│ │ │ │ │ │ ├── scanner.cpython-312.pyc
│ │ │ │ │ │ ├── sphinxext.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── token.cpython-312.pyc
│ │ │ │ │ │ ├── unistring.cpython-312.pyc
│ │ │ │ │ │ └── util.cpython-312.pyc
│ │ │ │ │ ├── cmdline.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── filter.py
│ │ │ │ │ ├── filters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── __pycache__
│ │ │ │ │ │ └── __init__.cpython-312.pyc
│ │ │ │ │ ├── formatter.py
│ │ │ │ │ ├── formatters
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ ├── bbcode.cpython-312.pyc
│ │ │ │ │ │ │ ├── groff.cpython-312.pyc
│ │ │ │ │ │ │ ├── html.cpython-312.pyc
│ │ │ │ │ │ │ ├── img.cpython-312.pyc
│ │ │ │ │ │ │ ├── irc.cpython-312.pyc
│ │ │ │ │ │ │ ├── latex.cpython-312.pyc
│ │ │ │ │ │ │ ├── other.cpython-312.pyc
│ │ │ │ │ │ │ ├── pangomarkup.cpython-312.pyc
│ │ │ │ │ │ │ ├── rtf.cpython-312.pyc
│ │ │ │ │ │ │ ├── svg.cpython-312.pyc
│ │ │ │ │ │ │ ├── terminal.cpython-312.pyc
│ │ │ │ │ │ │ └── terminal256.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ ├── bbcode.py
│ │ │ │ │ │ ├── groff.py
│ │ │ │ │ │ ├── html.py
│ │ │ │ │ │ ├── img.py
│ │ │ │ │ │ ├── irc.py
│ │ │ │ │ │ ├── latex.py
│ │ │ │ │ │ ├── other.py
│ │ │ │ │ │ ├── pangomarkup.py
│ │ │ │ │ │ ├── rtf.py
│ │ │ │ │ │ ├── svg.py
│ │ │ │ │ │ ├── terminal.py
│ │ │ │ │ │ └── terminal256.py
│ │ │ │ │ ├── lexer.py
│ │ │ │ │ ├── lexers
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _mapping.cpython-312.pyc
│ │ │ │ │ │ │ └── python.cpython-312.pyc
│ │ │ │ │ │ ├── _mapping.py
│ │ │ │ │ │ └── python.py
│ │ │ │ │ ├── modeline.py
│ │ │ │ │ ├── plugin.py
│ │ │ │ │ ├── regexopt.py
│ │ │ │ │ ├── scanner.py
│ │ │ │ │ ├── sphinxext.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styles
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── _mapping.cpython-312.pyc
│ │ │ │ │ │ └── _mapping.py
│ │ │ │ │ ├── token.py
│ │ │ │ │ ├── unistring.py
│ │ │ │ │ └── util.py
│ │ │ │ ├── pyproject_hooks
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _compat.cpython-312.pyc
│ │ │ │ │ │ └── _impl.cpython-312.pyc
│ │ │ │ │ ├── _compat.py
│ │ │ │ │ ├── _impl.py
│ │ │ │ │ └── _in_process
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ └── _in_process.cpython-312.pyc
│ │ │ │ │ └── _in_process.py
│ │ │ │ ├── requests
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ │ ├── __version__.py
│ │ │ │ │ ├── _internal_utils.py
│ │ │ │ │ ├── adapters.py
│ │ │ │ │ ├── api.py
│ │ │ │ │ ├── auth.py
│ │ │ │ │ ├── certs.py
│ │ │ │ │ ├── compat.py
│ │ │ │ │ ├── cookies.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── help.py
│ │ │ │ │ ├── hooks.py
│ │ │ │ │ ├── models.py
│ │ │ │ │ ├── packages.py
│ │ │ │ │ ├── sessions.py
│ │ │ │ │ ├── status_codes.py
│ │ │ │ │ ├── structures.py
│ │ │ │ │ └── utils.py
│ │ │ │ ├── resolvelib
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── providers.cpython-312.pyc
│ │ │ │ │ │ ├── reporters.cpython-312.pyc
│ │ │ │ │ │ ├── resolvers.cpython-312.pyc
│ │ │ │ │ │ └── structs.cpython-312.pyc
│ │ │ │ │ ├── compat
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── collections_abc.cpython-312.pyc
│ │ │ │ │ │ └── collections_abc.py
│ │ │ │ │ ├── providers.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── reporters.py
│ │ │ │ │ ├── resolvers.py
│ │ │ │ │ └── structs.py
│ │ │ │ ├── rich
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __main__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── __main__.cpython-312.pyc
│ │ │ │ │ │ ├── _cell_widths.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_codes.cpython-312.pyc
│ │ │ │ │ │ ├── _emoji_replace.cpython-312.pyc
│ │ │ │ │ │ ├── _export_format.cpython-312.pyc
│ │ │ │ │ │ ├── _extension.cpython-312.pyc
│ │ │ │ │ │ ├── _fileno.cpython-312.pyc
│ │ │ │ │ │ ├── _inspect.cpython-312.pyc
│ │ │ │ │ │ ├── _log_render.cpython-312.pyc
│ │ │ │ │ │ ├── _loop.cpython-312.pyc
│ │ │ │ │ │ ├── _null_file.cpython-312.pyc
│ │ │ │ │ │ ├── _palettes.cpython-312.pyc
│ │ │ │ │ │ ├── _pick.cpython-312.pyc
│ │ │ │ │ │ ├── _ratio.cpython-312.pyc
│ │ │ │ │ │ ├── _spinners.cpython-312.pyc
│ │ │ │ │ │ ├── _stack.cpython-312.pyc
│ │ │ │ │ │ ├── _timer.cpython-312.pyc
│ │ │ │ │ │ ├── _win32_console.cpython-312.pyc
│ │ │ │ │ │ ├── _windows_renderer.cpython-312.pyc
│ │ │ │ │ │ ├── _windows.cpython-312.pyc
│ │ │ │ │ │ ├── _wrap.cpython-312.pyc
│ │ │ │ │ │ ├── abc.cpython-312.pyc
│ │ │ │ │ │ ├── align.cpython-312.pyc
│ │ │ │ │ │ ├── ansi.cpython-312.pyc
│ │ │ │ │ │ ├── bar.cpython-312.pyc
│ │ │ │ │ │ ├── box.cpython-312.pyc
│ │ │ │ │ │ ├── cells.cpython-312.pyc
│ │ │ │ │ │ ├── color_triplet.cpython-312.pyc
│ │ │ │ │ │ ├── color.cpython-312.pyc
│ │ │ │ │ │ ├── columns.cpython-312.pyc
│ │ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ │ ├── constrain.cpython-312.pyc
│ │ │ │ │ │ ├── containers.cpython-312.pyc
│ │ │ │ │ │ ├── control.cpython-312.pyc
│ │ │ │ │ │ ├── default_styles.cpython-312.pyc
│ │ │ │ │ │ ├── diagnose.cpython-312.pyc
│ │ │ │ │ │ ├── emoji.cpython-312.pyc
│ │ │ │ │ │ ├── errors.cpython-312.pyc
│ │ │ │ │ │ ├── file_proxy.cpython-312.pyc
│ │ │ │ │ │ ├── filesize.cpython-312.pyc
│ │ │ │ │ │ ├── highlighter.cpython-312.pyc
│ │ │ │ │ │ ├── json.cpython-312.pyc
│ │ │ │ │ │ ├── jupyter.cpython-312.pyc
│ │ │ │ │ │ ├── layout.cpython-312.pyc
│ │ │ │ │ │ ├── live_render.cpython-312.pyc
│ │ │ │ │ │ ├── live.cpython-312.pyc
│ │ │ │ │ │ ├── logging.cpython-312.pyc
│ │ │ │ │ │ ├── markup.cpython-312.pyc
│ │ │ │ │ │ ├── measure.cpython-312.pyc
│ │ │ │ │ │ ├── padding.cpython-312.pyc
│ │ │ │ │ │ ├── pager.cpython-312.pyc
│ │ │ │ │ │ ├── palette.cpython-312.pyc
│ │ │ │ │ │ ├── panel.cpython-312.pyc
│ │ │ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ │ │ ├── progress_bar.cpython-312.pyc
│ │ │ │ │ │ ├── progress.cpython-312.pyc
│ │ │ │ │ │ ├── prompt.cpython-312.pyc
│ │ │ │ │ │ ├── protocol.cpython-312.pyc
│ │ │ │ │ │ ├── region.cpython-312.pyc
│ │ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ │ ├── rule.cpython-312.pyc
│ │ │ │ │ │ ├── scope.cpython-312.pyc
│ │ │ │ │ │ ├── screen.cpython-312.pyc
│ │ │ │ │ │ ├── segment.cpython-312.pyc
│ │ │ │ │ │ ├── spinner.cpython-312.pyc
│ │ │ │ │ │ ├── status.cpython-312.pyc
│ │ │ │ │ │ ├── style.cpython-312.pyc
│ │ │ │ │ │ ├── styled.cpython-312.pyc
│ │ │ │ │ │ ├── syntax.cpython-312.pyc
│ │ │ │ │ │ ├── table.cpython-312.pyc
│ │ │ │ │ │ ├── terminal_theme.cpython-312.pyc
│ │ │ │ │ │ ├── text.cpython-312.pyc
│ │ │ │ │ │ ├── theme.cpython-312.pyc
│ │ │ │ │ │ ├── themes.cpython-312.pyc
│ │ │ │ │ │ ├── traceback.cpython-312.pyc
│ │ │ │ │ │ └── tree.cpython-312.pyc
│ │ │ │ │ ├── _cell_widths.py
│ │ │ │ │ ├── _emoji_codes.py
│ │ │ │ │ ├── _emoji_replace.py
│ │ │ │ │ ├── _export_format.py
│ │ │ │ │ ├── _extension.py
│ │ │ │ │ ├── _fileno.py
│ │ │ │ │ ├── _inspect.py
│ │ │ │ │ ├── _log_render.py
│ │ │ │ │ ├── _loop.py
│ │ │ │ │ ├── _null_file.py
│ │ │ │ │ ├── _palettes.py
│ │ │ │ │ ├── _pick.py
│ │ │ │ │ ├── _ratio.py
│ │ │ │ │ ├── _spinners.py
│ │ │ │ │ ├── _stack.py
│ │ │ │ │ ├── _timer.py
│ │ │ │ │ ├── _win32_console.py
│ │ │ │ │ ├── _windows_renderer.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ ├── _wrap.py
│ │ │ │ │ ├── abc.py
│ │ │ │ │ ├── align.py
│ │ │ │ │ ├── ansi.py
│ │ │ │ │ ├── bar.py
│ │ │ │ │ ├── box.py
│ │ │ │ │ ├── cells.py
│ │ │ │ │ ├── color_triplet.py
│ │ │ │ │ ├── color.py
│ │ │ │ │ ├── columns.py
│ │ │ │ │ ├── console.py
│ │ │ │ │ ├── constrain.py
│ │ │ │ │ ├── containers.py
│ │ │ │ │ ├── control.py
│ │ │ │ │ ├── default_styles.py
│ │ │ │ │ ├── diagnose.py
│ │ │ │ │ ├── emoji.py
│ │ │ │ │ ├── errors.py
│ │ │ │ │ ├── file_proxy.py
│ │ │ │ │ ├── filesize.py
│ │ │ │ │ ├── highlighter.py
│ │ │ │ │ ├── json.py
│ │ │ │ │ ├── jupyter.py
│ │ │ │ │ ├── layout.py
│ │ │ │ │ ├── live_render.py
│ │ │ │ │ ├── live.py
│ │ │ │ │ ├── logging.py
│ │ │ │ │ ├── markup.py
│ │ │ │ │ ├── measure.py
│ │ │ │ │ ├── padding.py
│ │ │ │ │ ├── pager.py
│ │ │ │ │ ├── palette.py
│ │ │ │ │ ├── panel.py
│ │ │ │ │ ├── pretty.py
│ │ │ │ │ ├── progress_bar.py
│ │ │ │ │ ├── progress.py
│ │ │ │ │ ├── prompt.py
│ │ │ │ │ ├── protocol.py
│ │ │ │ │ ├── py.typed
│ │ │ │ │ ├── region.py
│ │ │ │ │ ├── repr.py
│ │ │ │ │ ├── rule.py
│ │ │ │ │ ├── scope.py
│ │ │ │ │ ├── screen.py
│ │ │ │ │ ├── segment.py
│ │ │ │ │ ├── spinner.py
│ │ │ │ │ ├── status.py
│ │ │ │ │ ├── style.py
│ │ │ │ │ ├── styled.py
│ │ │ │ │ ├── syntax.py
│ │ │ │ │ ├── table.py
│ │ │ │ │ ├── terminal_theme.py
│ │ │ │ │ ├── text.py
│ │ │ │ │ ├── theme.py
│ │ │ │ │ ├── themes.py
│ │ │ │ │ ├── traceback.py
│ │ │ │ │ └── tree.py
│ │ │ │ ├── tomli
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _parser.cpython-312.pyc
│ │ │ │ │ │ ├── _re.cpython-312.pyc
│ │ │ │ │ │ └── _types.cpython-312.pyc
│ │ │ │ │ ├── _parser.py
│ │ │ │ │ ├── _re.py
│ │ │ │ │ ├── _types.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── truststore
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _api.cpython-312.pyc
│ │ │ │ │ │ ├── _macos.cpython-312.pyc
│ │ │ │ │ │ ├── _openssl.cpython-312.pyc
│ │ │ │ │ │ ├── _ssl_constants.cpython-312.pyc
│ │ │ │ │ │ └── _windows.cpython-312.pyc
│ │ │ │ │ ├── _api.py
│ │ │ │ │ ├── _macos.py
│ │ │ │ │ ├── _openssl.py
│ │ │ │ │ ├── _ssl_constants.py
│ │ │ │ │ ├── _windows.py
│ │ │ │ │ └── py.typed
│ │ │ │ ├── typing_extensions.py
│ │ │ │ ├── urllib3
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── _collections.py
│ │ │ │ │ ├── _version.py
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── connectionpool.py
│ │ │ │ │ ├── contrib
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ ├── _appengine_environ.cpython-312.pyc
│ │ │ │ │ │ │ ├── appengine.cpython-312.pyc
│ │ │ │ │ │ │ ├── ntlmpool.cpython-312.pyc
│ │ │ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ │ │ ├── securetransport.cpython-312.pyc
│ │ │ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ │ │ ├── _appengine_environ.py
│ │ │ │ │ │ ├── _securetransport
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── bindings.cpython-312.pyc
│ │ │ │ │ │ │ │ └── low_level.cpython-312.pyc
│ │ │ │ │ │ │ ├── bindings.py
│ │ │ │ │ │ │ └── low_level.py
│ │ │ │ │ │ ├── appengine.py
│ │ │ │ │ │ ├── ntlmpool.py
│ │ │ │ │ │ ├── pyopenssl.py
│ │ │ │ │ │ ├── securetransport.py
│ │ │ │ │ │ └── socks.py
│ │ │ │ │ ├── exceptions.py
│ │ │ │ │ ├── fields.py
│ │ │ │ │ ├── filepost.py
│ │ │ │ │ ├── packages
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ └── six.cpython-312.pyc
│ │ │ │ │ │ ├── backports
│ │ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ │ │ ├── makefile.cpython-312.pyc
│ │ │ │ │ │ │ │ └── weakref_finalize.cpython-312.pyc
│ │ │ │ │ │ │ ├── makefile.py
│ │ │ │ │ │ │ └── weakref_finalize.py
│ │ │ │ │ │ └── six.py
│ │ │ │ │ ├── poolmanager.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ └── util
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ │ │ ├── queue.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ │ │ └── wait.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── proxy.py
│ │ │ │ │ ├── queue.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ ├── response.py
│ │ │ │ │ ├── retry.py
│ │ │ │ │ ├── ssl_.py
│ │ │ │ │ ├── ssl_match_hostname.py
│ │ │ │ │ ├── ssltransport.py
│ │ │ │ │ ├── timeout.py
│ │ │ │ │ ├── url.py
│ │ │ │ │ └── wait.py
│ │ │ │ └── vendor.txt
│ │ │ └── py.typed
│ │ ├── pip-24.2.dist-info
│ │ │ ├── AUTHORS.txt
│ │ │ ├── entry_points.txt
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── requests
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __version__.cpython-312.pyc
│ │ │ │ ├── _internal_utils.cpython-312.pyc
│ │ │ │ ├── adapters.cpython-312.pyc
│ │ │ │ ├── api.cpython-312.pyc
│ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ ├── certs.cpython-312.pyc
│ │ │ │ ├── compat.cpython-312.pyc
│ │ │ │ ├── cookies.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── help.cpython-312.pyc
│ │ │ │ ├── hooks.cpython-312.pyc
│ │ │ │ ├── models.cpython-312.pyc
│ │ │ │ ├── packages.cpython-312.pyc
│ │ │ │ ├── sessions.cpython-312.pyc
│ │ │ │ ├── status_codes.cpython-312.pyc
│ │ │ │ ├── structures.cpython-312.pyc
│ │ │ │ └── utils.cpython-312.pyc
│ │ │ ├── __version__.py
│ │ │ ├── _internal_utils.py
│ │ │ ├── adapters.py
│ │ │ ├── api.py
│ │ │ ├── auth.py
│ │ │ ├── certs.py
│ │ │ ├── compat.py
│ │ │ ├── cookies.py
│ │ │ ├── exceptions.py
│ │ │ ├── help.py
│ │ │ ├── hooks.py
│ │ │ ├── models.py
│ │ │ ├── packages.py
│ │ │ ├── sessions.py
│ │ │ ├── status_codes.py
│ │ │ ├── structures.py
│ │ │ └── utils.py
│ │ ├── requests-2.32.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── soupsieve
│ │ │ ├── __init__.py
│ │ │ ├── __meta__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── __meta__.cpython-312.pyc
│ │ │ │ ├── css_match.cpython-312.pyc
│ │ │ │ ├── css_parser.cpython-312.pyc
│ │ │ │ ├── css_types.cpython-312.pyc
│ │ │ │ ├── pretty.cpython-312.pyc
│ │ │ │ └── util.cpython-312.pyc
│ │ │ ├── css_match.py
│ │ │ ├── css_parser.py
│ │ │ ├── css_types.py
│ │ │ ├── pretty.py
│ │ │ ├── py.typed
│ │ │ └── util.py
│ │ ├── soupsieve-2.6.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.md
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── urllib3
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _base_connection.cpython-312.pyc
│ │ │ │ ├── _collections.cpython-312.pyc
│ │ │ │ ├── _request_methods.cpython-312.pyc
│ │ │ │ ├── _version.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── connectionpool.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── fields.cpython-312.pyc
│ │ │ │ ├── filepost.cpython-312.pyc
│ │ │ │ ├── poolmanager.cpython-312.pyc
│ │ │ │ └── response.cpython-312.pyc
│ │ │ ├── _base_connection.py
│ │ │ ├── _collections.py
│ │ │ ├── _request_methods.py
│ │ │ ├── _version.py
│ │ │ ├── connection.py
│ │ │ ├── connectionpool.py
│ │ │ ├── contrib
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── pyopenssl.cpython-312.pyc
│ │ │ │ │ └── socks.cpython-312.pyc
│ │ │ │ ├── emscripten
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── __pycache__
│ │ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ │ ├── fetch.cpython-312.pyc
│ │ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ │ ├── connection.py
│ │ │ │ │ ├── emscripten_fetch_worker.js
│ │ │ │ │ ├── fetch.py
│ │ │ │ │ ├── request.py
│ │ │ │ │ └── response.py
│ │ │ │ ├── pyopenssl.py
│ │ │ │ └── socks.py
│ │ │ ├── exceptions.py
│ │ │ ├── fields.py
│ │ │ ├── filepost.py
│ │ │ ├── http2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ │ └── probe.cpython-312.pyc
│ │ │ │ ├── connection.py
│ │ │ │ └── probe.py
│ │ │ ├── poolmanager.py
│ │ │ ├── py.typed
│ │ │ ├── response.py
│ │ │ └── util
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── connection.cpython-312.pyc
│ │ │ │ ├── proxy.cpython-312.pyc
│ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ ├── retry.cpython-312.pyc
│ │ │ │ ├── ssl_.cpython-312.pyc
│ │ │ │ ├── ssl_match_hostname.cpython-312.pyc
│ │ │ │ ├── ssltransport.cpython-312.pyc
│ │ │ │ ├── timeout.cpython-312.pyc
│ │ │ │ ├── url.cpython-312.pyc
│ │ │ │ ├── util.cpython-312.pyc
│ │ │ │ └── wait.cpython-312.pyc
│ │ │ ├── connection.py
│ │ │ ├── proxy.py
│ │ │ ├── request.py
│ │ │ ├── response.py
│ │ │ ├── retry.py
│ │ │ ├── ssl_.py
│ │ │ ├── ssl_match_hostname.py
│ │ │ ├── ssltransport.py
│ │ │ ├── timeout.py
│ │ │ ├── url.py
│ │ │ ├── util.py
│ │ │ └── wait.py
│ │ ├── urllib3-2.2.3.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── licenses
│ │ │ │ └── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ └── WHEEL
│ │ ├── useragent
│ │ │ ├── __init__.py
│ │ │ ├── __init__.pyc
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── resources
│ │ │ │ └── user_agent_data.json
│ │ │ └── test
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ └── __init__.cpython-312.pyc
│ │ │ ├── test_additional_os.json
│ │ │ ├── test_browser.json
│ │ │ ├── test_device.json
│ │ │ ├── test_firefox.json
│ │ │ ├── test_os.json
│ │ │ └── test_pgts_browser.json
│ │ ├── useragent-0.1.1.dist-info
│ │ │ ├── INSTALLER
│ │ │ ├── LICENSE.txt
│ │ │ ├── METADATA
│ │ │ ├── RECORD
│ │ │ ├── REQUESTED
│ │ │ ├── top_level.txt
│ │ │ └── WHEEL
│ │ ├── werkzeug
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ ├── _internal.cpython-312.pyc
│ │ │ │ ├── _reloader.cpython-312.pyc
│ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ ├── formparser.cpython-312.pyc
│ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ ├── local.cpython-312.pyc
│ │ │ │ ├── security.cpython-312.pyc
│ │ │ │ ├── serving.cpython-312.pyc
│ │ │ │ ├── test.cpython-312.pyc
│ │ │ │ ├── testapp.cpython-312.pyc
│ │ │ │ ├── urls.cpython-312.pyc
│ │ │ │ ├── user_agent.cpython-312.pyc
│ │ │ │ ├── utils.cpython-312.pyc
│ │ │ │ └── wsgi.cpython-312.pyc
│ │ │ ├── _internal.py
│ │ │ ├── _reloader.py
│ │ │ ├── datastructures
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── accept.cpython-312.pyc
│ │ │ │ │ ├── auth.cpython-312.pyc
│ │ │ │ │ ├── cache_control.cpython-312.pyc
│ │ │ │ │ ├── csp.cpython-312.pyc
│ │ │ │ │ ├── etag.cpython-312.pyc
│ │ │ │ │ ├── file_storage.cpython-312.pyc
│ │ │ │ │ ├── headers.cpython-312.pyc
│ │ │ │ │ ├── mixins.cpython-312.pyc
│ │ │ │ │ ├── range.cpython-312.pyc
│ │ │ │ │ └── structures.cpython-312.pyc
│ │ │ │ ├── accept.py
│ │ │ │ ├── accept.pyi
│ │ │ │ ├── auth.py
│ │ │ │ ├── cache_control.py
│ │ │ │ ├── cache_control.pyi
│ │ │ │ ├── csp.py
│ │ │ │ ├── csp.pyi
│ │ │ │ ├── etag.py
│ │ │ │ ├── etag.pyi
│ │ │ │ ├── file_storage.py
│ │ │ │ ├── file_storage.pyi
│ │ │ │ ├── headers.py
│ │ │ │ ├── headers.pyi
│ │ │ │ ├── mixins.py
│ │ │ │ ├── mixins.pyi
│ │ │ │ ├── range.py
│ │ │ │ ├── range.pyi
│ │ │ │ ├── structures.py
│ │ │ │ └── structures.pyi
│ │ │ ├── debug
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── console.cpython-312.pyc
│ │ │ │ │ ├── repr.cpython-312.pyc
│ │ │ │ │ └── tbtools.cpython-312.pyc
│ │ │ │ ├── console.py
│ │ │ │ ├── repr.py
│ │ │ │ ├── shared
│ │ │ │ │ ├── console.png
│ │ │ │ │ ├── debugger.js
│ │ │ │ │ ├── ICON_LICENSE.md
│ │ │ │ │ ├── less.png
│ │ │ │ │ ├── more.png
│ │ │ │ │ └── style.css
│ │ │ │ └── tbtools.py
│ │ │ ├── exceptions.py
│ │ │ ├── formparser.py
│ │ │ ├── http.py
│ │ │ ├── local.py
│ │ │ ├── middleware
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── dispatcher.cpython-312.pyc
│ │ │ │ │ ├── http_proxy.cpython-312.pyc
│ │ │ │ │ ├── lint.cpython-312.pyc
│ │ │ │ │ ├── profiler.cpython-312.pyc
│ │ │ │ │ ├── proxy_fix.cpython-312.pyc
│ │ │ │ │ └── shared_data.cpython-312.pyc
│ │ │ │ ├── dispatcher.py
│ │ │ │ ├── http_proxy.py
│ │ │ │ ├── lint.py
│ │ │ │ ├── profiler.py
│ │ │ │ ├── proxy_fix.py
│ │ │ │ └── shared_data.py
│ │ │ ├── py.typed
│ │ │ ├── routing
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── converters.cpython-312.pyc
│ │ │ │ │ ├── exceptions.cpython-312.pyc
│ │ │ │ │ ├── map.cpython-312.pyc
│ │ │ │ │ ├── matcher.cpython-312.pyc
│ │ │ │ │ └── rules.cpython-312.pyc
│ │ │ │ ├── converters.py
│ │ │ │ ├── exceptions.py
│ │ │ │ ├── map.py
│ │ │ │ ├── matcher.py
│ │ │ │ └── rules.py
│ │ │ ├── sansio
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── http.cpython-312.pyc
│ │ │ │ │ ├── multipart.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ ├── response.cpython-312.pyc
│ │ │ │ │ └── utils.cpython-312.pyc
│ │ │ │ ├── http.py
│ │ │ │ ├── multipart.py
│ │ │ │ ├── request.py
│ │ │ │ ├── response.py
│ │ │ │ └── utils.py
│ │ │ ├── security.py
│ │ │ ├── serving.py
│ │ │ ├── test.py
│ │ │ ├── testapp.py
│ │ │ ├── urls.py
│ │ │ ├── user_agent.py
│ │ │ ├── utils.py
│ │ │ ├── wrappers
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __pycache__
│ │ │ │ │ ├── __init__.cpython-312.pyc
│ │ │ │ │ ├── request.cpython-312.pyc
│ │ │ │ │ └── response.cpython-312.pyc
│ │ │ │ ├── request.py
│ │ │ │ └── response.py
│ │ │ └── wsgi.py
│ │ └── werkzeug-3.0.4.dist-info
│ │ ├── INSTALLER
│ │ ├── LICENSE.txt
│ │ ├── METADATA
│ │ ├── RECORD
│ │ └── WHEEL
│ ├── pyvenv.cfg
│ ├── static
│ │ └── styles.css
│ ├── templates
│ │ └── index.html
│ └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
├── text1.txt
└── text2.txt
```
# Files
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/rich/__main__.py:
--------------------------------------------------------------------------------
```python
1 | import colorsys
2 | import io
3 | from time import process_time
4 |
5 | from pip._vendor.rich import box
6 | from pip._vendor.rich.color import Color
7 | from pip._vendor.rich.console import Console, ConsoleOptions, Group, RenderableType, RenderResult
8 | from pip._vendor.rich.markdown import Markdown
9 | from pip._vendor.rich.measure import Measurement
10 | from pip._vendor.rich.pretty import Pretty
11 | from pip._vendor.rich.segment import Segment
12 | from pip._vendor.rich.style import Style
13 | from pip._vendor.rich.syntax import Syntax
14 | from pip._vendor.rich.table import Table
15 | from pip._vendor.rich.text import Text
16 |
17 |
18 | class ColorBox:
19 | def __rich_console__(
20 | self, console: Console, options: ConsoleOptions
21 | ) -> RenderResult:
22 | for y in range(0, 5):
23 | for x in range(options.max_width):
24 | h = x / options.max_width
25 | l = 0.1 + ((y / 5) * 0.7)
26 | r1, g1, b1 = colorsys.hls_to_rgb(h, l, 1.0)
27 | r2, g2, b2 = colorsys.hls_to_rgb(h, l + 0.7 / 10, 1.0)
28 | bgcolor = Color.from_rgb(r1 * 255, g1 * 255, b1 * 255)
29 | color = Color.from_rgb(r2 * 255, g2 * 255, b2 * 255)
30 | yield Segment("▄", Style(color=color, bgcolor=bgcolor))
31 | yield Segment.line()
32 |
33 | def __rich_measure__(
34 | self, console: "Console", options: ConsoleOptions
35 | ) -> Measurement:
36 | return Measurement(1, options.max_width)
37 |
38 |
39 | def make_test_card() -> Table:
40 | """Get a renderable that demonstrates a number of features."""
41 | table = Table.grid(padding=1, pad_edge=True)
42 | table.title = "Rich features"
43 | table.add_column("Feature", no_wrap=True, justify="center", style="bold red")
44 | table.add_column("Demonstration")
45 |
46 | color_table = Table(
47 | box=None,
48 | expand=False,
49 | show_header=False,
50 | show_edge=False,
51 | pad_edge=False,
52 | )
53 | color_table.add_row(
54 | (
55 | "✓ [bold green]4-bit color[/]\n"
56 | "✓ [bold blue]8-bit color[/]\n"
57 | "✓ [bold magenta]Truecolor (16.7 million)[/]\n"
58 | "✓ [bold yellow]Dumb terminals[/]\n"
59 | "✓ [bold cyan]Automatic color conversion"
60 | ),
61 | ColorBox(),
62 | )
63 |
64 | table.add_row("Colors", color_table)
65 |
66 | table.add_row(
67 | "Styles",
68 | "All ansi styles: [bold]bold[/], [dim]dim[/], [italic]italic[/italic], [underline]underline[/], [strike]strikethrough[/], [reverse]reverse[/], and even [blink]blink[/].",
69 | )
70 |
71 | lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in metus sed sapien ultricies pretium a at justo. Maecenas luctus velit et auctor maximus."
72 | lorem_table = Table.grid(padding=1, collapse_padding=True)
73 | lorem_table.pad_edge = False
74 | lorem_table.add_row(
75 | Text(lorem, justify="left", style="green"),
76 | Text(lorem, justify="center", style="yellow"),
77 | Text(lorem, justify="right", style="blue"),
78 | Text(lorem, justify="full", style="red"),
79 | )
80 | table.add_row(
81 | "Text",
82 | Group(
83 | Text.from_markup(
84 | """Word wrap text. Justify [green]left[/], [yellow]center[/], [blue]right[/] or [red]full[/].\n"""
85 | ),
86 | lorem_table,
87 | ),
88 | )
89 |
90 | def comparison(renderable1: RenderableType, renderable2: RenderableType) -> Table:
91 | table = Table(show_header=False, pad_edge=False, box=None, expand=True)
92 | table.add_column("1", ratio=1)
93 | table.add_column("2", ratio=1)
94 | table.add_row(renderable1, renderable2)
95 | return table
96 |
97 | table.add_row(
98 | "Asian\nlanguage\nsupport",
99 | ":flag_for_china: 该库支持中文,日文和韩文文本!\n:flag_for_japan: ライブラリは中国語、日本語、韓国語のテキストをサポートしています\n:flag_for_south_korea: 이 라이브러리는 중국어, 일본어 및 한국어 텍스트를 지원합니다",
100 | )
101 |
102 | markup_example = (
103 | "[bold magenta]Rich[/] supports a simple [i]bbcode[/i]-like [b]markup[/b] for [yellow]color[/], [underline]style[/], and emoji! "
104 | ":+1: :apple: :ant: :bear: :baguette_bread: :bus: "
105 | )
106 | table.add_row("Markup", markup_example)
107 |
108 | example_table = Table(
109 | show_edge=False,
110 | show_header=True,
111 | expand=False,
112 | row_styles=["none", "dim"],
113 | box=box.SIMPLE,
114 | )
115 | example_table.add_column("[green]Date", style="green", no_wrap=True)
116 | example_table.add_column("[blue]Title", style="blue")
117 | example_table.add_column(
118 | "[cyan]Production Budget",
119 | style="cyan",
120 | justify="right",
121 | no_wrap=True,
122 | )
123 | example_table.add_column(
124 | "[magenta]Box Office",
125 | style="magenta",
126 | justify="right",
127 | no_wrap=True,
128 | )
129 | example_table.add_row(
130 | "Dec 20, 2019",
131 | "Star Wars: The Rise of Skywalker",
132 | "$275,000,000",
133 | "$375,126,118",
134 | )
135 | example_table.add_row(
136 | "May 25, 2018",
137 | "[b]Solo[/]: A Star Wars Story",
138 | "$275,000,000",
139 | "$393,151,347",
140 | )
141 | example_table.add_row(
142 | "Dec 15, 2017",
143 | "Star Wars Ep. VIII: The Last Jedi",
144 | "$262,000,000",
145 | "[bold]$1,332,539,889[/bold]",
146 | )
147 | example_table.add_row(
148 | "May 19, 1999",
149 | "Star Wars Ep. [b]I[/b]: [i]The phantom Menace",
150 | "$115,000,000",
151 | "$1,027,044,677",
152 | )
153 |
154 | table.add_row("Tables", example_table)
155 |
156 | code = '''\
157 | def iter_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:
158 | """Iterate and generate a tuple with a flag for last value."""
159 | iter_values = iter(values)
160 | try:
161 | previous_value = next(iter_values)
162 | except StopIteration:
163 | return
164 | for value in iter_values:
165 | yield False, previous_value
166 | previous_value = value
167 | yield True, previous_value'''
168 |
169 | pretty_data = {
170 | "foo": [
171 | 3.1427,
172 | (
173 | "Paul Atreides",
174 | "Vladimir Harkonnen",
175 | "Thufir Hawat",
176 | ),
177 | ],
178 | "atomic": (False, True, None),
179 | }
180 | table.add_row(
181 | "Syntax\nhighlighting\n&\npretty\nprinting",
182 | comparison(
183 | Syntax(code, "python3", line_numbers=True, indent_guides=True),
184 | Pretty(pretty_data, indent_guides=True),
185 | ),
186 | )
187 |
188 | markdown_example = """\
189 | # Markdown
190 |
191 | Supports much of the *markdown* __syntax__!
192 |
193 | - Headers
194 | - Basic formatting: **bold**, *italic*, `code`
195 | - Block quotes
196 | - Lists, and more...
197 | """
198 | table.add_row(
199 | "Markdown", comparison("[cyan]" + markdown_example, Markdown(markdown_example))
200 | )
201 |
202 | table.add_row(
203 | "+more!",
204 | """Progress bars, columns, styled logging handler, tracebacks, etc...""",
205 | )
206 | return table
207 |
208 |
209 | if __name__ == "__main__": # pragma: no cover
210 | console = Console(
211 | file=io.StringIO(),
212 | force_terminal=True,
213 | )
214 | test_card = make_test_card()
215 |
216 | # Print once to warm cache
217 | start = process_time()
218 | console.print(test_card)
219 | pre_cache_taken = round((process_time() - start) * 1000.0, 1)
220 |
221 | console.file = io.StringIO()
222 |
223 | start = process_time()
224 | console.print(test_card)
225 | taken = round((process_time() - start) * 1000.0, 1)
226 |
227 | c = Console(record=True)
228 | c.print(test_card)
229 |
230 | print(f"rendered in {pre_cache_taken}ms (cold cache)")
231 | print(f"rendered in {taken}ms (warm cache)")
232 |
233 | from pip._vendor.rich.panel import Panel
234 |
235 | console = Console()
236 |
237 | sponsor_message = Table.grid(padding=1)
238 | sponsor_message.add_column(style="green", justify="right")
239 | sponsor_message.add_column(no_wrap=True)
240 |
241 | sponsor_message.add_row(
242 | "Textualize",
243 | "[u blue link=https://github.com/textualize]https://github.com/textualize",
244 | )
245 | sponsor_message.add_row(
246 | "Twitter",
247 | "[u blue link=https://twitter.com/willmcgugan]https://twitter.com/willmcgugan",
248 | )
249 |
250 | intro_message = Text.from_markup(
251 | """\
252 | We hope you enjoy using Rich!
253 |
254 | Rich is maintained with [red]:heart:[/] by [link=https://www.textualize.io]Textualize.io[/]
255 |
256 | - Will McGugan"""
257 | )
258 |
259 | message = Table.grid(padding=2)
260 | message.add_column()
261 | message.add_column(no_wrap=True)
262 | message.add_row(intro_message, sponsor_message)
263 |
264 | console.print(
265 | Panel.fit(
266 | message,
267 | box=box.ROUNDED,
268 | padding=(1, 2),
269 | title="[b red]Thanks for trying out Rich!",
270 | border_style="bright_blue",
271 | ),
272 | justify="center",
273 | )
274 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/bs4/tests/test_html5lib.py:
--------------------------------------------------------------------------------
```python
1 | """Tests to ensure that the html5lib tree builder generates good trees."""
2 |
3 | import pytest
4 | import warnings
5 |
6 | from bs4 import BeautifulSoup
7 | from bs4.element import SoupStrainer
8 | from . import (
9 | HTML5LIB_PRESENT,
10 | HTML5TreeBuilderSmokeTest,
11 | SoupTest,
12 | )
13 |
14 | @pytest.mark.skipif(
15 | not HTML5LIB_PRESENT,
16 | reason="html5lib seems not to be present, not testing its tree builder."
17 | )
18 | class TestHTML5LibBuilder(SoupTest, HTML5TreeBuilderSmokeTest):
19 | """See ``HTML5TreeBuilderSmokeTest``."""
20 |
21 | @property
22 | def default_builder(self):
23 | from bs4.builder import HTML5TreeBuilder
24 | return HTML5TreeBuilder
25 |
26 | def test_soupstrainer(self):
27 | # The html5lib tree builder does not support SoupStrainers.
28 | strainer = SoupStrainer("b")
29 | markup = "<p>A <b>bold</b> statement.</p>"
30 | with warnings.catch_warnings(record=True) as w:
31 | soup = BeautifulSoup(markup, "html5lib", parse_only=strainer)
32 | assert soup.decode() == self.document_for(markup)
33 |
34 | [warning] = w
35 | assert warning.filename == __file__
36 | assert "the html5lib tree builder doesn't support parse_only" in str(warning.message)
37 |
38 | def test_correctly_nested_tables(self):
39 | """html5lib inserts <tbody> tags where other parsers don't."""
40 | markup = ('<table id="1">'
41 | '<tr>'
42 | "<td>Here's another table:"
43 | '<table id="2">'
44 | '<tr><td>foo</td></tr>'
45 | '</table></td>')
46 |
47 | self.assert_soup(
48 | markup,
49 | '<table id="1"><tbody><tr><td>Here\'s another table:'
50 | '<table id="2"><tbody><tr><td>foo</td></tr></tbody></table>'
51 | '</td></tr></tbody></table>')
52 |
53 | self.assert_soup(
54 | "<table><thead><tr><td>Foo</td></tr></thead>"
55 | "<tbody><tr><td>Bar</td></tr></tbody>"
56 | "<tfoot><tr><td>Baz</td></tr></tfoot></table>")
57 |
58 | def test_xml_declaration_followed_by_doctype(self):
59 | markup = '''<?xml version="1.0" encoding="utf-8"?>
60 | <!DOCTYPE html>
61 | <html>
62 | <head>
63 | </head>
64 | <body>
65 | <p>foo</p>
66 | </body>
67 | </html>'''
68 | soup = self.soup(markup)
69 | # Verify that we can reach the <p> tag; this means the tree is connected.
70 | assert b"<p>foo</p>" == soup.p.encode()
71 |
72 | def test_reparented_markup(self):
73 | markup = '<p><em>foo</p>\n<p>bar<a></a></em></p>'
74 | soup = self.soup(markup)
75 | assert "<body><p><em>foo</em></p><em>\n</em><p><em>bar<a></a></em></p></body>" == soup.body.decode()
76 | assert 2 == len(soup.find_all('p'))
77 |
78 |
79 | def test_reparented_markup_ends_with_whitespace(self):
80 | markup = '<p><em>foo</p>\n<p>bar<a></a></em></p>\n'
81 | soup = self.soup(markup)
82 | assert "<body><p><em>foo</em></p><em>\n</em><p><em>bar<a></a></em></p>\n</body>" == soup.body.decode()
83 | assert 2 == len(soup.find_all('p'))
84 |
85 | def test_reparented_markup_containing_identical_whitespace_nodes(self):
86 | """Verify that we keep the two whitespace nodes in this
87 | document distinct when reparenting the adjacent <tbody> tags.
88 | """
89 | markup = '<table> <tbody><tbody><ims></tbody> </table>'
90 | soup = self.soup(markup)
91 | space1, space2 = soup.find_all(string=' ')
92 | tbody1, tbody2 = soup.find_all('tbody')
93 | assert space1.next_element is tbody1
94 | assert tbody2.next_element is space2
95 |
96 | def test_reparented_markup_containing_children(self):
97 | markup = '<div><a>aftermath<p><noscript>target</noscript>aftermath</a></p></div>'
98 | soup = self.soup(markup)
99 | noscript = soup.noscript
100 | assert "target" == noscript.next_element
101 | target = soup.find(string='target')
102 |
103 | # The 'aftermath' string was duplicated; we want the second one.
104 | final_aftermath = soup.find_all(string='aftermath')[-1]
105 |
106 | # The <noscript> tag was moved beneath a copy of the <a> tag,
107 | # but the 'target' string within is still connected to the
108 | # (second) 'aftermath' string.
109 | assert final_aftermath == target.next_element
110 | assert target == final_aftermath.previous_element
111 |
112 | def test_processing_instruction(self):
113 | """Processing instructions become comments."""
114 | markup = b"""<?PITarget PIContent?>"""
115 | soup = self.soup(markup)
116 | assert str(soup).startswith("<!--?PITarget PIContent?-->")
117 |
118 | def test_cloned_multivalue_node(self):
119 | markup = b"""<a class="my_class"><p></a>"""
120 | soup = self.soup(markup)
121 | a1, a2 = soup.find_all('a')
122 | assert a1 == a2
123 | assert a1 is not a2
124 |
125 | def test_foster_parenting(self):
126 | markup = b"""<table><td></tbody>A"""
127 | soup = self.soup(markup)
128 | assert "<body>A<table><tbody><tr><td></td></tr></tbody></table></body>" == soup.body.decode()
129 |
130 | def test_extraction(self):
131 | """
132 | Test that extraction does not destroy the tree.
133 |
134 | https://bugs.launchpad.net/beautifulsoup/+bug/1782928
135 | """
136 |
137 | markup = """
138 | <html><head></head>
139 | <style>
140 | </style><script></script><body><p>hello</p></body></html>
141 | """
142 | soup = self.soup(markup)
143 | [s.extract() for s in soup('script')]
144 | [s.extract() for s in soup('style')]
145 |
146 | assert len(soup.find_all("p")) == 1
147 |
148 | def test_empty_comment(self):
149 | """
150 | Test that empty comment does not break structure.
151 |
152 | https://bugs.launchpad.net/beautifulsoup/+bug/1806598
153 | """
154 |
155 | markup = """
156 | <html>
157 | <body>
158 | <form>
159 | <!----><input type="text">
160 | </form>
161 | </body>
162 | </html>
163 | """
164 | soup = self.soup(markup)
165 | inputs = []
166 | for form in soup.find_all('form'):
167 | inputs.extend(form.find_all('input'))
168 | assert len(inputs) == 1
169 |
170 | def test_tracking_line_numbers(self):
171 | # The html.parser TreeBuilder keeps track of line number and
172 | # position of each element.
173 | markup = "\n <p>\n\n<sourceline>\n<b>text</b></sourceline><sourcepos></p>"
174 | soup = self.soup(markup)
175 | assert 2 == soup.p.sourceline
176 | assert 5 == soup.p.sourcepos
177 | assert "sourceline" == soup.p.find('sourceline').name
178 |
179 | # You can deactivate this behavior.
180 | soup = self.soup(markup, store_line_numbers=False)
181 | assert "sourceline" == soup.p.sourceline.name
182 | assert "sourcepos" == soup.p.sourcepos.name
183 |
184 | def test_special_string_containers(self):
185 | # The html5lib tree builder doesn't support this standard feature,
186 | # because there's no way of knowing, when a string is created,
187 | # where in the tree it will eventually end up.
188 | pass
189 |
190 | def test_html5_attributes(self):
191 | # The html5lib TreeBuilder can convert any entity named in
192 | # the HTML5 spec to a sequence of Unicode characters, and
193 | # convert those Unicode characters to a (potentially
194 | # different) named entity on the way out.
195 | #
196 | # This is a copy of the same test from
197 | # HTMLParserTreeBuilderSmokeTest. It's not in the superclass
198 | # because the lxml HTML TreeBuilder _doesn't_ work this way.
199 | for input_element, output_unicode, output_element in (
200 | ("⇄", '\u21c4', b'⇄'),
201 | ('⊧', '\u22a7', b'⊧'),
202 | ('𝔑', '\U0001d511', b'𝔑'),
203 | ('≧̸', '\u2267\u0338', b'≧̸'),
204 | ('¬', '\xac', b'¬'),
205 | ('⫬', '\u2aec', b'⫬'),
206 | ('"', '"', b'"'),
207 | ('∴', '\u2234', b'∴'),
208 | ('∴', '\u2234', b'∴'),
209 | ('∴', '\u2234', b'∴'),
210 | ("fj", 'fj', b'fj'),
211 | ("⊔", '\u2294', b'⊔'),
212 | ("⊔︀", '\u2294\ufe00', b'⊔︀'),
213 | ("'", "'", b"'"),
214 | ("|", "|", b"|"),
215 | ):
216 | markup = '<div>%s</div>' % input_element
217 | div = self.soup(markup).div
218 | without_element = div.encode()
219 | expect = b"<div>%s</div>" % output_unicode.encode("utf8")
220 | assert without_element == expect
221 |
222 | with_element = div.encode(formatter="html")
223 | expect = b"<div>%s</div>" % output_element
224 | assert with_element == expect
225 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/rich/markup.py:
--------------------------------------------------------------------------------
```python
1 | import re
2 | from ast import literal_eval
3 | from operator import attrgetter
4 | from typing import Callable, Iterable, List, Match, NamedTuple, Optional, Tuple, Union
5 |
6 | from ._emoji_replace import _emoji_replace
7 | from .emoji import EmojiVariant
8 | from .errors import MarkupError
9 | from .style import Style
10 | from .text import Span, Text
11 |
12 | RE_TAGS = re.compile(
13 | r"""((\\*)\[([a-z#/@][^[]*?)])""",
14 | re.VERBOSE,
15 | )
16 |
17 | RE_HANDLER = re.compile(r"^([\w.]*?)(\(.*?\))?$")
18 |
19 |
20 | class Tag(NamedTuple):
21 | """A tag in console markup."""
22 |
23 | name: str
24 | """The tag name. e.g. 'bold'."""
25 | parameters: Optional[str]
26 | """Any additional parameters after the name."""
27 |
28 | def __str__(self) -> str:
29 | return (
30 | self.name if self.parameters is None else f"{self.name} {self.parameters}"
31 | )
32 |
33 | @property
34 | def markup(self) -> str:
35 | """Get the string representation of this tag."""
36 | return (
37 | f"[{self.name}]"
38 | if self.parameters is None
39 | else f"[{self.name}={self.parameters}]"
40 | )
41 |
42 |
43 | _ReStringMatch = Match[str] # regex match object
44 | _ReSubCallable = Callable[[_ReStringMatch], str] # Callable invoked by re.sub
45 | _EscapeSubMethod = Callable[[_ReSubCallable, str], str] # Sub method of a compiled re
46 |
47 |
48 | def escape(
49 | markup: str,
50 | _escape: _EscapeSubMethod = re.compile(r"(\\*)(\[[a-z#/@][^[]*?])").sub,
51 | ) -> str:
52 | """Escapes text so that it won't be interpreted as markup.
53 |
54 | Args:
55 | markup (str): Content to be inserted in to markup.
56 |
57 | Returns:
58 | str: Markup with square brackets escaped.
59 | """
60 |
61 | def escape_backslashes(match: Match[str]) -> str:
62 | """Called by re.sub replace matches."""
63 | backslashes, text = match.groups()
64 | return f"{backslashes}{backslashes}\\{text}"
65 |
66 | markup = _escape(escape_backslashes, markup)
67 | if markup.endswith("\\") and not markup.endswith("\\\\"):
68 | return markup + "\\"
69 |
70 | return markup
71 |
72 |
73 | def _parse(markup: str) -> Iterable[Tuple[int, Optional[str], Optional[Tag]]]:
74 | """Parse markup in to an iterable of tuples of (position, text, tag).
75 |
76 | Args:
77 | markup (str): A string containing console markup
78 |
79 | """
80 | position = 0
81 | _divmod = divmod
82 | _Tag = Tag
83 | for match in RE_TAGS.finditer(markup):
84 | full_text, escapes, tag_text = match.groups()
85 | start, end = match.span()
86 | if start > position:
87 | yield start, markup[position:start], None
88 | if escapes:
89 | backslashes, escaped = _divmod(len(escapes), 2)
90 | if backslashes:
91 | # Literal backslashes
92 | yield start, "\\" * backslashes, None
93 | start += backslashes * 2
94 | if escaped:
95 | # Escape of tag
96 | yield start, full_text[len(escapes) :], None
97 | position = end
98 | continue
99 | text, equals, parameters = tag_text.partition("=")
100 | yield start, None, _Tag(text, parameters if equals else None)
101 | position = end
102 | if position < len(markup):
103 | yield position, markup[position:], None
104 |
105 |
106 | def render(
107 | markup: str,
108 | style: Union[str, Style] = "",
109 | emoji: bool = True,
110 | emoji_variant: Optional[EmojiVariant] = None,
111 | ) -> Text:
112 | """Render console markup in to a Text instance.
113 |
114 | Args:
115 | markup (str): A string containing console markup.
116 | style: (Union[str, Style]): The style to use.
117 | emoji (bool, optional): Also render emoji code. Defaults to True.
118 | emoji_variant (str, optional): Optional emoji variant, either "text" or "emoji". Defaults to None.
119 |
120 |
121 | Raises:
122 | MarkupError: If there is a syntax error in the markup.
123 |
124 | Returns:
125 | Text: A test instance.
126 | """
127 | emoji_replace = _emoji_replace
128 | if "[" not in markup:
129 | return Text(
130 | emoji_replace(markup, default_variant=emoji_variant) if emoji else markup,
131 | style=style,
132 | )
133 | text = Text(style=style)
134 | append = text.append
135 | normalize = Style.normalize
136 |
137 | style_stack: List[Tuple[int, Tag]] = []
138 | pop = style_stack.pop
139 |
140 | spans: List[Span] = []
141 | append_span = spans.append
142 |
143 | _Span = Span
144 | _Tag = Tag
145 |
146 | def pop_style(style_name: str) -> Tuple[int, Tag]:
147 | """Pop tag matching given style name."""
148 | for index, (_, tag) in enumerate(reversed(style_stack), 1):
149 | if tag.name == style_name:
150 | return pop(-index)
151 | raise KeyError(style_name)
152 |
153 | for position, plain_text, tag in _parse(markup):
154 | if plain_text is not None:
155 | # Handle open brace escapes, where the brace is not part of a tag.
156 | plain_text = plain_text.replace("\\[", "[")
157 | append(emoji_replace(plain_text) if emoji else plain_text)
158 | elif tag is not None:
159 | if tag.name.startswith("/"): # Closing tag
160 | style_name = tag.name[1:].strip()
161 |
162 | if style_name: # explicit close
163 | style_name = normalize(style_name)
164 | try:
165 | start, open_tag = pop_style(style_name)
166 | except KeyError:
167 | raise MarkupError(
168 | f"closing tag '{tag.markup}' at position {position} doesn't match any open tag"
169 | ) from None
170 | else: # implicit close
171 | try:
172 | start, open_tag = pop()
173 | except IndexError:
174 | raise MarkupError(
175 | f"closing tag '[/]' at position {position} has nothing to close"
176 | ) from None
177 |
178 | if open_tag.name.startswith("@"):
179 | if open_tag.parameters:
180 | handler_name = ""
181 | parameters = open_tag.parameters.strip()
182 | handler_match = RE_HANDLER.match(parameters)
183 | if handler_match is not None:
184 | handler_name, match_parameters = handler_match.groups()
185 | parameters = (
186 | "()" if match_parameters is None else match_parameters
187 | )
188 |
189 | try:
190 | meta_params = literal_eval(parameters)
191 | except SyntaxError as error:
192 | raise MarkupError(
193 | f"error parsing {parameters!r} in {open_tag.parameters!r}; {error.msg}"
194 | )
195 | except Exception as error:
196 | raise MarkupError(
197 | f"error parsing {open_tag.parameters!r}; {error}"
198 | ) from None
199 |
200 | if handler_name:
201 | meta_params = (
202 | handler_name,
203 | meta_params
204 | if isinstance(meta_params, tuple)
205 | else (meta_params,),
206 | )
207 |
208 | else:
209 | meta_params = ()
210 |
211 | append_span(
212 | _Span(
213 | start, len(text), Style(meta={open_tag.name: meta_params})
214 | )
215 | )
216 | else:
217 | append_span(_Span(start, len(text), str(open_tag)))
218 |
219 | else: # Opening tag
220 | normalized_tag = _Tag(normalize(tag.name), tag.parameters)
221 | style_stack.append((len(text), normalized_tag))
222 |
223 | text_length = len(text)
224 | while style_stack:
225 | start, tag = style_stack.pop()
226 | style = str(tag)
227 | if style:
228 | append_span(_Span(start, text_length, style))
229 |
230 | text.spans = sorted(spans[::-1], key=attrgetter("start"))
231 | return text
232 |
233 |
234 | if __name__ == "__main__": # pragma: no cover
235 | MARKUP = [
236 | "[red]Hello World[/red]",
237 | "[magenta]Hello [b]World[/b]",
238 | "[bold]Bold[italic] bold and italic [/bold]italic[/italic]",
239 | "Click [link=https://www.willmcgugan.com]here[/link] to visit my Blog",
240 | ":warning-emoji: [bold red blink] DANGER![/]",
241 | ]
242 |
243 | from pip._vendor.rich import print
244 | from pip._vendor.rich.table import Table
245 |
246 | grid = Table("Markup", "Result", padding=(0, 1))
247 |
248 | for markup in MARKUP:
249 | grid.add_row(Text(markup), markup)
250 |
251 | print(grid)
252 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/fake_useragent/fake.py:
--------------------------------------------------------------------------------
```python
1 | import random
2 |
3 | from fake_useragent import settings
4 | from fake_useragent.errors import FakeUserAgentError
5 | from fake_useragent.log import logger
6 | from fake_useragent.utils import load, str_types
7 |
8 |
9 | class FakeUserAgent:
10 | def __init__( # noqa: PLR0913
11 | self,
12 | browsers=["chrome", "edge", "firefox", "safari"],
13 | os=["windows", "macos", "linux", "android", "ios"],
14 | min_version=0.0,
15 | min_percentage=0.0,
16 | platforms=["pc", "mobile", "tablet"],
17 | fallback=(
18 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
19 | "AppleWebKit/537.36 (KHTML, like Gecko) "
20 | "Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"
21 | ),
22 | safe_attrs=tuple(),
23 | ):
24 | # Check inputs
25 | assert isinstance(browsers, (list, str)), "browsers must be list or string"
26 | if isinstance(browsers, str):
27 | browsers = [browsers]
28 | self.browsers = browsers
29 |
30 | assert isinstance(os, (list, str)), "OS must be list or string"
31 | if isinstance(os, str):
32 | os = [os]
33 | # OS replacement (windows -> [win10, win7])
34 | self.os = []
35 | for os_name in os:
36 | if os_name in settings.OS_REPLACEMENTS:
37 | self.os.extend(settings.OS_REPLACEMENTS[os_name])
38 | else:
39 | self.os.append(os_name)
40 |
41 | assert isinstance(
42 | min_percentage, (float, int)
43 | ), "Minimum usage percentage must be float or int"
44 | if isinstance(min_percentage, int):
45 | min_percentage = float(min_percentage)
46 | self.min_percentage = min_percentage
47 |
48 | assert isinstance(
49 | min_version, (float, int)
50 | ), "Minimum version must be float or int"
51 | if isinstance(min_version, int):
52 | min_version = float(min_version)
53 | self.min_version = min_version
54 |
55 | assert isinstance(platforms, (list, str)), "platforms must be list or string"
56 | if isinstance(platforms, str):
57 | platforms = [platforms]
58 | self.platforms = platforms
59 |
60 | assert isinstance(fallback, str), "fallback must be string"
61 | self.fallback = fallback
62 |
63 | assert isinstance(
64 | safe_attrs, (list, set, tuple)
65 | ), "safe_attrs must be list\\tuple\\set of strings or unicode"
66 |
67 | if safe_attrs:
68 | str_types_safe_attrs = [isinstance(attr, str_types) for attr in safe_attrs]
69 |
70 | assert all(
71 | str_types_safe_attrs
72 | ), "safe_attrs must be list\\tuple\\set of strings or unicode"
73 | self.safe_attrs = set(safe_attrs)
74 |
75 | # Next, load our local data file into memory (browsers.json)
76 | self.data_browsers = load()
77 |
78 | # This method will return a filtered list of user agents.
79 | # The request parameter can be used to specify a browser.
80 | def _filter_useragents(self, request=None):
81 | # filter based on browser, os, platform and version.
82 | filtered_useragents = list(
83 | filter(
84 | lambda x: x["browser"] in self.browsers
85 | and x["os"] in self.os
86 | and x["type"] in self.platforms
87 | and x["version"] >= self.min_version
88 | and x["percent"] >= self.min_percentage,
89 | self.data_browsers,
90 | )
91 | )
92 | # filter based on a specific browser request
93 | if request:
94 | filtered_useragents = list(
95 | filter(lambda x: x["browser"] == request, filtered_useragents)
96 | )
97 |
98 | return filtered_useragents
99 |
100 | # This method will return an object
101 | # Usage: ua.getBrowser('firefox')
102 | def getBrowser(self, request):
103 | try:
104 | # Handle request value
105 | for value, replacement in settings.REPLACEMENTS.items():
106 | request = request.replace(value, replacement)
107 | request = request.lower()
108 | request = settings.SHORTCUTS.get(request, request)
109 |
110 | if request == "random":
111 | # Filter the browser list based on the browsers array using lambda
112 | # And based on OS list
113 | # And percentage is bigger then min percentage
114 | # And convert the iterator back to a list
115 | filtered_browsers = self._filter_useragents()
116 | else:
117 | # Or when random isn't select, we filter the browsers array based on the 'request' using lamba
118 | # And based on OS list
119 | # And percentage is bigger then min percentage
120 | # And convert the iterator back to a list
121 | filtered_browsers = self._filter_useragents(request=request)
122 |
123 | # Pick a random browser user-agent from the filtered browsers
124 | # And return the full dict
125 | return random.choice(filtered_browsers) # noqa: S311
126 | except (KeyError, IndexError):
127 | if self.fallback is None:
128 | raise FakeUserAgentError(
129 | f"Error occurred during getting browser: {request}"
130 | ) # noqa
131 | else:
132 | logger.warning(
133 | f"Error occurred during getting browser: {request}, "
134 | "but was suppressed with fallback.",
135 | )
136 | # Return fallback object
137 | return {
138 | "useragent": self.fallback,
139 | "system": "Chrome 122.0 Win10",
140 | "browser": "chrome",
141 | "version": 122.0,
142 | "os": "win10",
143 | }
144 |
145 | # This method will use the method below, returning a string
146 | # Usage: ua['random']
147 | def __getitem__(self, attr):
148 | return self.__getattr__(attr)
149 |
150 | # This method will returns a string
151 | # Usage: ua.random
152 | def __getattr__(self, attr):
153 | if attr in self.safe_attrs:
154 | return super(UserAgent, self).__getattribute__(attr)
155 |
156 | try:
157 | # Handle input value
158 | for value, replacement in settings.REPLACEMENTS.items():
159 | attr = attr.replace(value, replacement)
160 | attr = attr.lower()
161 | attr = settings.SHORTCUTS.get(attr, attr)
162 |
163 | if attr == "random":
164 | # Filter the browser list based on the browsers array using lambda
165 | # And based on OS list
166 | # And percentage is bigger then min percentage
167 | # And convert the iterator back to a list
168 | filtered_browsers = self._filter_useragents()
169 | else:
170 | # Or when random isn't select, we filter the browsers array based on the 'attr' using lamba
171 | # And based on OS list
172 | # And percentage is bigger then min percentage
173 | # And convert the iterator back to a list
174 | filtered_browsers = self._filter_useragents(request=attr)
175 |
176 | # Pick a random browser user-agent from the filtered browsers
177 | # And return the useragent string.
178 | return random.choice(filtered_browsers).get("useragent") # noqa: S311
179 | except (KeyError, IndexError):
180 | if self.fallback is None:
181 | raise FakeUserAgentError(
182 | f"Error occurred during getting browser: {attr}"
183 | ) # noqa
184 | else:
185 | logger.warning(
186 | f"Error occurred during getting browser: {attr}, "
187 | "but was suppressed with fallback.",
188 | )
189 |
190 | return self.fallback
191 |
192 | @property
193 | def chrome(self):
194 | return self.__getattr__("chrome")
195 |
196 | @property
197 | def googlechrome(self):
198 | return self.chrome
199 |
200 | @property
201 | def edge(self):
202 | return self.__getattr__("edge")
203 |
204 | @property
205 | def firefox(self):
206 | return self.__getattr__("firefox")
207 |
208 | @property
209 | def ff(self):
210 | return self.firefox
211 |
212 | @property
213 | def safari(self):
214 | return self.__getattr__("safari")
215 |
216 | @property
217 | def random(self):
218 | return self.__getattr__("random")
219 |
220 | # The following 'get' methods return an object rather than only the UA string
221 | @property
222 | def getFirefox(self):
223 | return self.getBrowser("firefox")
224 |
225 | @property
226 | def getChrome(self):
227 | return self.getBrowser("chrome")
228 |
229 | @property
230 | def getEdge(self):
231 | return self.getBrowser("edge")
232 |
233 | @property
234 | def getSafari(self):
235 | return self.getBrowser("safari")
236 |
237 | @property
238 | def getRandom(self):
239 | return self.getBrowser("random")
240 |
241 |
242 | # common alias
243 | UserAgent = FakeUserAgent
244 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/lxml/ElementInclude.py:
--------------------------------------------------------------------------------
```python
1 | #
2 | # ElementTree
3 | # $Id: ElementInclude.py 1862 2004-06-18 07:31:02Z Fredrik $
4 | #
5 | # limited xinclude support for element trees
6 | #
7 | # history:
8 | # 2003-08-15 fl created
9 | # 2003-11-14 fl fixed default loader
10 | #
11 | # Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved.
12 | #
13 | # [email protected]
14 | # http://www.pythonware.com
15 | #
16 | # --------------------------------------------------------------------
17 | # The ElementTree toolkit is
18 | #
19 | # Copyright (c) 1999-2004 by Fredrik Lundh
20 | #
21 | # By obtaining, using, and/or copying this software and/or its
22 | # associated documentation, you agree that you have read, understood,
23 | # and will comply with the following terms and conditions:
24 | #
25 | # Permission to use, copy, modify, and distribute this software and
26 | # its associated documentation for any purpose and without fee is
27 | # hereby granted, provided that the above copyright notice appears in
28 | # all copies, and that both that copyright notice and this permission
29 | # notice appear in supporting documentation, and that the name of
30 | # Secret Labs AB or the author not be used in advertising or publicity
31 | # pertaining to distribution of the software without specific, written
32 | # prior permission.
33 | #
34 | # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
35 | # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
36 | # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
37 | # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
38 | # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39 | # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
40 | # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
41 | # OF THIS SOFTWARE.
42 | # --------------------------------------------------------------------
43 |
44 | """
45 | Limited XInclude support for the ElementTree package.
46 |
47 | While lxml.etree has full support for XInclude (see
48 | `etree.ElementTree.xinclude()`), this module provides a simpler, pure
49 | Python, ElementTree compatible implementation that supports a simple
50 | form of custom URL resolvers.
51 | """
52 |
53 | from lxml import etree
54 | try:
55 | from urlparse import urljoin
56 | from urllib2 import urlopen
57 | except ImportError:
58 | # Python 3
59 | from urllib.parse import urljoin
60 | from urllib.request import urlopen
61 |
62 | XINCLUDE = "{http://www.w3.org/2001/XInclude}"
63 |
64 | XINCLUDE_INCLUDE = XINCLUDE + "include"
65 | XINCLUDE_FALLBACK = XINCLUDE + "fallback"
66 | XINCLUDE_ITER_TAG = XINCLUDE + "*"
67 |
68 | # For security reasons, the inclusion depth is limited to this read-only value by default.
69 | DEFAULT_MAX_INCLUSION_DEPTH = 6
70 |
71 |
72 | ##
73 | # Fatal include error.
74 |
75 | class FatalIncludeError(etree.LxmlSyntaxError):
76 | pass
77 |
78 |
79 | class LimitedRecursiveIncludeError(FatalIncludeError):
80 | pass
81 |
82 |
83 | ##
84 | # ET compatible default loader.
85 | # This loader reads an included resource from disk.
86 | #
87 | # @param href Resource reference.
88 | # @param parse Parse mode. Either "xml" or "text".
89 | # @param encoding Optional text encoding.
90 | # @return The expanded resource. If the parse mode is "xml", this
91 | # is an ElementTree instance. If the parse mode is "text", this
92 | # is a Unicode string. If the loader fails, it can return None
93 | # or raise an IOError exception.
94 | # @throws IOError If the loader fails to load the resource.
95 |
96 | def default_loader(href, parse, encoding=None):
97 | file = open(href, 'rb')
98 | if parse == "xml":
99 | data = etree.parse(file).getroot()
100 | else:
101 | data = file.read()
102 | if not encoding:
103 | encoding = 'utf-8'
104 | data = data.decode(encoding)
105 | file.close()
106 | return data
107 |
108 |
109 | ##
110 | # Default loader used by lxml.etree - handles custom resolvers properly
111 | #
112 |
113 | def _lxml_default_loader(href, parse, encoding=None, parser=None):
114 | if parse == "xml":
115 | data = etree.parse(href, parser).getroot()
116 | else:
117 | if "://" in href:
118 | f = urlopen(href)
119 | else:
120 | f = open(href, 'rb')
121 | data = f.read()
122 | f.close()
123 | if not encoding:
124 | encoding = 'utf-8'
125 | data = data.decode(encoding)
126 | return data
127 |
128 |
129 | ##
130 | # Wrapper for ET compatibility - drops the parser
131 |
132 | def _wrap_et_loader(loader):
133 | def load(href, parse, encoding=None, parser=None):
134 | return loader(href, parse, encoding)
135 | return load
136 |
137 |
138 | ##
139 | # Expand XInclude directives.
140 | #
141 | # @param elem Root element.
142 | # @param loader Optional resource loader. If omitted, it defaults
143 | # to {@link default_loader}. If given, it should be a callable
144 | # that implements the same interface as <b>default_loader</b>.
145 | # @param base_url The base URL of the original file, to resolve
146 | # relative include file references.
147 | # @param max_depth The maximum number of recursive inclusions.
148 | # Limited to reduce the risk of malicious content explosion.
149 | # Pass None to disable the limitation.
150 | # @throws LimitedRecursiveIncludeError If the {@link max_depth} was exceeded.
151 | # @throws FatalIncludeError If the function fails to include a given
152 | # resource, or if the tree contains malformed XInclude elements.
153 | # @throws IOError If the function fails to load a given resource.
154 | # @returns the node or its replacement if it was an XInclude node
155 |
156 | def include(elem, loader=None, base_url=None,
157 | max_depth=DEFAULT_MAX_INCLUSION_DEPTH):
158 | if max_depth is None:
159 | max_depth = -1
160 | elif max_depth < 0:
161 | raise ValueError("expected non-negative depth or None for 'max_depth', got %r" % max_depth)
162 |
163 | if base_url is None:
164 | if hasattr(elem, 'getroot'):
165 | tree = elem
166 | elem = elem.getroot()
167 | else:
168 | tree = elem.getroottree()
169 | if hasattr(tree, 'docinfo'):
170 | base_url = tree.docinfo.URL
171 | elif hasattr(elem, 'getroot'):
172 | elem = elem.getroot()
173 | _include(elem, loader, base_url, max_depth)
174 |
175 |
176 | def _include(elem, loader=None, base_url=None,
177 | max_depth=DEFAULT_MAX_INCLUSION_DEPTH, _parent_hrefs=None):
178 | if loader is not None:
179 | load_include = _wrap_et_loader(loader)
180 | else:
181 | load_include = _lxml_default_loader
182 |
183 | if _parent_hrefs is None:
184 | _parent_hrefs = set()
185 |
186 | parser = elem.getroottree().parser
187 |
188 | include_elements = list(
189 | elem.iter(XINCLUDE_ITER_TAG))
190 |
191 | for e in include_elements:
192 | if e.tag == XINCLUDE_INCLUDE:
193 | # process xinclude directive
194 | href = urljoin(base_url, e.get("href"))
195 | parse = e.get("parse", "xml")
196 | parent = e.getparent()
197 | if parse == "xml":
198 | if href in _parent_hrefs:
199 | raise FatalIncludeError(
200 | "recursive include of %r detected" % href
201 | )
202 | if max_depth == 0:
203 | raise LimitedRecursiveIncludeError(
204 | "maximum xinclude depth reached when including file %s" % href)
205 | node = load_include(href, parse, parser=parser)
206 | if node is None:
207 | raise FatalIncludeError(
208 | "cannot load %r as %r" % (href, parse)
209 | )
210 | node = _include(node, loader, href, max_depth - 1, {href} | _parent_hrefs)
211 | if e.tail:
212 | node.tail = (node.tail or "") + e.tail
213 | if parent is None:
214 | return node # replaced the root node!
215 | parent.replace(e, node)
216 | elif parse == "text":
217 | text = load_include(href, parse, encoding=e.get("encoding"))
218 | if text is None:
219 | raise FatalIncludeError(
220 | "cannot load %r as %r" % (href, parse)
221 | )
222 | predecessor = e.getprevious()
223 | if predecessor is not None:
224 | predecessor.tail = (predecessor.tail or "") + text
225 | elif parent is None:
226 | return text # replaced the root node!
227 | else:
228 | parent.text = (parent.text or "") + text + (e.tail or "")
229 | parent.remove(e)
230 | else:
231 | raise FatalIncludeError(
232 | "unknown parse type in xi:include tag (%r)" % parse
233 | )
234 | elif e.tag == XINCLUDE_FALLBACK:
235 | parent = e.getparent()
236 | if parent is not None and parent.tag != XINCLUDE_INCLUDE:
237 | raise FatalIncludeError(
238 | "xi:fallback tag must be child of xi:include (%r)" % e.tag
239 | )
240 | else:
241 | raise FatalIncludeError(
242 | "Invalid element found in XInclude namespace (%r)" % e.tag
243 | )
244 | return elem
245 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/fields.py:
--------------------------------------------------------------------------------
```python
1 | from __future__ import absolute_import
2 |
3 | import email.utils
4 | import mimetypes
5 | import re
6 |
7 | from .packages import six
8 |
9 |
10 | def guess_content_type(filename, default="application/octet-stream"):
11 | """
12 | Guess the "Content-Type" of a file.
13 |
14 | :param filename:
15 | The filename to guess the "Content-Type" of using :mod:`mimetypes`.
16 | :param default:
17 | If no "Content-Type" can be guessed, default to `default`.
18 | """
19 | if filename:
20 | return mimetypes.guess_type(filename)[0] or default
21 | return default
22 |
23 |
24 | def format_header_param_rfc2231(name, value):
25 | """
26 | Helper function to format and quote a single header parameter using the
27 | strategy defined in RFC 2231.
28 |
29 | Particularly useful for header parameters which might contain
30 | non-ASCII values, like file names. This follows
31 | `RFC 2388 Section 4.4 <https://tools.ietf.org/html/rfc2388#section-4.4>`_.
32 |
33 | :param name:
34 | The name of the parameter, a string expected to be ASCII only.
35 | :param value:
36 | The value of the parameter, provided as ``bytes`` or `str``.
37 | :ret:
38 | An RFC-2231-formatted unicode string.
39 | """
40 | if isinstance(value, six.binary_type):
41 | value = value.decode("utf-8")
42 |
43 | if not any(ch in value for ch in '"\\\r\n'):
44 | result = u'%s="%s"' % (name, value)
45 | try:
46 | result.encode("ascii")
47 | except (UnicodeEncodeError, UnicodeDecodeError):
48 | pass
49 | else:
50 | return result
51 |
52 | if six.PY2: # Python 2:
53 | value = value.encode("utf-8")
54 |
55 | # encode_rfc2231 accepts an encoded string and returns an ascii-encoded
56 | # string in Python 2 but accepts and returns unicode strings in Python 3
57 | value = email.utils.encode_rfc2231(value, "utf-8")
58 | value = "%s*=%s" % (name, value)
59 |
60 | if six.PY2: # Python 2:
61 | value = value.decode("utf-8")
62 |
63 | return value
64 |
65 |
66 | _HTML5_REPLACEMENTS = {
67 | u"\u0022": u"%22",
68 | # Replace "\" with "\\".
69 | u"\u005C": u"\u005C\u005C",
70 | }
71 |
72 | # All control characters from 0x00 to 0x1F *except* 0x1B.
73 | _HTML5_REPLACEMENTS.update(
74 | {
75 | six.unichr(cc): u"%{:02X}".format(cc)
76 | for cc in range(0x00, 0x1F + 1)
77 | if cc not in (0x1B,)
78 | }
79 | )
80 |
81 |
82 | def _replace_multiple(value, needles_and_replacements):
83 | def replacer(match):
84 | return needles_and_replacements[match.group(0)]
85 |
86 | pattern = re.compile(
87 | r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()])
88 | )
89 |
90 | result = pattern.sub(replacer, value)
91 |
92 | return result
93 |
94 |
95 | def format_header_param_html5(name, value):
96 | """
97 | Helper function to format and quote a single header parameter using the
98 | HTML5 strategy.
99 |
100 | Particularly useful for header parameters which might contain
101 | non-ASCII values, like file names. This follows the `HTML5 Working Draft
102 | Section 4.10.22.7`_ and matches the behavior of curl and modern browsers.
103 |
104 | .. _HTML5 Working Draft Section 4.10.22.7:
105 | https://w3c.github.io/html/sec-forms.html#multipart-form-data
106 |
107 | :param name:
108 | The name of the parameter, a string expected to be ASCII only.
109 | :param value:
110 | The value of the parameter, provided as ``bytes`` or `str``.
111 | :ret:
112 | A unicode string, stripped of troublesome characters.
113 | """
114 | if isinstance(value, six.binary_type):
115 | value = value.decode("utf-8")
116 |
117 | value = _replace_multiple(value, _HTML5_REPLACEMENTS)
118 |
119 | return u'%s="%s"' % (name, value)
120 |
121 |
122 | # For backwards-compatibility.
123 | format_header_param = format_header_param_html5
124 |
125 |
126 | class RequestField(object):
127 | """
128 | A data container for request body parameters.
129 |
130 | :param name:
131 | The name of this request field. Must be unicode.
132 | :param data:
133 | The data/value body.
134 | :param filename:
135 | An optional filename of the request field. Must be unicode.
136 | :param headers:
137 | An optional dict-like object of headers to initially use for the field.
138 | :param header_formatter:
139 | An optional callable that is used to encode and format the headers. By
140 | default, this is :func:`format_header_param_html5`.
141 | """
142 |
143 | def __init__(
144 | self,
145 | name,
146 | data,
147 | filename=None,
148 | headers=None,
149 | header_formatter=format_header_param_html5,
150 | ):
151 | self._name = name
152 | self._filename = filename
153 | self.data = data
154 | self.headers = {}
155 | if headers:
156 | self.headers = dict(headers)
157 | self.header_formatter = header_formatter
158 |
159 | @classmethod
160 | def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5):
161 | """
162 | A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
163 |
164 | Supports constructing :class:`~urllib3.fields.RequestField` from
165 | parameter of key/value strings AND key/filetuple. A filetuple is a
166 | (filename, data, MIME type) tuple where the MIME type is optional.
167 | For example::
168 |
169 | 'foo': 'bar',
170 | 'fakefile': ('foofile.txt', 'contents of foofile'),
171 | 'realfile': ('barfile.txt', open('realfile').read()),
172 | 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
173 | 'nonamefile': 'contents of nonamefile field',
174 |
175 | Field names and filenames must be unicode.
176 | """
177 | if isinstance(value, tuple):
178 | if len(value) == 3:
179 | filename, data, content_type = value
180 | else:
181 | filename, data = value
182 | content_type = guess_content_type(filename)
183 | else:
184 | filename = None
185 | content_type = None
186 | data = value
187 |
188 | request_param = cls(
189 | fieldname, data, filename=filename, header_formatter=header_formatter
190 | )
191 | request_param.make_multipart(content_type=content_type)
192 |
193 | return request_param
194 |
195 | def _render_part(self, name, value):
196 | """
197 | Overridable helper function to format a single header parameter. By
198 | default, this calls ``self.header_formatter``.
199 |
200 | :param name:
201 | The name of the parameter, a string expected to be ASCII only.
202 | :param value:
203 | The value of the parameter, provided as a unicode string.
204 | """
205 |
206 | return self.header_formatter(name, value)
207 |
208 | def _render_parts(self, header_parts):
209 | """
210 | Helper function to format and quote a single header.
211 |
212 | Useful for single headers that are composed of multiple items. E.g.,
213 | 'Content-Disposition' fields.
214 |
215 | :param header_parts:
216 | A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format
217 | as `k1="v1"; k2="v2"; ...`.
218 | """
219 | parts = []
220 | iterable = header_parts
221 | if isinstance(header_parts, dict):
222 | iterable = header_parts.items()
223 |
224 | for name, value in iterable:
225 | if value is not None:
226 | parts.append(self._render_part(name, value))
227 |
228 | return u"; ".join(parts)
229 |
230 | def render_headers(self):
231 | """
232 | Renders the headers for this request field.
233 | """
234 | lines = []
235 |
236 | sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"]
237 | for sort_key in sort_keys:
238 | if self.headers.get(sort_key, False):
239 | lines.append(u"%s: %s" % (sort_key, self.headers[sort_key]))
240 |
241 | for header_name, header_value in self.headers.items():
242 | if header_name not in sort_keys:
243 | if header_value:
244 | lines.append(u"%s: %s" % (header_name, header_value))
245 |
246 | lines.append(u"\r\n")
247 | return u"\r\n".join(lines)
248 |
249 | def make_multipart(
250 | self, content_disposition=None, content_type=None, content_location=None
251 | ):
252 | """
253 | Makes this request field into a multipart request field.
254 |
255 | This method overrides "Content-Disposition", "Content-Type" and
256 | "Content-Location" headers to the request parameter.
257 |
258 | :param content_type:
259 | The 'Content-Type' of the request body.
260 | :param content_location:
261 | The 'Content-Location' of the request body.
262 |
263 | """
264 | self.headers["Content-Disposition"] = content_disposition or u"form-data"
265 | self.headers["Content-Disposition"] += u"; ".join(
266 | [
267 | u"",
268 | self._render_parts(
269 | ((u"name", self._name), (u"filename", self._filename))
270 | ),
271 | ]
272 | )
273 | self.headers["Content-Type"] = content_type
274 | self.headers["Content-Location"] = content_location
275 |
```
--------------------------------------------------------------------------------
/.venv/lib/python3.12/site-packages/lxml/html/html5parser.py:
--------------------------------------------------------------------------------
```python
1 | """
2 | An interface to html5lib that mimics the lxml.html interface.
3 | """
4 | import sys
5 | import string
6 |
7 | from html5lib import HTMLParser as _HTMLParser
8 | from html5lib.treebuilders.etree_lxml import TreeBuilder
9 | from lxml import etree
10 | from lxml.html import Element, XHTML_NAMESPACE, _contains_block_level_tag
11 |
12 | # python3 compatibility
13 | try:
14 | _strings = basestring
15 | except NameError:
16 | _strings = (bytes, str)
17 | try:
18 | from urllib2 import urlopen
19 | except ImportError:
20 | from urllib.request import urlopen
21 | try:
22 | from urlparse import urlparse
23 | except ImportError:
24 | from urllib.parse import urlparse
25 |
26 |
27 | class HTMLParser(_HTMLParser):
28 | """An html5lib HTML parser with lxml as tree."""
29 |
30 | def __init__(self, strict=False, **kwargs):
31 | _HTMLParser.__init__(self, strict=strict, tree=TreeBuilder, **kwargs)
32 |
33 |
34 | try:
35 | from html5lib import XHTMLParser as _XHTMLParser
36 | except ImportError:
37 | pass
38 | else:
39 | class XHTMLParser(_XHTMLParser):
40 | """An html5lib XHTML Parser with lxml as tree."""
41 |
42 | def __init__(self, strict=False, **kwargs):
43 | _XHTMLParser.__init__(self, strict=strict, tree=TreeBuilder, **kwargs)
44 |
45 | xhtml_parser = XHTMLParser()
46 |
47 |
48 | def _find_tag(tree, tag):
49 | elem = tree.find(tag)
50 | if elem is not None:
51 | return elem
52 | return tree.find('{%s}%s' % (XHTML_NAMESPACE, tag))
53 |
54 |
55 | def document_fromstring(html, guess_charset=None, parser=None):
56 | """
57 | Parse a whole document into a string.
58 |
59 | If `guess_charset` is true, or if the input is not Unicode but a
60 | byte string, the `chardet` library will perform charset guessing
61 | on the string.
62 | """
63 | if not isinstance(html, _strings):
64 | raise TypeError('string required')
65 |
66 | if parser is None:
67 | parser = html_parser
68 |
69 | options = {}
70 | if guess_charset is None and isinstance(html, bytes):
71 | # html5lib does not accept useChardet as an argument, if it
72 | # detected the html argument would produce unicode objects.
73 | guess_charset = True
74 | if guess_charset is not None:
75 | options['useChardet'] = guess_charset
76 | return parser.parse(html, **options).getroot()
77 |
78 |
79 | def fragments_fromstring(html, no_leading_text=False,
80 | guess_charset=None, parser=None):
81 | """Parses several HTML elements, returning a list of elements.
82 |
83 | The first item in the list may be a string. If no_leading_text is true,
84 | then it will be an error if there is leading text, and it will always be
85 | a list of only elements.
86 |
87 | If `guess_charset` is true, the `chardet` library will perform charset
88 | guessing on the string.
89 | """
90 | if not isinstance(html, _strings):
91 | raise TypeError('string required')
92 |
93 | if parser is None:
94 | parser = html_parser
95 |
96 | options = {}
97 | if guess_charset is None and isinstance(html, bytes):
98 | # html5lib does not accept useChardet as an argument, if it
99 | # detected the html argument would produce unicode objects.
100 | guess_charset = False
101 | if guess_charset is not None:
102 | options['useChardet'] = guess_charset
103 | children = parser.parseFragment(html, 'div', **options)
104 | if children and isinstance(children[0], _strings):
105 | if no_leading_text:
106 | if children[0].strip():
107 | raise etree.ParserError('There is leading text: %r' %
108 | children[0])
109 | del children[0]
110 | return children
111 |
112 |
113 | def fragment_fromstring(html, create_parent=False,
114 | guess_charset=None, parser=None):
115 | """Parses a single HTML element; it is an error if there is more than
116 | one element, or if anything but whitespace precedes or follows the
117 | element.
118 |
119 | If 'create_parent' is true (or is a tag name) then a parent node
120 | will be created to encapsulate the HTML in a single element. In
121 | this case, leading or trailing text is allowed.
122 |
123 | If `guess_charset` is true, the `chardet` library will perform charset
124 | guessing on the string.
125 | """
126 | if not isinstance(html, _strings):
127 | raise TypeError('string required')
128 |
129 | accept_leading_text = bool(create_parent)
130 |
131 | elements = fragments_fromstring(
132 | html, guess_charset=guess_charset, parser=parser,
133 | no_leading_text=not accept_leading_text)
134 |
135 | if create_parent:
136 | if not isinstance(create_parent, _strings):
137 | create_parent = 'div'
138 | new_root = Element(create_parent)
139 | if elements:
140 | if isinstance(elements[0], _strings):
141 | new_root.text = elements[0]
142 | del elements[0]
143 | new_root.extend(elements)
144 | return new_root
145 |
146 | if not elements:
147 | raise etree.ParserError('No elements found')
148 | if len(elements) > 1:
149 | raise etree.ParserError('Multiple elements found')
150 | result = elements[0]
151 | if result.tail and result.tail.strip():
152 | raise etree.ParserError('Element followed by text: %r' % result.tail)
153 | result.tail = None
154 | return result
155 |
156 |
157 | def fromstring(html, guess_charset=None, parser=None):
158 | """Parse the html, returning a single element/document.
159 |
160 | This tries to minimally parse the chunk of text, without knowing if it
161 | is a fragment or a document.
162 |
163 | 'base_url' will set the document's base_url attribute (and the tree's
164 | docinfo.URL)
165 |
166 | If `guess_charset` is true, or if the input is not Unicode but a
167 | byte string, the `chardet` library will perform charset guessing
168 | on the string.
169 | """
170 | if not isinstance(html, _strings):
171 | raise TypeError('string required')
172 | doc = document_fromstring(html, parser=parser,
173 | guess_charset=guess_charset)
174 |
175 | # document starts with doctype or <html>, full document!
176 | start = html[:50]
177 | if isinstance(start, bytes):
178 | # Allow text comparison in python3.
179 | # Decode as ascii, that also covers latin-1 and utf-8 for the
180 | # characters we need.
181 | start = start.decode('ascii', 'replace')
182 |
183 | start = start.lstrip().lower()
184 | if start.startswith('<html') or start.startswith('<!doctype'):
185 | return doc
186 |
187 | head = _find_tag(doc, 'head')
188 |
189 | # if the head is not empty we have a full document
190 | if len(head):
191 | return doc
192 |
193 | body = _find_tag(doc, 'body')
194 |
195 | # The body has just one element, so it was probably a single
196 | # element passed in
197 | if (len(body) == 1 and (not body.text or not body.text.strip())
198 | and (not body[-1].tail or not body[-1].tail.strip())):
199 | return body[0]
200 |
201 | # Now we have a body which represents a bunch of tags which have the
202 | # content that was passed in. We will create a fake container, which
203 | # is the body tag, except <body> implies too much structure.
204 | if _contains_block_level_tag(body):
205 | body.tag = 'div'
206 | else:
207 | body.tag = 'span'
208 | return body
209 |
210 |
211 | def parse(filename_url_or_file, guess_charset=None, parser=None):
212 | """Parse a filename, URL, or file-like object into an HTML document
213 | tree. Note: this returns a tree, not an element. Use
214 | ``parse(...).getroot()`` to get the document root.
215 |
216 | If ``guess_charset`` is true, the ``useChardet`` option is passed into
217 | html5lib to enable character detection. This option is on by default
218 | when parsing from URLs, off by default when parsing from file(-like)
219 | objects (which tend to return Unicode more often than not), and on by
220 | default when parsing from a file path (which is read in binary mode).
221 | """
222 | if parser is None:
223 | parser = html_parser
224 | if not isinstance(filename_url_or_file, _strings):
225 | fp = filename_url_or_file
226 | if guess_charset is None:
227 | # assume that file-like objects return Unicode more often than bytes
228 | guess_charset = False
229 | elif _looks_like_url(filename_url_or_file):
230 | fp = urlopen(filename_url_or_file)
231 | if guess_charset is None:
232 | # assume that URLs return bytes
233 | guess_charset = True
234 | else:
235 | fp = open(filename_url_or_file, 'rb')
236 | if guess_charset is None:
237 | guess_charset = True
238 |
239 | options = {}
240 | # html5lib does not accept useChardet as an argument, if it
241 | # detected the html argument would produce unicode objects.
242 | if guess_charset:
243 | options['useChardet'] = guess_charset
244 | return parser.parse(fp, **options)
245 |
246 |
247 | def _looks_like_url(str):
248 | scheme = urlparse(str)[0]
249 | if not scheme:
250 | return False
251 | elif (sys.platform == 'win32' and
252 | scheme in string.ascii_letters
253 | and len(scheme) == 1):
254 | # looks like a 'normal' absolute path
255 | return False
256 | else:
257 | return True
258 |
259 |
260 | html_parser = HTMLParser()
261 |
```