#
tokens: 47069/50000 1/808 files (page 135/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 135 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/werkzeug/http.py:
--------------------------------------------------------------------------------

```python
   1 | from __future__ import annotations
   2 | 
   3 | import email.utils
   4 | import re
   5 | import typing as t
   6 | import warnings
   7 | from datetime import date
   8 | from datetime import datetime
   9 | from datetime import time
  10 | from datetime import timedelta
  11 | from datetime import timezone
  12 | from enum import Enum
  13 | from hashlib import sha1
  14 | from time import mktime
  15 | from time import struct_time
  16 | from urllib.parse import quote
  17 | from urllib.parse import unquote
  18 | from urllib.request import parse_http_list as _parse_list_header
  19 | 
  20 | from ._internal import _dt_as_utc
  21 | from ._internal import _plain_int
  22 | 
  23 | if t.TYPE_CHECKING:
  24 |     from _typeshed.wsgi import WSGIEnvironment
  25 | 
  26 | _token_chars = frozenset(
  27 |     "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"
  28 | )
  29 | _etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)')
  30 | _entity_headers = frozenset(
  31 |     [
  32 |         "allow",
  33 |         "content-encoding",
  34 |         "content-language",
  35 |         "content-length",
  36 |         "content-location",
  37 |         "content-md5",
  38 |         "content-range",
  39 |         "content-type",
  40 |         "expires",
  41 |         "last-modified",
  42 |     ]
  43 | )
  44 | _hop_by_hop_headers = frozenset(
  45 |     [
  46 |         "connection",
  47 |         "keep-alive",
  48 |         "proxy-authenticate",
  49 |         "proxy-authorization",
  50 |         "te",
  51 |         "trailer",
  52 |         "transfer-encoding",
  53 |         "upgrade",
  54 |     ]
  55 | )
  56 | HTTP_STATUS_CODES = {
  57 |     100: "Continue",
  58 |     101: "Switching Protocols",
  59 |     102: "Processing",
  60 |     103: "Early Hints",  # see RFC 8297
  61 |     200: "OK",
  62 |     201: "Created",
  63 |     202: "Accepted",
  64 |     203: "Non Authoritative Information",
  65 |     204: "No Content",
  66 |     205: "Reset Content",
  67 |     206: "Partial Content",
  68 |     207: "Multi Status",
  69 |     208: "Already Reported",  # see RFC 5842
  70 |     226: "IM Used",  # see RFC 3229
  71 |     300: "Multiple Choices",
  72 |     301: "Moved Permanently",
  73 |     302: "Found",
  74 |     303: "See Other",
  75 |     304: "Not Modified",
  76 |     305: "Use Proxy",
  77 |     306: "Switch Proxy",  # unused
  78 |     307: "Temporary Redirect",
  79 |     308: "Permanent Redirect",
  80 |     400: "Bad Request",
  81 |     401: "Unauthorized",
  82 |     402: "Payment Required",  # unused
  83 |     403: "Forbidden",
  84 |     404: "Not Found",
  85 |     405: "Method Not Allowed",
  86 |     406: "Not Acceptable",
  87 |     407: "Proxy Authentication Required",
  88 |     408: "Request Timeout",
  89 |     409: "Conflict",
  90 |     410: "Gone",
  91 |     411: "Length Required",
  92 |     412: "Precondition Failed",
  93 |     413: "Request Entity Too Large",
  94 |     414: "Request URI Too Long",
  95 |     415: "Unsupported Media Type",
  96 |     416: "Requested Range Not Satisfiable",
  97 |     417: "Expectation Failed",
  98 |     418: "I'm a teapot",  # see RFC 2324
  99 |     421: "Misdirected Request",  # see RFC 7540
 100 |     422: "Unprocessable Entity",
 101 |     423: "Locked",
 102 |     424: "Failed Dependency",
 103 |     425: "Too Early",  # see RFC 8470
 104 |     426: "Upgrade Required",
 105 |     428: "Precondition Required",  # see RFC 6585
 106 |     429: "Too Many Requests",
 107 |     431: "Request Header Fields Too Large",
 108 |     449: "Retry With",  # proprietary MS extension
 109 |     451: "Unavailable For Legal Reasons",
 110 |     500: "Internal Server Error",
 111 |     501: "Not Implemented",
 112 |     502: "Bad Gateway",
 113 |     503: "Service Unavailable",
 114 |     504: "Gateway Timeout",
 115 |     505: "HTTP Version Not Supported",
 116 |     506: "Variant Also Negotiates",  # see RFC 2295
 117 |     507: "Insufficient Storage",
 118 |     508: "Loop Detected",  # see RFC 5842
 119 |     510: "Not Extended",
 120 |     511: "Network Authentication Failed",
 121 | }
 122 | 
 123 | 
 124 | class COEP(Enum):
 125 |     """Cross Origin Embedder Policies"""
 126 | 
 127 |     UNSAFE_NONE = "unsafe-none"
 128 |     REQUIRE_CORP = "require-corp"
 129 | 
 130 | 
 131 | class COOP(Enum):
 132 |     """Cross Origin Opener Policies"""
 133 | 
 134 |     UNSAFE_NONE = "unsafe-none"
 135 |     SAME_ORIGIN_ALLOW_POPUPS = "same-origin-allow-popups"
 136 |     SAME_ORIGIN = "same-origin"
 137 | 
 138 | 
 139 | def quote_header_value(value: t.Any, allow_token: bool = True) -> str:
 140 |     """Add double quotes around a header value. If the header contains only ASCII token
 141 |     characters, it will be returned unchanged. If the header contains ``"`` or ``\\``
 142 |     characters, they will be escaped with an additional ``\\`` character.
 143 | 
 144 |     This is the reverse of :func:`unquote_header_value`.
 145 | 
 146 |     :param value: The value to quote. Will be converted to a string.
 147 |     :param allow_token: Disable to quote the value even if it only has token characters.
 148 | 
 149 |     .. versionchanged:: 3.0
 150 |         Passing bytes is not supported.
 151 | 
 152 |     .. versionchanged:: 3.0
 153 |         The ``extra_chars`` parameter is removed.
 154 | 
 155 |     .. versionchanged:: 2.3
 156 |         The value is quoted if it is the empty string.
 157 | 
 158 |     .. versionadded:: 0.5
 159 |     """
 160 |     value_str = str(value)
 161 | 
 162 |     if not value_str:
 163 |         return '""'
 164 | 
 165 |     if allow_token:
 166 |         token_chars = _token_chars
 167 | 
 168 |         if token_chars.issuperset(value_str):
 169 |             return value_str
 170 | 
 171 |     value_str = value_str.replace("\\", "\\\\").replace('"', '\\"')
 172 |     return f'"{value_str}"'
 173 | 
 174 | 
 175 | def unquote_header_value(value: str) -> str:
 176 |     """Remove double quotes and decode slash-escaped ``"`` and ``\\`` characters in a
 177 |     header value.
 178 | 
 179 |     This is the reverse of :func:`quote_header_value`.
 180 | 
 181 |     :param value: The header value to unquote.
 182 | 
 183 |     .. versionchanged:: 3.0
 184 |         The ``is_filename`` parameter is removed.
 185 |     """
 186 |     if len(value) >= 2 and value[0] == value[-1] == '"':
 187 |         value = value[1:-1]
 188 |         return value.replace("\\\\", "\\").replace('\\"', '"')
 189 | 
 190 |     return value
 191 | 
 192 | 
 193 | def dump_options_header(header: str | None, options: t.Mapping[str, t.Any]) -> str:
 194 |     """Produce a header value and ``key=value`` parameters separated by semicolons
 195 |     ``;``. For example, the ``Content-Type`` header.
 196 | 
 197 |     .. code-block:: python
 198 | 
 199 |         dump_options_header("text/html", {"charset": "UTF-8"})
 200 |         'text/html; charset=UTF-8'
 201 | 
 202 |     This is the reverse of :func:`parse_options_header`.
 203 | 
 204 |     If a value contains non-token characters, it will be quoted.
 205 | 
 206 |     If a value is ``None``, the parameter is skipped.
 207 | 
 208 |     In some keys for some headers, a UTF-8 value can be encoded using a special
 209 |     ``key*=UTF-8''value`` form, where ``value`` is percent encoded. This function will
 210 |     not produce that format automatically, but if a given key ends with an asterisk
 211 |     ``*``, the value is assumed to have that form and will not be quoted further.
 212 | 
 213 |     :param header: The primary header value.
 214 |     :param options: Parameters to encode as ``key=value`` pairs.
 215 | 
 216 |     .. versionchanged:: 2.3
 217 |         Keys with ``None`` values are skipped rather than treated as a bare key.
 218 | 
 219 |     .. versionchanged:: 2.2.3
 220 |         If a key ends with ``*``, its value will not be quoted.
 221 |     """
 222 |     segments = []
 223 | 
 224 |     if header is not None:
 225 |         segments.append(header)
 226 | 
 227 |     for key, value in options.items():
 228 |         if value is None:
 229 |             continue
 230 | 
 231 |         if key[-1] == "*":
 232 |             segments.append(f"{key}={value}")
 233 |         else:
 234 |             segments.append(f"{key}={quote_header_value(value)}")
 235 | 
 236 |     return "; ".join(segments)
 237 | 
 238 | 
 239 | def dump_header(iterable: dict[str, t.Any] | t.Iterable[t.Any]) -> str:
 240 |     """Produce a header value from a list of items or ``key=value`` pairs, separated by
 241 |     commas ``,``.
 242 | 
 243 |     This is the reverse of :func:`parse_list_header`, :func:`parse_dict_header`, and
 244 |     :func:`parse_set_header`.
 245 | 
 246 |     If a value contains non-token characters, it will be quoted.
 247 | 
 248 |     If a value is ``None``, the key is output alone.
 249 | 
 250 |     In some keys for some headers, a UTF-8 value can be encoded using a special
 251 |     ``key*=UTF-8''value`` form, where ``value`` is percent encoded. This function will
 252 |     not produce that format automatically, but if a given key ends with an asterisk
 253 |     ``*``, the value is assumed to have that form and will not be quoted further.
 254 | 
 255 |     .. code-block:: python
 256 | 
 257 |         dump_header(["foo", "bar baz"])
 258 |         'foo, "bar baz"'
 259 | 
 260 |         dump_header({"foo": "bar baz"})
 261 |         'foo="bar baz"'
 262 | 
 263 |     :param iterable: The items to create a header from.
 264 | 
 265 |     .. versionchanged:: 3.0
 266 |         The ``allow_token`` parameter is removed.
 267 | 
 268 |     .. versionchanged:: 2.2.3
 269 |         If a key ends with ``*``, its value will not be quoted.
 270 |     """
 271 |     if isinstance(iterable, dict):
 272 |         items = []
 273 | 
 274 |         for key, value in iterable.items():
 275 |             if value is None:
 276 |                 items.append(key)
 277 |             elif key[-1] == "*":
 278 |                 items.append(f"{key}={value}")
 279 |             else:
 280 |                 items.append(f"{key}={quote_header_value(value)}")
 281 |     else:
 282 |         items = [quote_header_value(x) for x in iterable]
 283 | 
 284 |     return ", ".join(items)
 285 | 
 286 | 
 287 | def dump_csp_header(header: ds.ContentSecurityPolicy) -> str:
 288 |     """Dump a Content Security Policy header.
 289 | 
 290 |     These are structured into policies such as "default-src 'self';
 291 |     script-src 'self'".
 292 | 
 293 |     .. versionadded:: 1.0.0
 294 |        Support for Content Security Policy headers was added.
 295 | 
 296 |     """
 297 |     return "; ".join(f"{key} {value}" for key, value in header.items())
 298 | 
 299 | 
 300 | def parse_list_header(value: str) -> list[str]:
 301 |     """Parse a header value that consists of a list of comma separated items according
 302 |     to `RFC 9110 <https://httpwg.org/specs/rfc9110.html#abnf.extension>`__.
 303 | 
 304 |     This extends :func:`urllib.request.parse_http_list` to remove surrounding quotes
 305 |     from values.
 306 | 
 307 |     .. code-block:: python
 308 | 
 309 |         parse_list_header('token, "quoted value"')
 310 |         ['token', 'quoted value']
 311 | 
 312 |     This is the reverse of :func:`dump_header`.
 313 | 
 314 |     :param value: The header value to parse.
 315 |     """
 316 |     result = []
 317 | 
 318 |     for item in _parse_list_header(value):
 319 |         if len(item) >= 2 and item[0] == item[-1] == '"':
 320 |             item = item[1:-1]
 321 | 
 322 |         result.append(item)
 323 | 
 324 |     return result
 325 | 
 326 | 
 327 | def parse_dict_header(value: str) -> dict[str, str | None]:
 328 |     """Parse a list header using :func:`parse_list_header`, then parse each item as a
 329 |     ``key=value`` pair.
 330 | 
 331 |     .. code-block:: python
 332 | 
 333 |         parse_dict_header('a=b, c="d, e", f')
 334 |         {"a": "b", "c": "d, e", "f": None}
 335 | 
 336 |     This is the reverse of :func:`dump_header`.
 337 | 
 338 |     If a key does not have a value, it is ``None``.
 339 | 
 340 |     This handles charsets for values as described in
 341 |     `RFC 2231 <https://www.rfc-editor.org/rfc/rfc2231#section-3>`__. Only ASCII, UTF-8,
 342 |     and ISO-8859-1 charsets are accepted, otherwise the value remains quoted.
 343 | 
 344 |     :param value: The header value to parse.
 345 | 
 346 |     .. versionchanged:: 3.0
 347 |         Passing bytes is not supported.
 348 | 
 349 |     .. versionchanged:: 3.0
 350 |         The ``cls`` argument is removed.
 351 | 
 352 |     .. versionchanged:: 2.3
 353 |         Added support for ``key*=charset''value`` encoded items.
 354 | 
 355 |     .. versionchanged:: 0.9
 356 |        The ``cls`` argument was added.
 357 |     """
 358 |     result: dict[str, str | None] = {}
 359 | 
 360 |     for item in parse_list_header(value):
 361 |         key, has_value, value = item.partition("=")
 362 |         key = key.strip()
 363 | 
 364 |         if not has_value:
 365 |             result[key] = None
 366 |             continue
 367 | 
 368 |         value = value.strip()
 369 |         encoding: str | None = None
 370 | 
 371 |         if key[-1] == "*":
 372 |             # key*=charset''value becomes key=value, where value is percent encoded
 373 |             # adapted from parse_options_header, without the continuation handling
 374 |             key = key[:-1]
 375 |             match = _charset_value_re.match(value)
 376 | 
 377 |             if match:
 378 |                 # If there is a charset marker in the value, split it off.
 379 |                 encoding, value = match.groups()
 380 |                 encoding = encoding.lower()
 381 | 
 382 |             # A safe list of encodings. Modern clients should only send ASCII or UTF-8.
 383 |             # This list will not be extended further. An invalid encoding will leave the
 384 |             # value quoted.
 385 |             if encoding in {"ascii", "us-ascii", "utf-8", "iso-8859-1"}:
 386 |                 # invalid bytes are replaced during unquoting
 387 |                 value = unquote(value, encoding=encoding)
 388 | 
 389 |         if len(value) >= 2 and value[0] == value[-1] == '"':
 390 |             value = value[1:-1]
 391 | 
 392 |         result[key] = value
 393 | 
 394 |     return result
 395 | 
 396 | 
 397 | # https://httpwg.org/specs/rfc9110.html#parameter
 398 | _parameter_key_re = re.compile(r"([\w!#$%&'*+\-.^`|~]+)=", flags=re.ASCII)
 399 | _parameter_token_value_re = re.compile(r"[\w!#$%&'*+\-.^`|~]+", flags=re.ASCII)
 400 | # https://www.rfc-editor.org/rfc/rfc2231#section-4
 401 | _charset_value_re = re.compile(
 402 |     r"""
 403 |     ([\w!#$%&*+\-.^`|~]*)'  # charset part, could be empty
 404 |     [\w!#$%&*+\-.^`|~]*'  # don't care about language part, usually empty
 405 |     ([\w!#$%&'*+\-.^`|~]+)  # one or more token chars with percent encoding
 406 |     """,
 407 |     re.ASCII | re.VERBOSE,
 408 | )
 409 | # https://www.rfc-editor.org/rfc/rfc2231#section-3
 410 | _continuation_re = re.compile(r"\*(\d+)$", re.ASCII)
 411 | 
 412 | 
 413 | def parse_options_header(value: str | None) -> tuple[str, dict[str, str]]:
 414 |     """Parse a header that consists of a value with ``key=value`` parameters separated
 415 |     by semicolons ``;``. For example, the ``Content-Type`` header.
 416 | 
 417 |     .. code-block:: python
 418 | 
 419 |         parse_options_header("text/html; charset=UTF-8")
 420 |         ('text/html', {'charset': 'UTF-8'})
 421 | 
 422 |         parse_options_header("")
 423 |         ("", {})
 424 | 
 425 |     This is the reverse of :func:`dump_options_header`.
 426 | 
 427 |     This parses valid parameter parts as described in
 428 |     `RFC 9110 <https://httpwg.org/specs/rfc9110.html#parameter>`__. Invalid parts are
 429 |     skipped.
 430 | 
 431 |     This handles continuations and charsets as described in
 432 |     `RFC 2231 <https://www.rfc-editor.org/rfc/rfc2231#section-3>`__, although not as
 433 |     strictly as the RFC. Only ASCII, UTF-8, and ISO-8859-1 charsets are accepted,
 434 |     otherwise the value remains quoted.
 435 | 
 436 |     Clients may not be consistent in how they handle a quote character within a quoted
 437 |     value. The `HTML Standard <https://html.spec.whatwg.org/#multipart-form-data>`__
 438 |     replaces it with ``%22`` in multipart form data.
 439 |     `RFC 9110 <https://httpwg.org/specs/rfc9110.html#quoted.strings>`__ uses backslash
 440 |     escapes in HTTP headers. Both are decoded to the ``"`` character.
 441 | 
 442 |     Clients may not be consistent in how they handle non-ASCII characters. HTML
 443 |     documents must declare ``<meta charset=UTF-8>``, otherwise browsers may replace with
 444 |     HTML character references, which can be decoded using :func:`html.unescape`.
 445 | 
 446 |     :param value: The header value to parse.
 447 |     :return: ``(value, options)``, where ``options`` is a dict
 448 | 
 449 |     .. versionchanged:: 2.3
 450 |         Invalid parts, such as keys with no value, quoted keys, and incorrectly quoted
 451 |         values, are discarded instead of treating as ``None``.
 452 | 
 453 |     .. versionchanged:: 2.3
 454 |         Only ASCII, UTF-8, and ISO-8859-1 are accepted for charset values.
 455 | 
 456 |     .. versionchanged:: 2.3
 457 |         Escaped quotes in quoted values, like ``%22`` and ``\\"``, are handled.
 458 | 
 459 |     .. versionchanged:: 2.2
 460 |         Option names are always converted to lowercase.
 461 | 
 462 |     .. versionchanged:: 2.2
 463 |         The ``multiple`` parameter was removed.
 464 | 
 465 |     .. versionchanged:: 0.15
 466 |         :rfc:`2231` parameter continuations are handled.
 467 | 
 468 |     .. versionadded:: 0.5
 469 |     """
 470 |     if value is None:
 471 |         return "", {}
 472 | 
 473 |     value, _, rest = value.partition(";")
 474 |     value = value.strip()
 475 |     rest = rest.strip()
 476 | 
 477 |     if not value or not rest:
 478 |         # empty (invalid) value, or value without options
 479 |         return value, {}
 480 | 
 481 |     # Collect all valid key=value parts without processing the value.
 482 |     parts: list[tuple[str, str]] = []
 483 | 
 484 |     while True:
 485 |         if (m := _parameter_key_re.match(rest)) is not None:
 486 |             pk = m.group(1).lower()
 487 |             rest = rest[m.end() :]
 488 | 
 489 |             # Value may be a token.
 490 |             if (m := _parameter_token_value_re.match(rest)) is not None:
 491 |                 parts.append((pk, m.group()))
 492 | 
 493 |             # Value may be a quoted string, find the closing quote.
 494 |             elif rest[:1] == '"':
 495 |                 pos = 1
 496 |                 length = len(rest)
 497 | 
 498 |                 while pos < length:
 499 |                     if rest[pos : pos + 2] in {"\\\\", '\\"'}:
 500 |                         # Consume escaped slashes and quotes.
 501 |                         pos += 2
 502 |                     elif rest[pos] == '"':
 503 |                         # Stop at an unescaped quote.
 504 |                         parts.append((pk, rest[: pos + 1]))
 505 |                         rest = rest[pos + 1 :]
 506 |                         break
 507 |                     else:
 508 |                         # Consume any other character.
 509 |                         pos += 1
 510 | 
 511 |         # Find the next section delimited by `;`, if any.
 512 |         if (end := rest.find(";")) == -1:
 513 |             break
 514 | 
 515 |         rest = rest[end + 1 :].lstrip()
 516 | 
 517 |     options: dict[str, str] = {}
 518 |     encoding: str | None = None
 519 |     continued_encoding: str | None = None
 520 | 
 521 |     # For each collected part, process optional charset and continuation,
 522 |     # unquote quoted values.
 523 |     for pk, pv in parts:
 524 |         if pk[-1] == "*":
 525 |             # key*=charset''value becomes key=value, where value is percent encoded
 526 |             pk = pk[:-1]
 527 |             match = _charset_value_re.match(pv)
 528 | 
 529 |             if match:
 530 |                 # If there is a valid charset marker in the value, split it off.
 531 |                 encoding, pv = match.groups()
 532 |                 # This might be the empty string, handled next.
 533 |                 encoding = encoding.lower()
 534 | 
 535 |             # No charset marker, or marker with empty charset value.
 536 |             if not encoding:
 537 |                 encoding = continued_encoding
 538 | 
 539 |             # A safe list of encodings. Modern clients should only send ASCII or UTF-8.
 540 |             # This list will not be extended further. An invalid encoding will leave the
 541 |             # value quoted.
 542 |             if encoding in {"ascii", "us-ascii", "utf-8", "iso-8859-1"}:
 543 |                 # Continuation parts don't require their own charset marker. This is
 544 |                 # looser than the RFC, it will persist across different keys and allows
 545 |                 # changing the charset during a continuation. But this implementation is
 546 |                 # much simpler than tracking the full state.
 547 |                 continued_encoding = encoding
 548 |                 # invalid bytes are replaced during unquoting
 549 |                 pv = unquote(pv, encoding=encoding)
 550 | 
 551 |         # Remove quotes. At this point the value cannot be empty or a single quote.
 552 |         if pv[0] == pv[-1] == '"':
 553 |             # HTTP headers use slash, multipart form data uses percent
 554 |             pv = pv[1:-1].replace("\\\\", "\\").replace('\\"', '"').replace("%22", '"')
 555 | 
 556 |         match = _continuation_re.search(pk)
 557 | 
 558 |         if match:
 559 |             # key*0=a; key*1=b becomes key=ab
 560 |             pk = pk[: match.start()]
 561 |             options[pk] = options.get(pk, "") + pv
 562 |         else:
 563 |             options[pk] = pv
 564 | 
 565 |     return value, options
 566 | 
 567 | 
 568 | _q_value_re = re.compile(r"-?\d+(\.\d+)?", re.ASCII)
 569 | _TAnyAccept = t.TypeVar("_TAnyAccept", bound="ds.Accept")
 570 | 
 571 | 
 572 | @t.overload
 573 | def parse_accept_header(value: str | None) -> ds.Accept: ...
 574 | 
 575 | 
 576 | @t.overload
 577 | def parse_accept_header(value: str | None, cls: type[_TAnyAccept]) -> _TAnyAccept: ...
 578 | 
 579 | 
 580 | def parse_accept_header(
 581 |     value: str | None, cls: type[_TAnyAccept] | None = None
 582 | ) -> _TAnyAccept:
 583 |     """Parse an ``Accept`` header according to
 584 |     `RFC 9110 <https://httpwg.org/specs/rfc9110.html#field.accept>`__.
 585 | 
 586 |     Returns an :class:`.Accept` instance, which can sort and inspect items based on
 587 |     their quality parameter. When parsing ``Accept-Charset``, ``Accept-Encoding``, or
 588 |     ``Accept-Language``, pass the appropriate :class:`.Accept` subclass.
 589 | 
 590 |     :param value: The header value to parse.
 591 |     :param cls: The :class:`.Accept` class to wrap the result in.
 592 |     :return: An instance of ``cls``.
 593 | 
 594 |     .. versionchanged:: 2.3
 595 |         Parse according to RFC 9110. Items with invalid ``q`` values are skipped.
 596 |     """
 597 |     if cls is None:
 598 |         cls = t.cast(t.Type[_TAnyAccept], ds.Accept)
 599 | 
 600 |     if not value:
 601 |         return cls(None)
 602 | 
 603 |     result = []
 604 | 
 605 |     for item in parse_list_header(value):
 606 |         item, options = parse_options_header(item)
 607 | 
 608 |         if "q" in options:
 609 |             # pop q, remaining options are reconstructed
 610 |             q_str = options.pop("q").strip()
 611 | 
 612 |             if _q_value_re.fullmatch(q_str) is None:
 613 |                 # ignore an invalid q
 614 |                 continue
 615 | 
 616 |             q = float(q_str)
 617 | 
 618 |             if q < 0 or q > 1:
 619 |                 # ignore an invalid q
 620 |                 continue
 621 |         else:
 622 |             q = 1
 623 | 
 624 |         if options:
 625 |             # reconstruct the media type with any options
 626 |             item = dump_options_header(item, options)
 627 | 
 628 |         result.append((item, q))
 629 | 
 630 |     return cls(result)
 631 | 
 632 | 
 633 | _TAnyCC = t.TypeVar("_TAnyCC", bound="ds.cache_control._CacheControl")
 634 | 
 635 | 
 636 | @t.overload
 637 | def parse_cache_control_header(
 638 |     value: str | None,
 639 |     on_update: t.Callable[[ds.cache_control._CacheControl], None] | None = None,
 640 | ) -> ds.RequestCacheControl: ...
 641 | 
 642 | 
 643 | @t.overload
 644 | def parse_cache_control_header(
 645 |     value: str | None,
 646 |     on_update: t.Callable[[ds.cache_control._CacheControl], None] | None = None,
 647 |     cls: type[_TAnyCC] = ...,
 648 | ) -> _TAnyCC: ...
 649 | 
 650 | 
 651 | def parse_cache_control_header(
 652 |     value: str | None,
 653 |     on_update: t.Callable[[ds.cache_control._CacheControl], None] | None = None,
 654 |     cls: type[_TAnyCC] | None = None,
 655 | ) -> _TAnyCC:
 656 |     """Parse a cache control header.  The RFC differs between response and
 657 |     request cache control, this method does not.  It's your responsibility
 658 |     to not use the wrong control statements.
 659 | 
 660 |     .. versionadded:: 0.5
 661 |        The `cls` was added.  If not specified an immutable
 662 |        :class:`~werkzeug.datastructures.RequestCacheControl` is returned.
 663 | 
 664 |     :param value: a cache control header to be parsed.
 665 |     :param on_update: an optional callable that is called every time a value
 666 |                       on the :class:`~werkzeug.datastructures.CacheControl`
 667 |                       object is changed.
 668 |     :param cls: the class for the returned object.  By default
 669 |                 :class:`~werkzeug.datastructures.RequestCacheControl` is used.
 670 |     :return: a `cls` object.
 671 |     """
 672 |     if cls is None:
 673 |         cls = t.cast("type[_TAnyCC]", ds.RequestCacheControl)
 674 | 
 675 |     if not value:
 676 |         return cls((), on_update)
 677 | 
 678 |     return cls(parse_dict_header(value), on_update)
 679 | 
 680 | 
 681 | _TAnyCSP = t.TypeVar("_TAnyCSP", bound="ds.ContentSecurityPolicy")
 682 | 
 683 | 
 684 | @t.overload
 685 | def parse_csp_header(
 686 |     value: str | None,
 687 |     on_update: t.Callable[[ds.ContentSecurityPolicy], None] | None = None,
 688 | ) -> ds.ContentSecurityPolicy: ...
 689 | 
 690 | 
 691 | @t.overload
 692 | def parse_csp_header(
 693 |     value: str | None,
 694 |     on_update: t.Callable[[ds.ContentSecurityPolicy], None] | None = None,
 695 |     cls: type[_TAnyCSP] = ...,
 696 | ) -> _TAnyCSP: ...
 697 | 
 698 | 
 699 | def parse_csp_header(
 700 |     value: str | None,
 701 |     on_update: t.Callable[[ds.ContentSecurityPolicy], None] | None = None,
 702 |     cls: type[_TAnyCSP] | None = None,
 703 | ) -> _TAnyCSP:
 704 |     """Parse a Content Security Policy header.
 705 | 
 706 |     .. versionadded:: 1.0.0
 707 |        Support for Content Security Policy headers was added.
 708 | 
 709 |     :param value: a csp header to be parsed.
 710 |     :param on_update: an optional callable that is called every time a value
 711 |                       on the object is changed.
 712 |     :param cls: the class for the returned object.  By default
 713 |                 :class:`~werkzeug.datastructures.ContentSecurityPolicy` is used.
 714 |     :return: a `cls` object.
 715 |     """
 716 |     if cls is None:
 717 |         cls = t.cast("type[_TAnyCSP]", ds.ContentSecurityPolicy)
 718 | 
 719 |     if value is None:
 720 |         return cls((), on_update)
 721 | 
 722 |     items = []
 723 | 
 724 |     for policy in value.split(";"):
 725 |         policy = policy.strip()
 726 | 
 727 |         # Ignore badly formatted policies (no space)
 728 |         if " " in policy:
 729 |             directive, value = policy.strip().split(" ", 1)
 730 |             items.append((directive.strip(), value.strip()))
 731 | 
 732 |     return cls(items, on_update)
 733 | 
 734 | 
 735 | def parse_set_header(
 736 |     value: str | None,
 737 |     on_update: t.Callable[[ds.HeaderSet], None] | None = None,
 738 | ) -> ds.HeaderSet:
 739 |     """Parse a set-like header and return a
 740 |     :class:`~werkzeug.datastructures.HeaderSet` object:
 741 | 
 742 |     >>> hs = parse_set_header('token, "quoted value"')
 743 | 
 744 |     The return value is an object that treats the items case-insensitively
 745 |     and keeps the order of the items:
 746 | 
 747 |     >>> 'TOKEN' in hs
 748 |     True
 749 |     >>> hs.index('quoted value')
 750 |     1
 751 |     >>> hs
 752 |     HeaderSet(['token', 'quoted value'])
 753 | 
 754 |     To create a header from the :class:`HeaderSet` again, use the
 755 |     :func:`dump_header` function.
 756 | 
 757 |     :param value: a set header to be parsed.
 758 |     :param on_update: an optional callable that is called every time a
 759 |                       value on the :class:`~werkzeug.datastructures.HeaderSet`
 760 |                       object is changed.
 761 |     :return: a :class:`~werkzeug.datastructures.HeaderSet`
 762 |     """
 763 |     if not value:
 764 |         return ds.HeaderSet(None, on_update)
 765 |     return ds.HeaderSet(parse_list_header(value), on_update)
 766 | 
 767 | 
 768 | def parse_if_range_header(value: str | None) -> ds.IfRange:
 769 |     """Parses an if-range header which can be an etag or a date.  Returns
 770 |     a :class:`~werkzeug.datastructures.IfRange` object.
 771 | 
 772 |     .. versionchanged:: 2.0
 773 |         If the value represents a datetime, it is timezone-aware.
 774 | 
 775 |     .. versionadded:: 0.7
 776 |     """
 777 |     if not value:
 778 |         return ds.IfRange()
 779 |     date = parse_date(value)
 780 |     if date is not None:
 781 |         return ds.IfRange(date=date)
 782 |     # drop weakness information
 783 |     return ds.IfRange(unquote_etag(value)[0])
 784 | 
 785 | 
 786 | def parse_range_header(
 787 |     value: str | None, make_inclusive: bool = True
 788 | ) -> ds.Range | None:
 789 |     """Parses a range header into a :class:`~werkzeug.datastructures.Range`
 790 |     object.  If the header is missing or malformed `None` is returned.
 791 |     `ranges` is a list of ``(start, stop)`` tuples where the ranges are
 792 |     non-inclusive.
 793 | 
 794 |     .. versionadded:: 0.7
 795 |     """
 796 |     if not value or "=" not in value:
 797 |         return None
 798 | 
 799 |     ranges = []
 800 |     last_end = 0
 801 |     units, rng = value.split("=", 1)
 802 |     units = units.strip().lower()
 803 | 
 804 |     for item in rng.split(","):
 805 |         item = item.strip()
 806 |         if "-" not in item:
 807 |             return None
 808 |         if item.startswith("-"):
 809 |             if last_end < 0:
 810 |                 return None
 811 |             try:
 812 |                 begin = _plain_int(item)
 813 |             except ValueError:
 814 |                 return None
 815 |             end = None
 816 |             last_end = -1
 817 |         elif "-" in item:
 818 |             begin_str, end_str = item.split("-", 1)
 819 |             begin_str = begin_str.strip()
 820 |             end_str = end_str.strip()
 821 | 
 822 |             try:
 823 |                 begin = _plain_int(begin_str)
 824 |             except ValueError:
 825 |                 return None
 826 | 
 827 |             if begin < last_end or last_end < 0:
 828 |                 return None
 829 |             if end_str:
 830 |                 try:
 831 |                     end = _plain_int(end_str) + 1
 832 |                 except ValueError:
 833 |                     return None
 834 | 
 835 |                 if begin >= end:
 836 |                     return None
 837 |             else:
 838 |                 end = None
 839 |             last_end = end if end is not None else -1
 840 |         ranges.append((begin, end))
 841 | 
 842 |     return ds.Range(units, ranges)
 843 | 
 844 | 
 845 | def parse_content_range_header(
 846 |     value: str | None,
 847 |     on_update: t.Callable[[ds.ContentRange], None] | None = None,
 848 | ) -> ds.ContentRange | None:
 849 |     """Parses a range header into a
 850 |     :class:`~werkzeug.datastructures.ContentRange` object or `None` if
 851 |     parsing is not possible.
 852 | 
 853 |     .. versionadded:: 0.7
 854 | 
 855 |     :param value: a content range header to be parsed.
 856 |     :param on_update: an optional callable that is called every time a value
 857 |                       on the :class:`~werkzeug.datastructures.ContentRange`
 858 |                       object is changed.
 859 |     """
 860 |     if value is None:
 861 |         return None
 862 |     try:
 863 |         units, rangedef = (value or "").strip().split(None, 1)
 864 |     except ValueError:
 865 |         return None
 866 | 
 867 |     if "/" not in rangedef:
 868 |         return None
 869 |     rng, length_str = rangedef.split("/", 1)
 870 |     if length_str == "*":
 871 |         length = None
 872 |     else:
 873 |         try:
 874 |             length = _plain_int(length_str)
 875 |         except ValueError:
 876 |             return None
 877 | 
 878 |     if rng == "*":
 879 |         if not is_byte_range_valid(None, None, length):
 880 |             return None
 881 | 
 882 |         return ds.ContentRange(units, None, None, length, on_update=on_update)
 883 |     elif "-" not in rng:
 884 |         return None
 885 | 
 886 |     start_str, stop_str = rng.split("-", 1)
 887 |     try:
 888 |         start = _plain_int(start_str)
 889 |         stop = _plain_int(stop_str) + 1
 890 |     except ValueError:
 891 |         return None
 892 | 
 893 |     if is_byte_range_valid(start, stop, length):
 894 |         return ds.ContentRange(units, start, stop, length, on_update=on_update)
 895 | 
 896 |     return None
 897 | 
 898 | 
 899 | def quote_etag(etag: str, weak: bool = False) -> str:
 900 |     """Quote an etag.
 901 | 
 902 |     :param etag: the etag to quote.
 903 |     :param weak: set to `True` to tag it "weak".
 904 |     """
 905 |     if '"' in etag:
 906 |         raise ValueError("invalid etag")
 907 |     etag = f'"{etag}"'
 908 |     if weak:
 909 |         etag = f"W/{etag}"
 910 |     return etag
 911 | 
 912 | 
 913 | def unquote_etag(
 914 |     etag: str | None,
 915 | ) -> tuple[str, bool] | tuple[None, None]:
 916 |     """Unquote a single etag:
 917 | 
 918 |     >>> unquote_etag('W/"bar"')
 919 |     ('bar', True)
 920 |     >>> unquote_etag('"bar"')
 921 |     ('bar', False)
 922 | 
 923 |     :param etag: the etag identifier to unquote.
 924 |     :return: a ``(etag, weak)`` tuple.
 925 |     """
 926 |     if not etag:
 927 |         return None, None
 928 |     etag = etag.strip()
 929 |     weak = False
 930 |     if etag.startswith(("W/", "w/")):
 931 |         weak = True
 932 |         etag = etag[2:]
 933 |     if etag[:1] == etag[-1:] == '"':
 934 |         etag = etag[1:-1]
 935 |     return etag, weak
 936 | 
 937 | 
 938 | def parse_etags(value: str | None) -> ds.ETags:
 939 |     """Parse an etag header.
 940 | 
 941 |     :param value: the tag header to parse
 942 |     :return: an :class:`~werkzeug.datastructures.ETags` object.
 943 |     """
 944 |     if not value:
 945 |         return ds.ETags()
 946 |     strong = []
 947 |     weak = []
 948 |     end = len(value)
 949 |     pos = 0
 950 |     while pos < end:
 951 |         match = _etag_re.match(value, pos)
 952 |         if match is None:
 953 |             break
 954 |         is_weak, quoted, raw = match.groups()
 955 |         if raw == "*":
 956 |             return ds.ETags(star_tag=True)
 957 |         elif quoted:
 958 |             raw = quoted
 959 |         if is_weak:
 960 |             weak.append(raw)
 961 |         else:
 962 |             strong.append(raw)
 963 |         pos = match.end()
 964 |     return ds.ETags(strong, weak)
 965 | 
 966 | 
 967 | def generate_etag(data: bytes) -> str:
 968 |     """Generate an etag for some data.
 969 | 
 970 |     .. versionchanged:: 2.0
 971 |         Use SHA-1. MD5 may not be available in some environments.
 972 |     """
 973 |     return sha1(data).hexdigest()
 974 | 
 975 | 
 976 | def parse_date(value: str | None) -> datetime | None:
 977 |     """Parse an :rfc:`2822` date into a timezone-aware
 978 |     :class:`datetime.datetime` object, or ``None`` if parsing fails.
 979 | 
 980 |     This is a wrapper for :func:`email.utils.parsedate_to_datetime`. It
 981 |     returns ``None`` if parsing fails instead of raising an exception,
 982 |     and always returns a timezone-aware datetime object. If the string
 983 |     doesn't have timezone information, it is assumed to be UTC.
 984 | 
 985 |     :param value: A string with a supported date format.
 986 | 
 987 |     .. versionchanged:: 2.0
 988 |         Return a timezone-aware datetime object. Use
 989 |         ``email.utils.parsedate_to_datetime``.
 990 |     """
 991 |     if value is None:
 992 |         return None
 993 | 
 994 |     try:
 995 |         dt = email.utils.parsedate_to_datetime(value)
 996 |     except (TypeError, ValueError):
 997 |         return None
 998 | 
 999 |     if dt.tzinfo is None:
1000 |         return dt.replace(tzinfo=timezone.utc)
1001 | 
1002 |     return dt
1003 | 
1004 | 
1005 | def http_date(
1006 |     timestamp: datetime | date | int | float | struct_time | None = None,
1007 | ) -> str:
1008 |     """Format a datetime object or timestamp into an :rfc:`2822` date
1009 |     string.
1010 | 
1011 |     This is a wrapper for :func:`email.utils.format_datetime`. It
1012 |     assumes naive datetime objects are in UTC instead of raising an
1013 |     exception.
1014 | 
1015 |     :param timestamp: The datetime or timestamp to format. Defaults to
1016 |         the current time.
1017 | 
1018 |     .. versionchanged:: 2.0
1019 |         Use ``email.utils.format_datetime``. Accept ``date`` objects.
1020 |     """
1021 |     if isinstance(timestamp, date):
1022 |         if not isinstance(timestamp, datetime):
1023 |             # Assume plain date is midnight UTC.
1024 |             timestamp = datetime.combine(timestamp, time(), tzinfo=timezone.utc)
1025 |         else:
1026 |             # Ensure datetime is timezone-aware.
1027 |             timestamp = _dt_as_utc(timestamp)
1028 | 
1029 |         return email.utils.format_datetime(timestamp, usegmt=True)
1030 | 
1031 |     if isinstance(timestamp, struct_time):
1032 |         timestamp = mktime(timestamp)
1033 | 
1034 |     return email.utils.formatdate(timestamp, usegmt=True)
1035 | 
1036 | 
1037 | def parse_age(value: str | None = None) -> timedelta | None:
1038 |     """Parses a base-10 integer count of seconds into a timedelta.
1039 | 
1040 |     If parsing fails, the return value is `None`.
1041 | 
1042 |     :param value: a string consisting of an integer represented in base-10
1043 |     :return: a :class:`datetime.timedelta` object or `None`.
1044 |     """
1045 |     if not value:
1046 |         return None
1047 |     try:
1048 |         seconds = int(value)
1049 |     except ValueError:
1050 |         return None
1051 |     if seconds < 0:
1052 |         return None
1053 |     try:
1054 |         return timedelta(seconds=seconds)
1055 |     except OverflowError:
1056 |         return None
1057 | 
1058 | 
1059 | def dump_age(age: timedelta | int | None = None) -> str | None:
1060 |     """Formats the duration as a base-10 integer.
1061 | 
1062 |     :param age: should be an integer number of seconds,
1063 |                 a :class:`datetime.timedelta` object, or,
1064 |                 if the age is unknown, `None` (default).
1065 |     """
1066 |     if age is None:
1067 |         return None
1068 |     if isinstance(age, timedelta):
1069 |         age = int(age.total_seconds())
1070 |     else:
1071 |         age = int(age)
1072 | 
1073 |     if age < 0:
1074 |         raise ValueError("age cannot be negative")
1075 | 
1076 |     return str(age)
1077 | 
1078 | 
1079 | def is_resource_modified(
1080 |     environ: WSGIEnvironment,
1081 |     etag: str | None = None,
1082 |     data: bytes | None = None,
1083 |     last_modified: datetime | str | None = None,
1084 |     ignore_if_range: bool = True,
1085 | ) -> bool:
1086 |     """Convenience method for conditional requests.
1087 | 
1088 |     :param environ: the WSGI environment of the request to be checked.
1089 |     :param etag: the etag for the response for comparison.
1090 |     :param data: or alternatively the data of the response to automatically
1091 |                  generate an etag using :func:`generate_etag`.
1092 |     :param last_modified: an optional date of the last modification.
1093 |     :param ignore_if_range: If `False`, `If-Range` header will be taken into
1094 |                             account.
1095 |     :return: `True` if the resource was modified, otherwise `False`.
1096 | 
1097 |     .. versionchanged:: 2.0
1098 |         SHA-1 is used to generate an etag value for the data. MD5 may
1099 |         not be available in some environments.
1100 | 
1101 |     .. versionchanged:: 1.0.0
1102 |         The check is run for methods other than ``GET`` and ``HEAD``.
1103 |     """
1104 |     return _sansio_http.is_resource_modified(
1105 |         http_range=environ.get("HTTP_RANGE"),
1106 |         http_if_range=environ.get("HTTP_IF_RANGE"),
1107 |         http_if_modified_since=environ.get("HTTP_IF_MODIFIED_SINCE"),
1108 |         http_if_none_match=environ.get("HTTP_IF_NONE_MATCH"),
1109 |         http_if_match=environ.get("HTTP_IF_MATCH"),
1110 |         etag=etag,
1111 |         data=data,
1112 |         last_modified=last_modified,
1113 |         ignore_if_range=ignore_if_range,
1114 |     )
1115 | 
1116 | 
1117 | def remove_entity_headers(
1118 |     headers: ds.Headers | list[tuple[str, str]],
1119 |     allowed: t.Iterable[str] = ("expires", "content-location"),
1120 | ) -> None:
1121 |     """Remove all entity headers from a list or :class:`Headers` object.  This
1122 |     operation works in-place.  `Expires` and `Content-Location` headers are
1123 |     by default not removed.  The reason for this is :rfc:`2616` section
1124 |     10.3.5 which specifies some entity headers that should be sent.
1125 | 
1126 |     .. versionchanged:: 0.5
1127 |        added `allowed` parameter.
1128 | 
1129 |     :param headers: a list or :class:`Headers` object.
1130 |     :param allowed: a list of headers that should still be allowed even though
1131 |                     they are entity headers.
1132 |     """
1133 |     allowed = {x.lower() for x in allowed}
1134 |     headers[:] = [
1135 |         (key, value)
1136 |         for key, value in headers
1137 |         if not is_entity_header(key) or key.lower() in allowed
1138 |     ]
1139 | 
1140 | 
1141 | def remove_hop_by_hop_headers(headers: ds.Headers | list[tuple[str, str]]) -> None:
1142 |     """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or
1143 |     :class:`Headers` object.  This operation works in-place.
1144 | 
1145 |     .. versionadded:: 0.5
1146 | 
1147 |     :param headers: a list or :class:`Headers` object.
1148 |     """
1149 |     headers[:] = [
1150 |         (key, value) for key, value in headers if not is_hop_by_hop_header(key)
1151 |     ]
1152 | 
1153 | 
1154 | def is_entity_header(header: str) -> bool:
1155 |     """Check if a header is an entity header.
1156 | 
1157 |     .. versionadded:: 0.5
1158 | 
1159 |     :param header: the header to test.
1160 |     :return: `True` if it's an entity header, `False` otherwise.
1161 |     """
1162 |     return header.lower() in _entity_headers
1163 | 
1164 | 
1165 | def is_hop_by_hop_header(header: str) -> bool:
1166 |     """Check if a header is an HTTP/1.1 "Hop-by-Hop" header.
1167 | 
1168 |     .. versionadded:: 0.5
1169 | 
1170 |     :param header: the header to test.
1171 |     :return: `True` if it's an HTTP/1.1 "Hop-by-Hop" header, `False` otherwise.
1172 |     """
1173 |     return header.lower() in _hop_by_hop_headers
1174 | 
1175 | 
1176 | def parse_cookie(
1177 |     header: WSGIEnvironment | str | None,
1178 |     cls: type[ds.MultiDict[str, str]] | None = None,
1179 | ) -> ds.MultiDict[str, str]:
1180 |     """Parse a cookie from a string or WSGI environ.
1181 | 
1182 |     The same key can be provided multiple times, the values are stored
1183 |     in-order. The default :class:`MultiDict` will have the first value
1184 |     first, and all values can be retrieved with
1185 |     :meth:`MultiDict.getlist`.
1186 | 
1187 |     :param header: The cookie header as a string, or a WSGI environ dict
1188 |         with a ``HTTP_COOKIE`` key.
1189 |     :param cls: A dict-like class to store the parsed cookies in.
1190 |         Defaults to :class:`MultiDict`.
1191 | 
1192 |     .. versionchanged:: 3.0
1193 |         Passing bytes, and the ``charset`` and ``errors`` parameters, were removed.
1194 | 
1195 |     .. versionchanged:: 1.0
1196 |         Returns a :class:`MultiDict` instead of a ``TypeConversionDict``.
1197 | 
1198 |     .. versionchanged:: 0.5
1199 |         Returns a :class:`TypeConversionDict` instead of a regular dict. The ``cls``
1200 |         parameter was added.
1201 |     """
1202 |     if isinstance(header, dict):
1203 |         cookie = header.get("HTTP_COOKIE")
1204 |     else:
1205 |         cookie = header
1206 | 
1207 |     if cookie:
1208 |         cookie = cookie.encode("latin1").decode()
1209 | 
1210 |     return _sansio_http.parse_cookie(cookie=cookie, cls=cls)
1211 | 
1212 | 
1213 | _cookie_no_quote_re = re.compile(r"[\w!#$%&'()*+\-./:<=>?@\[\]^`{|}~]*", re.A)
1214 | _cookie_slash_re = re.compile(rb"[\x00-\x19\",;\\\x7f-\xff]", re.A)
1215 | _cookie_slash_map = {b'"': b'\\"', b"\\": b"\\\\"}
1216 | _cookie_slash_map.update(
1217 |     (v.to_bytes(1, "big"), b"\\%03o" % v)
1218 |     for v in [*range(0x20), *b",;", *range(0x7F, 256)]
1219 | )
1220 | 
1221 | 
1222 | def dump_cookie(
1223 |     key: str,
1224 |     value: str = "",
1225 |     max_age: timedelta | int | None = None,
1226 |     expires: str | datetime | int | float | None = None,
1227 |     path: str | None = "/",
1228 |     domain: str | None = None,
1229 |     secure: bool = False,
1230 |     httponly: bool = False,
1231 |     sync_expires: bool = True,
1232 |     max_size: int = 4093,
1233 |     samesite: str | None = None,
1234 | ) -> str:
1235 |     """Create a Set-Cookie header without the ``Set-Cookie`` prefix.
1236 | 
1237 |     The return value is usually restricted to ascii as the vast majority
1238 |     of values are properly escaped, but that is no guarantee. It's
1239 |     tunneled through latin1 as required by :pep:`3333`.
1240 | 
1241 |     The return value is not ASCII safe if the key contains unicode
1242 |     characters.  This is technically against the specification but
1243 |     happens in the wild.  It's strongly recommended to not use
1244 |     non-ASCII values for the keys.
1245 | 
1246 |     :param max_age: should be a number of seconds, or `None` (default) if
1247 |                     the cookie should last only as long as the client's
1248 |                     browser session.  Additionally `timedelta` objects
1249 |                     are accepted, too.
1250 |     :param expires: should be a `datetime` object or unix timestamp.
1251 |     :param path: limits the cookie to a given path, per default it will
1252 |                  span the whole domain.
1253 |     :param domain: Use this if you want to set a cross-domain cookie. For
1254 |                    example, ``domain="example.com"`` will set a cookie
1255 |                    that is readable by the domain ``www.example.com``,
1256 |                    ``foo.example.com`` etc. Otherwise, a cookie will only
1257 |                    be readable by the domain that set it.
1258 |     :param secure: The cookie will only be available via HTTPS
1259 |     :param httponly: disallow JavaScript to access the cookie.  This is an
1260 |                      extension to the cookie standard and probably not
1261 |                      supported by all browsers.
1262 |     :param charset: the encoding for string values.
1263 |     :param sync_expires: automatically set expires if max_age is defined
1264 |                          but expires not.
1265 |     :param max_size: Warn if the final header value exceeds this size. The
1266 |         default, 4093, should be safely `supported by most browsers
1267 |         <cookie_>`_. Set to 0 to disable this check.
1268 |     :param samesite: Limits the scope of the cookie such that it will
1269 |         only be attached to requests if those requests are same-site.
1270 | 
1271 |     .. _`cookie`: http://browsercookielimits.squawky.net/
1272 | 
1273 |     .. versionchanged:: 3.0
1274 |         Passing bytes, and the ``charset`` parameter, were removed.
1275 | 
1276 |     .. versionchanged:: 2.3.3
1277 |         The ``path`` parameter is ``/`` by default.
1278 | 
1279 |     .. versionchanged:: 2.3.1
1280 |         The value allows more characters without quoting.
1281 | 
1282 |     .. versionchanged:: 2.3
1283 |         ``localhost`` and other names without a dot are allowed for the domain. A
1284 |         leading dot is ignored.
1285 | 
1286 |     .. versionchanged:: 2.3
1287 |         The ``path`` parameter is ``None`` by default.
1288 | 
1289 |     .. versionchanged:: 1.0.0
1290 |         The string ``'None'`` is accepted for ``samesite``.
1291 |     """
1292 |     if path is not None:
1293 |         # safe = https://url.spec.whatwg.org/#url-path-segment-string
1294 |         # as well as percent for things that are already quoted
1295 |         # excluding semicolon since it's part of the header syntax
1296 |         path = quote(path, safe="%!$&'()*+,/:=@")
1297 | 
1298 |     if domain:
1299 |         domain = domain.partition(":")[0].lstrip(".").encode("idna").decode("ascii")
1300 | 
1301 |     if isinstance(max_age, timedelta):
1302 |         max_age = int(max_age.total_seconds())
1303 | 
1304 |     if expires is not None:
1305 |         if not isinstance(expires, str):
1306 |             expires = http_date(expires)
1307 |     elif max_age is not None and sync_expires:
1308 |         expires = http_date(datetime.now(tz=timezone.utc).timestamp() + max_age)
1309 | 
1310 |     if samesite is not None:
1311 |         samesite = samesite.title()
1312 | 
1313 |         if samesite not in {"Strict", "Lax", "None"}:
1314 |             raise ValueError("SameSite must be 'Strict', 'Lax', or 'None'.")
1315 | 
1316 |     # Quote value if it contains characters not allowed by RFC 6265. Slash-escape with
1317 |     # three octal digits, which matches http.cookies, although the RFC suggests base64.
1318 |     if not _cookie_no_quote_re.fullmatch(value):
1319 |         # Work with bytes here, since a UTF-8 character could be multiple bytes.
1320 |         value = _cookie_slash_re.sub(
1321 |             lambda m: _cookie_slash_map[m.group()], value.encode()
1322 |         ).decode("ascii")
1323 |         value = f'"{value}"'
1324 | 
1325 |     # Send a non-ASCII key as mojibake. Everything else should already be ASCII.
1326 |     # TODO Remove encoding dance, it seems like clients accept UTF-8 keys
1327 |     buf = [f"{key.encode().decode('latin1')}={value}"]
1328 | 
1329 |     for k, v in (
1330 |         ("Domain", domain),
1331 |         ("Expires", expires),
1332 |         ("Max-Age", max_age),
1333 |         ("Secure", secure),
1334 |         ("HttpOnly", httponly),
1335 |         ("Path", path),
1336 |         ("SameSite", samesite),
1337 |     ):
1338 |         if v is None or v is False:
1339 |             continue
1340 | 
1341 |         if v is True:
1342 |             buf.append(k)
1343 |             continue
1344 | 
1345 |         buf.append(f"{k}={v}")
1346 | 
1347 |     rv = "; ".join(buf)
1348 | 
1349 |     # Warn if the final value of the cookie is larger than the limit. If the cookie is
1350 |     # too large, then it may be silently ignored by the browser, which can be quite hard
1351 |     # to debug.
1352 |     cookie_size = len(rv)
1353 | 
1354 |     if max_size and cookie_size > max_size:
1355 |         value_size = len(value)
1356 |         warnings.warn(
1357 |             f"The '{key}' cookie is too large: the value was {value_size} bytes but the"
1358 |             f" header required {cookie_size - value_size} extra bytes. The final size"
1359 |             f" was {cookie_size} bytes but the limit is {max_size} bytes. Browsers may"
1360 |             " silently ignore cookies larger than this.",
1361 |             stacklevel=2,
1362 |         )
1363 | 
1364 |     return rv
1365 | 
1366 | 
1367 | def is_byte_range_valid(
1368 |     start: int | None, stop: int | None, length: int | None
1369 | ) -> bool:
1370 |     """Checks if a given byte content range is valid for the given length.
1371 | 
1372 |     .. versionadded:: 0.7
1373 |     """
1374 |     if (start is None) != (stop is None):
1375 |         return False
1376 |     elif start is None:
1377 |         return length is None or length >= 0
1378 |     elif length is None:
1379 |         return 0 <= start < stop  # type: ignore
1380 |     elif start >= stop:  # type: ignore
1381 |         return False
1382 |     return 0 <= start < length
1383 | 
1384 | 
1385 | # circular dependencies
1386 | from . import datastructures as ds
1387 | from .sansio import http as _sansio_http
1388 | 
```
Page 135/168FirstPrevNextLast