#
tokens: 60418/50000 1/808 files (page 163/168)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 163 of 168. Use http://codebase.md/romanshablio/mcp_server?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .DS_Store
├── .venv
│   ├── __pycache__
│   │   └── hello.cpython-312.pyc
│   ├── bin
│   │   ├── activate
│   │   ├── activate.csh
│   │   ├── activate.fish
│   │   ├── Activate.ps1
│   │   ├── flask
│   │   ├── normalizer
│   │   ├── pip
│   │   ├── pip3
│   │   ├── pip3.12
│   │   ├── python
│   │   ├── python3
│   │   └── python3.12
│   ├── hello.py
│   ├── lib
│   │   └── python3.12
│   │       └── site-packages
│   │           ├── beautifulsoup4-4.12.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   ├── AUTHORS
│   │           │   │   └── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   └── WHEEL
│   │           ├── blinker
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _utilities.cpython-312.pyc
│   │           │   │   └── base.cpython-312.pyc
│   │           │   ├── _utilities.py
│   │           │   ├── base.py
│   │           │   └── py.typed
│   │           ├── blinker-1.8.2.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── bs4
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── css.cpython-312.pyc
│   │           │   │   ├── dammit.cpython-312.pyc
│   │           │   │   ├── diagnose.cpython-312.pyc
│   │           │   │   ├── element.cpython-312.pyc
│   │           │   │   └── formatter.cpython-312.pyc
│   │           │   ├── builder
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── _html5lib.cpython-312.pyc
│   │           │   │   │   ├── _htmlparser.cpython-312.pyc
│   │           │   │   │   └── _lxml.cpython-312.pyc
│   │           │   │   ├── _html5lib.py
│   │           │   │   ├── _htmlparser.py
│   │           │   │   └── _lxml.py
│   │           │   ├── css.py
│   │           │   ├── dammit.py
│   │           │   ├── diagnose.py
│   │           │   ├── element.py
│   │           │   ├── formatter.py
│   │           │   └── tests
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   ├── __init__.cpython-312.pyc
│   │           │       │   ├── test_builder_registry.cpython-312.pyc
│   │           │       │   ├── test_builder.cpython-312.pyc
│   │           │       │   ├── test_css.cpython-312.pyc
│   │           │       │   ├── test_dammit.cpython-312.pyc
│   │           │       │   ├── test_docs.cpython-312.pyc
│   │           │       │   ├── test_element.cpython-312.pyc
│   │           │       │   ├── test_formatter.cpython-312.pyc
│   │           │       │   ├── test_fuzz.cpython-312.pyc
│   │           │       │   ├── test_html5lib.cpython-312.pyc
│   │           │       │   ├── test_htmlparser.cpython-312.pyc
│   │           │       │   ├── test_lxml.cpython-312.pyc
│   │           │       │   ├── test_navigablestring.cpython-312.pyc
│   │           │       │   ├── test_pageelement.cpython-312.pyc
│   │           │       │   ├── test_soup.cpython-312.pyc
│   │           │       │   ├── test_tag.cpython-312.pyc
│   │           │       │   └── test_tree.cpython-312.pyc
│   │           │       ├── fuzz
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4670634698080256.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4818336571064320.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-4999465949331456.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5000587759190016.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5167584867909632.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5270998950477824.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5375146639360000.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5492400320282624.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5703933063462912.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5843991618256896.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-5984173902397440.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6124268085182464.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6241471367348224.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6306874195312640.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6450958476902400.testcase
│   │           │       │   ├── clusterfuzz-testcase-minimized-bs4_fuzzer-6600557255327744.testcase
│   │           │       │   ├── crash-0d306a50c8ed8bcd0785b67000fcd5dea1d33f08.testcase
│   │           │       │   └── crash-ffbdfa8a2b26f13537b68d3794b0478a4090ee4a.testcase
│   │           │       ├── test_builder_registry.py
│   │           │       ├── test_builder.py
│   │           │       ├── test_css.py
│   │           │       ├── test_dammit.py
│   │           │       ├── test_docs.py
│   │           │       ├── test_element.py
│   │           │       ├── test_formatter.py
│   │           │       ├── test_fuzz.py
│   │           │       ├── test_html5lib.py
│   │           │       ├── test_htmlparser.py
│   │           │       ├── test_lxml.py
│   │           │       ├── test_navigablestring.py
│   │           │       ├── test_pageelement.py
│   │           │       ├── test_soup.py
│   │           │       ├── test_tag.py
│   │           │       └── test_tree.py
│   │           ├── certifi
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   └── core.cpython-312.pyc
│   │           │   ├── cacert.pem
│   │           │   ├── core.py
│   │           │   └── py.typed
│   │           ├── certifi-2024.8.30.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── charset_normalizer
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   ├── api.cpython-312.pyc
│   │           │   │   ├── cd.cpython-312.pyc
│   │           │   │   ├── constant.cpython-312.pyc
│   │           │   │   ├── legacy.cpython-312.pyc
│   │           │   │   ├── md.cpython-312.pyc
│   │           │   │   ├── models.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── version.cpython-312.pyc
│   │           │   ├── api.py
│   │           │   ├── cd.py
│   │           │   ├── cli
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __main__.py
│   │           │   │   └── __pycache__
│   │           │   │       ├── __init__.cpython-312.pyc
│   │           │   │       └── __main__.cpython-312.pyc
│   │           │   ├── constant.py
│   │           │   ├── legacy.py
│   │           │   ├── md__mypyc.cpython-312-darwin.so
│   │           │   ├── md.cpython-312-darwin.so
│   │           │   ├── md.py
│   │           │   ├── models.py
│   │           │   ├── py.typed
│   │           │   ├── utils.py
│   │           │   └── version.py
│   │           ├── charset_normalizer-3.4.0.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── click
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _compat.cpython-312.pyc
│   │           │   │   ├── _termui_impl.cpython-312.pyc
│   │           │   │   ├── _textwrap.cpython-312.pyc
│   │           │   │   ├── _winconsole.cpython-312.pyc
│   │           │   │   ├── core.cpython-312.pyc
│   │           │   │   ├── decorators.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── formatting.cpython-312.pyc
│   │           │   │   ├── globals.cpython-312.pyc
│   │           │   │   ├── parser.cpython-312.pyc
│   │           │   │   ├── shell_completion.cpython-312.pyc
│   │           │   │   ├── termui.cpython-312.pyc
│   │           │   │   ├── testing.cpython-312.pyc
│   │           │   │   ├── types.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── _compat.py
│   │           │   ├── _termui_impl.py
│   │           │   ├── _textwrap.py
│   │           │   ├── _winconsole.py
│   │           │   ├── core.py
│   │           │   ├── decorators.py
│   │           │   ├── exceptions.py
│   │           │   ├── formatting.py
│   │           │   ├── globals.py
│   │           │   ├── parser.py
│   │           │   ├── py.typed
│   │           │   ├── shell_completion.py
│   │           │   ├── termui.py
│   │           │   ├── testing.py
│   │           │   ├── types.py
│   │           │   └── utils.py
│   │           ├── click-8.1.7.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.rst
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── fake_useragent
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── errors.cpython-312.pyc
│   │           │   │   ├── fake.cpython-312.pyc
│   │           │   │   ├── log.cpython-312.pyc
│   │           │   │   ├── settings.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── data
│   │           │   │   └── browsers.json
│   │           │   ├── errors.py
│   │           │   ├── fake.py
│   │           │   ├── log.py
│   │           │   ├── settings.py
│   │           │   └── utils.py
│   │           ├── fake_useragent-1.5.1.dist-info
│   │           │   ├── AUTHORS
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── flask
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   ├── app.cpython-312.pyc
│   │           │   │   ├── blueprints.cpython-312.pyc
│   │           │   │   ├── cli.cpython-312.pyc
│   │           │   │   ├── config.cpython-312.pyc
│   │           │   │   ├── ctx.cpython-312.pyc
│   │           │   │   ├── debughelpers.cpython-312.pyc
│   │           │   │   ├── globals.cpython-312.pyc
│   │           │   │   ├── helpers.cpython-312.pyc
│   │           │   │   ├── logging.cpython-312.pyc
│   │           │   │   ├── sessions.cpython-312.pyc
│   │           │   │   ├── signals.cpython-312.pyc
│   │           │   │   ├── templating.cpython-312.pyc
│   │           │   │   ├── testing.cpython-312.pyc
│   │           │   │   ├── typing.cpython-312.pyc
│   │           │   │   ├── views.cpython-312.pyc
│   │           │   │   └── wrappers.cpython-312.pyc
│   │           │   ├── app.py
│   │           │   ├── blueprints.py
│   │           │   ├── cli.py
│   │           │   ├── config.py
│   │           │   ├── ctx.py
│   │           │   ├── debughelpers.py
│   │           │   ├── globals.py
│   │           │   ├── helpers.py
│   │           │   ├── json
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── provider.cpython-312.pyc
│   │           │   │   │   └── tag.cpython-312.pyc
│   │           │   │   ├── provider.py
│   │           │   │   └── tag.py
│   │           │   ├── logging.py
│   │           │   ├── py.typed
│   │           │   ├── sansio
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── app.cpython-312.pyc
│   │           │   │   │   ├── blueprints.cpython-312.pyc
│   │           │   │   │   └── scaffold.cpython-312.pyc
│   │           │   │   ├── app.py
│   │           │   │   ├── blueprints.py
│   │           │   │   ├── README.md
│   │           │   │   └── scaffold.py
│   │           │   ├── sessions.py
│   │           │   ├── signals.py
│   │           │   ├── templating.py
│   │           │   ├── testing.py
│   │           │   ├── typing.py
│   │           │   ├── views.py
│   │           │   └── wrappers.py
│   │           ├── flask-3.0.3.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   └── WHEEL
│   │           ├── idna
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── codec.cpython-312.pyc
│   │           │   │   ├── compat.cpython-312.pyc
│   │           │   │   ├── core.cpython-312.pyc
│   │           │   │   ├── idnadata.cpython-312.pyc
│   │           │   │   ├── intranges.cpython-312.pyc
│   │           │   │   ├── package_data.cpython-312.pyc
│   │           │   │   └── uts46data.cpython-312.pyc
│   │           │   ├── codec.py
│   │           │   ├── compat.py
│   │           │   ├── core.py
│   │           │   ├── idnadata.py
│   │           │   ├── intranges.py
│   │           │   ├── package_data.py
│   │           │   ├── py.typed
│   │           │   └── uts46data.py
│   │           ├── idna-3.10.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.md
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── itsdangerous
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _json.cpython-312.pyc
│   │           │   │   ├── encoding.cpython-312.pyc
│   │           │   │   ├── exc.cpython-312.pyc
│   │           │   │   ├── serializer.cpython-312.pyc
│   │           │   │   ├── signer.cpython-312.pyc
│   │           │   │   ├── timed.cpython-312.pyc
│   │           │   │   └── url_safe.cpython-312.pyc
│   │           │   ├── _json.py
│   │           │   ├── encoding.py
│   │           │   ├── exc.py
│   │           │   ├── py.typed
│   │           │   ├── serializer.py
│   │           │   ├── signer.py
│   │           │   ├── timed.py
│   │           │   └── url_safe.py
│   │           ├── itsdangerous-2.2.0.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── jinja2
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _identifier.cpython-312.pyc
│   │           │   │   ├── async_utils.cpython-312.pyc
│   │           │   │   ├── bccache.cpython-312.pyc
│   │           │   │   ├── compiler.cpython-312.pyc
│   │           │   │   ├── constants.cpython-312.pyc
│   │           │   │   ├── debug.cpython-312.pyc
│   │           │   │   ├── defaults.cpython-312.pyc
│   │           │   │   ├── environment.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── ext.cpython-312.pyc
│   │           │   │   ├── filters.cpython-312.pyc
│   │           │   │   ├── idtracking.cpython-312.pyc
│   │           │   │   ├── lexer.cpython-312.pyc
│   │           │   │   ├── loaders.cpython-312.pyc
│   │           │   │   ├── meta.cpython-312.pyc
│   │           │   │   ├── nativetypes.cpython-312.pyc
│   │           │   │   ├── nodes.cpython-312.pyc
│   │           │   │   ├── optimizer.cpython-312.pyc
│   │           │   │   ├── parser.cpython-312.pyc
│   │           │   │   ├── runtime.cpython-312.pyc
│   │           │   │   ├── sandbox.cpython-312.pyc
│   │           │   │   ├── tests.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── visitor.cpython-312.pyc
│   │           │   ├── _identifier.py
│   │           │   ├── async_utils.py
│   │           │   ├── bccache.py
│   │           │   ├── compiler.py
│   │           │   ├── constants.py
│   │           │   ├── debug.py
│   │           │   ├── defaults.py
│   │           │   ├── environment.py
│   │           │   ├── exceptions.py
│   │           │   ├── ext.py
│   │           │   ├── filters.py
│   │           │   ├── idtracking.py
│   │           │   ├── lexer.py
│   │           │   ├── loaders.py
│   │           │   ├── meta.py
│   │           │   ├── nativetypes.py
│   │           │   ├── nodes.py
│   │           │   ├── optimizer.py
│   │           │   ├── parser.py
│   │           │   ├── py.typed
│   │           │   ├── runtime.py
│   │           │   ├── sandbox.py
│   │           │   ├── tests.py
│   │           │   ├── utils.py
│   │           │   └── visitor.py
│   │           ├── jinja2-3.1.4.dist-info
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── lxml
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _elementpath.cpython-312.pyc
│   │           │   │   ├── builder.cpython-312.pyc
│   │           │   │   ├── cssselect.cpython-312.pyc
│   │           │   │   ├── doctestcompare.cpython-312.pyc
│   │           │   │   ├── ElementInclude.cpython-312.pyc
│   │           │   │   ├── pyclasslookup.cpython-312.pyc
│   │           │   │   ├── sax.cpython-312.pyc
│   │           │   │   └── usedoctest.cpython-312.pyc
│   │           │   ├── _elementpath.cpython-312-darwin.so
│   │           │   ├── _elementpath.py
│   │           │   ├── apihelpers.pxi
│   │           │   ├── builder.cpython-312-darwin.so
│   │           │   ├── builder.py
│   │           │   ├── classlookup.pxi
│   │           │   ├── cleanup.pxi
│   │           │   ├── cssselect.py
│   │           │   ├── debug.pxi
│   │           │   ├── docloader.pxi
│   │           │   ├── doctestcompare.py
│   │           │   ├── dtd.pxi
│   │           │   ├── ElementInclude.py
│   │           │   ├── etree_api.h
│   │           │   ├── etree.cpython-312-darwin.so
│   │           │   ├── etree.h
│   │           │   ├── etree.pyx
│   │           │   ├── extensions.pxi
│   │           │   ├── html
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── _diffcommand.cpython-312.pyc
│   │           │   │   │   ├── _html5builder.cpython-312.pyc
│   │           │   │   │   ├── _setmixin.cpython-312.pyc
│   │           │   │   │   ├── builder.cpython-312.pyc
│   │           │   │   │   ├── clean.cpython-312.pyc
│   │           │   │   │   ├── defs.cpython-312.pyc
│   │           │   │   │   ├── diff.cpython-312.pyc
│   │           │   │   │   ├── ElementSoup.cpython-312.pyc
│   │           │   │   │   ├── formfill.cpython-312.pyc
│   │           │   │   │   ├── html5parser.cpython-312.pyc
│   │           │   │   │   ├── soupparser.cpython-312.pyc
│   │           │   │   │   └── usedoctest.cpython-312.pyc
│   │           │   │   ├── _diffcommand.py
│   │           │   │   ├── _html5builder.py
│   │           │   │   ├── _setmixin.py
│   │           │   │   ├── builder.py
│   │           │   │   ├── clean.py
│   │           │   │   ├── defs.py
│   │           │   │   ├── diff.cpython-312-darwin.so
│   │           │   │   ├── diff.py
│   │           │   │   ├── ElementSoup.py
│   │           │   │   ├── formfill.py
│   │           │   │   ├── html5parser.py
│   │           │   │   ├── soupparser.py
│   │           │   │   └── usedoctest.py
│   │           │   ├── includes
│   │           │   │   ├── __init__.pxd
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   ├── c14n.pxd
│   │           │   │   ├── config.pxd
│   │           │   │   ├── dtdvalid.pxd
│   │           │   │   ├── etree_defs.h
│   │           │   │   ├── etreepublic.pxd
│   │           │   │   ├── extlibs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── libcharset.h
│   │           │   │   │   ├── localcharset.h
│   │           │   │   │   ├── zconf.h
│   │           │   │   │   └── zlib.h
│   │           │   │   ├── htmlparser.pxd
│   │           │   │   ├── libexslt
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── exslt.h
│   │           │   │   │   ├── exsltconfig.h
│   │           │   │   │   └── exsltexports.h
│   │           │   │   ├── libxml
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── c14n.h
│   │           │   │   │   ├── catalog.h
│   │           │   │   │   ├── chvalid.h
│   │           │   │   │   ├── debugXML.h
│   │           │   │   │   ├── dict.h
│   │           │   │   │   ├── encoding.h
│   │           │   │   │   ├── entities.h
│   │           │   │   │   ├── globals.h
│   │           │   │   │   ├── hash.h
│   │           │   │   │   ├── HTMLparser.h
│   │           │   │   │   ├── HTMLtree.h
│   │           │   │   │   ├── list.h
│   │           │   │   │   ├── nanoftp.h
│   │           │   │   │   ├── nanohttp.h
│   │           │   │   │   ├── parser.h
│   │           │   │   │   ├── parserInternals.h
│   │           │   │   │   ├── relaxng.h
│   │           │   │   │   ├── SAX.h
│   │           │   │   │   ├── SAX2.h
│   │           │   │   │   ├── schemasInternals.h
│   │           │   │   │   ├── schematron.h
│   │           │   │   │   ├── threads.h
│   │           │   │   │   ├── tree.h
│   │           │   │   │   ├── uri.h
│   │           │   │   │   ├── valid.h
│   │           │   │   │   ├── xinclude.h
│   │           │   │   │   ├── xlink.h
│   │           │   │   │   ├── xmlautomata.h
│   │           │   │   │   ├── xmlerror.h
│   │           │   │   │   ├── xmlexports.h
│   │           │   │   │   ├── xmlIO.h
│   │           │   │   │   ├── xmlmemory.h
│   │           │   │   │   ├── xmlmodule.h
│   │           │   │   │   ├── xmlreader.h
│   │           │   │   │   ├── xmlregexp.h
│   │           │   │   │   ├── xmlsave.h
│   │           │   │   │   ├── xmlschemas.h
│   │           │   │   │   ├── xmlschemastypes.h
│   │           │   │   │   ├── xmlstring.h
│   │           │   │   │   ├── xmlunicode.h
│   │           │   │   │   ├── xmlversion.h
│   │           │   │   │   ├── xmlwriter.h
│   │           │   │   │   ├── xpath.h
│   │           │   │   │   ├── xpathInternals.h
│   │           │   │   │   └── xpointer.h
│   │           │   │   ├── libxslt
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   │   ├── attributes.h
│   │           │   │   │   ├── documents.h
│   │           │   │   │   ├── extensions.h
│   │           │   │   │   ├── extra.h
│   │           │   │   │   ├── functions.h
│   │           │   │   │   ├── imports.h
│   │           │   │   │   ├── keys.h
│   │           │   │   │   ├── namespaces.h
│   │           │   │   │   ├── numbersInternals.h
│   │           │   │   │   ├── pattern.h
│   │           │   │   │   ├── preproc.h
│   │           │   │   │   ├── security.h
│   │           │   │   │   ├── templates.h
│   │           │   │   │   ├── transform.h
│   │           │   │   │   ├── variables.h
│   │           │   │   │   ├── xslt.h
│   │           │   │   │   ├── xsltconfig.h
│   │           │   │   │   ├── xsltexports.h
│   │           │   │   │   ├── xsltInternals.h
│   │           │   │   │   ├── xsltlocale.h
│   │           │   │   │   └── xsltutils.h
│   │           │   │   ├── lxml-version.h
│   │           │   │   ├── relaxng.pxd
│   │           │   │   ├── schematron.pxd
│   │           │   │   ├── tree.pxd
│   │           │   │   ├── uri.pxd
│   │           │   │   ├── xinclude.pxd
│   │           │   │   ├── xmlerror.pxd
│   │           │   │   ├── xmlparser.pxd
│   │           │   │   ├── xmlschema.pxd
│   │           │   │   ├── xpath.pxd
│   │           │   │   └── xslt.pxd
│   │           │   ├── isoschematron
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   └── __init__.cpython-312.pyc
│   │           │   │   └── resources
│   │           │   │       ├── rng
│   │           │   │       │   └── iso-schematron.rng
│   │           │   │       └── xsl
│   │           │   │           ├── iso-schematron-xslt1
│   │           │   │           │   ├── iso_abstract_expand.xsl
│   │           │   │           │   ├── iso_dsdl_include.xsl
│   │           │   │           │   ├── iso_schematron_message.xsl
│   │           │   │           │   ├── iso_schematron_skeleton_for_xslt1.xsl
│   │           │   │           │   ├── iso_svrl_for_xslt1.xsl
│   │           │   │           │   └── readme.txt
│   │           │   │           ├── RNG2Schtrn.xsl
│   │           │   │           └── XSD2Schtrn.xsl
│   │           │   ├── iterparse.pxi
│   │           │   ├── lxml.etree_api.h
│   │           │   ├── lxml.etree.h
│   │           │   ├── nsclasses.pxi
│   │           │   ├── objectify.cpython-312-darwin.so
│   │           │   ├── objectify.pyx
│   │           │   ├── objectpath.pxi
│   │           │   ├── parser.pxi
│   │           │   ├── parsertarget.pxi
│   │           │   ├── proxy.pxi
│   │           │   ├── public-api.pxi
│   │           │   ├── pyclasslookup.py
│   │           │   ├── readonlytree.pxi
│   │           │   ├── relaxng.pxi
│   │           │   ├── sax.cpython-312-darwin.so
│   │           │   ├── sax.py
│   │           │   ├── saxparser.pxi
│   │           │   ├── schematron.pxi
│   │           │   ├── serializer.pxi
│   │           │   ├── usedoctest.py
│   │           │   ├── xinclude.pxi
│   │           │   ├── xmlerror.pxi
│   │           │   ├── xmlid.pxi
│   │           │   ├── xmlschema.pxi
│   │           │   ├── xpath.pxi
│   │           │   ├── xslt.pxi
│   │           │   └── xsltext.pxi
│   │           ├── lxml-5.3.0.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── LICENSES.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── markupsafe
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   └── _native.cpython-312.pyc
│   │           │   ├── _native.py
│   │           │   ├── _speedups.c
│   │           │   ├── _speedups.cpython-312-darwin.so
│   │           │   ├── _speedups.pyi
│   │           │   └── py.typed
│   │           ├── MarkupSafe-3.0.1.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── pip
│   │           │   ├── __init__.py
│   │           │   ├── __main__.py
│   │           │   ├── __pip-runner__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __main__.cpython-312.pyc
│   │           │   │   └── __pip-runner__.cpython-312.pyc
│   │           │   ├── _internal
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── build_env.cpython-312.pyc
│   │           │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   ├── configuration.cpython-312.pyc
│   │           │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   ├── main.cpython-312.pyc
│   │           │   │   │   ├── pyproject.cpython-312.pyc
│   │           │   │   │   ├── self_outdated_check.cpython-312.pyc
│   │           │   │   │   └── wheel_builder.cpython-312.pyc
│   │           │   │   ├── build_env.py
│   │           │   │   ├── cache.py
│   │           │   │   ├── cli
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── autocompletion.cpython-312.pyc
│   │           │   │   │   │   ├── base_command.cpython-312.pyc
│   │           │   │   │   │   ├── cmdoptions.cpython-312.pyc
│   │           │   │   │   │   ├── command_context.cpython-312.pyc
│   │           │   │   │   │   ├── index_command.cpython-312.pyc
│   │           │   │   │   │   ├── main_parser.cpython-312.pyc
│   │           │   │   │   │   ├── main.cpython-312.pyc
│   │           │   │   │   │   ├── parser.cpython-312.pyc
│   │           │   │   │   │   ├── progress_bars.cpython-312.pyc
│   │           │   │   │   │   ├── req_command.cpython-312.pyc
│   │           │   │   │   │   ├── spinners.cpython-312.pyc
│   │           │   │   │   │   └── status_codes.cpython-312.pyc
│   │           │   │   │   ├── autocompletion.py
│   │           │   │   │   ├── base_command.py
│   │           │   │   │   ├── cmdoptions.py
│   │           │   │   │   ├── command_context.py
│   │           │   │   │   ├── index_command.py
│   │           │   │   │   ├── main_parser.py
│   │           │   │   │   ├── main.py
│   │           │   │   │   ├── parser.py
│   │           │   │   │   ├── progress_bars.py
│   │           │   │   │   ├── req_command.py
│   │           │   │   │   ├── spinners.py
│   │           │   │   │   └── status_codes.py
│   │           │   │   ├── commands
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── check.cpython-312.pyc
│   │           │   │   │   │   ├── completion.cpython-312.pyc
│   │           │   │   │   │   ├── configuration.cpython-312.pyc
│   │           │   │   │   │   ├── debug.cpython-312.pyc
│   │           │   │   │   │   ├── download.cpython-312.pyc
│   │           │   │   │   │   ├── freeze.cpython-312.pyc
│   │           │   │   │   │   ├── hash.cpython-312.pyc
│   │           │   │   │   │   ├── help.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── inspect.cpython-312.pyc
│   │           │   │   │   │   ├── install.cpython-312.pyc
│   │           │   │   │   │   ├── list.cpython-312.pyc
│   │           │   │   │   │   ├── search.cpython-312.pyc
│   │           │   │   │   │   ├── show.cpython-312.pyc
│   │           │   │   │   │   ├── uninstall.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── check.py
│   │           │   │   │   ├── completion.py
│   │           │   │   │   ├── configuration.py
│   │           │   │   │   ├── debug.py
│   │           │   │   │   ├── download.py
│   │           │   │   │   ├── freeze.py
│   │           │   │   │   ├── hash.py
│   │           │   │   │   ├── help.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── inspect.py
│   │           │   │   │   ├── install.py
│   │           │   │   │   ├── list.py
│   │           │   │   │   ├── search.py
│   │           │   │   │   ├── show.py
│   │           │   │   │   ├── uninstall.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── configuration.py
│   │           │   │   ├── distributions
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── base.cpython-312.pyc
│   │           │   │   │   │   ├── installed.cpython-312.pyc
│   │           │   │   │   │   ├── sdist.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── installed.py
│   │           │   │   │   ├── sdist.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── exceptions.py
│   │           │   │   ├── index
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── collector.cpython-312.pyc
│   │           │   │   │   │   ├── package_finder.cpython-312.pyc
│   │           │   │   │   │   └── sources.cpython-312.pyc
│   │           │   │   │   ├── collector.py
│   │           │   │   │   ├── package_finder.py
│   │           │   │   │   └── sources.py
│   │           │   │   ├── locations
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _distutils.cpython-312.pyc
│   │           │   │   │   │   ├── _sysconfig.cpython-312.pyc
│   │           │   │   │   │   └── base.cpython-312.pyc
│   │           │   │   │   ├── _distutils.py
│   │           │   │   │   ├── _sysconfig.py
│   │           │   │   │   └── base.py
│   │           │   │   ├── main.py
│   │           │   │   ├── metadata
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _json.cpython-312.pyc
│   │           │   │   │   │   ├── base.cpython-312.pyc
│   │           │   │   │   │   └── pkg_resources.cpython-312.pyc
│   │           │   │   │   ├── _json.py
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── importlib
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _compat.cpython-312.pyc
│   │           │   │   │   │   │   ├── _dists.cpython-312.pyc
│   │           │   │   │   │   │   └── _envs.cpython-312.pyc
│   │           │   │   │   │   ├── _compat.py
│   │           │   │   │   │   ├── _dists.py
│   │           │   │   │   │   └── _envs.py
│   │           │   │   │   └── pkg_resources.py
│   │           │   │   ├── models
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── candidate.cpython-312.pyc
│   │           │   │   │   │   ├── direct_url.cpython-312.pyc
│   │           │   │   │   │   ├── format_control.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── installation_report.cpython-312.pyc
│   │           │   │   │   │   ├── link.cpython-312.pyc
│   │           │   │   │   │   ├── scheme.cpython-312.pyc
│   │           │   │   │   │   ├── search_scope.cpython-312.pyc
│   │           │   │   │   │   ├── selection_prefs.cpython-312.pyc
│   │           │   │   │   │   ├── target_python.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── candidate.py
│   │           │   │   │   ├── direct_url.py
│   │           │   │   │   ├── format_control.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── installation_report.py
│   │           │   │   │   ├── link.py
│   │           │   │   │   ├── scheme.py
│   │           │   │   │   ├── search_scope.py
│   │           │   │   │   ├── selection_prefs.py
│   │           │   │   │   ├── target_python.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── network
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── download.cpython-312.pyc
│   │           │   │   │   │   ├── lazy_wheel.cpython-312.pyc
│   │           │   │   │   │   ├── session.cpython-312.pyc
│   │           │   │   │   │   ├── utils.cpython-312.pyc
│   │           │   │   │   │   └── xmlrpc.cpython-312.pyc
│   │           │   │   │   ├── auth.py
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── download.py
│   │           │   │   │   ├── lazy_wheel.py
│   │           │   │   │   ├── session.py
│   │           │   │   │   ├── utils.py
│   │           │   │   │   └── xmlrpc.py
│   │           │   │   ├── operations
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── check.cpython-312.pyc
│   │           │   │   │   │   ├── freeze.cpython-312.pyc
│   │           │   │   │   │   └── prepare.cpython-312.pyc
│   │           │   │   │   ├── build
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── build_tracker.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata_editable.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata_legacy.cpython-312.pyc
│   │           │   │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   │   ├── wheel_editable.cpython-312.pyc
│   │           │   │   │   │   │   ├── wheel_legacy.cpython-312.pyc
│   │           │   │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   │   ├── build_tracker.py
│   │           │   │   │   │   ├── metadata_editable.py
│   │           │   │   │   │   ├── metadata_legacy.py
│   │           │   │   │   │   ├── metadata.py
│   │           │   │   │   │   ├── wheel_editable.py
│   │           │   │   │   │   ├── wheel_legacy.py
│   │           │   │   │   │   └── wheel.py
│   │           │   │   │   ├── check.py
│   │           │   │   │   ├── freeze.py
│   │           │   │   │   ├── install
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── editable_legacy.cpython-312.pyc
│   │           │   │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   │   ├── editable_legacy.py
│   │           │   │   │   │   └── wheel.py
│   │           │   │   │   └── prepare.py
│   │           │   │   ├── pyproject.py
│   │           │   │   ├── req
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── constructors.cpython-312.pyc
│   │           │   │   │   │   ├── req_file.cpython-312.pyc
│   │           │   │   │   │   ├── req_install.cpython-312.pyc
│   │           │   │   │   │   ├── req_set.cpython-312.pyc
│   │           │   │   │   │   └── req_uninstall.cpython-312.pyc
│   │           │   │   │   ├── constructors.py
│   │           │   │   │   ├── req_file.py
│   │           │   │   │   ├── req_install.py
│   │           │   │   │   ├── req_set.py
│   │           │   │   │   └── req_uninstall.py
│   │           │   │   ├── resolution
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   └── base.cpython-312.pyc
│   │           │   │   │   ├── base.py
│   │           │   │   │   ├── legacy
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── resolver.cpython-312.pyc
│   │           │   │   │   │   └── resolver.py
│   │           │   │   │   └── resolvelib
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   ├── base.cpython-312.pyc
│   │           │   │   │       │   ├── candidates.cpython-312.pyc
│   │           │   │   │       │   ├── factory.cpython-312.pyc
│   │           │   │   │       │   ├── found_candidates.cpython-312.pyc
│   │           │   │   │       │   ├── provider.cpython-312.pyc
│   │           │   │   │       │   ├── reporter.cpython-312.pyc
│   │           │   │   │       │   ├── requirements.cpython-312.pyc
│   │           │   │   │       │   └── resolver.cpython-312.pyc
│   │           │   │   │       ├── base.py
│   │           │   │   │       ├── candidates.py
│   │           │   │   │       ├── factory.py
│   │           │   │   │       ├── found_candidates.py
│   │           │   │   │       ├── provider.py
│   │           │   │   │       ├── reporter.py
│   │           │   │   │       ├── requirements.py
│   │           │   │   │       └── resolver.py
│   │           │   │   ├── self_outdated_check.py
│   │           │   │   ├── utils
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _jaraco_text.cpython-312.pyc
│   │           │   │   │   │   ├── _log.cpython-312.pyc
│   │           │   │   │   │   ├── appdirs.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── compatibility_tags.cpython-312.pyc
│   │           │   │   │   │   ├── datetime.cpython-312.pyc
│   │           │   │   │   │   ├── deprecation.cpython-312.pyc
│   │           │   │   │   │   ├── direct_url_helpers.cpython-312.pyc
│   │           │   │   │   │   ├── egg_link.cpython-312.pyc
│   │           │   │   │   │   ├── encoding.cpython-312.pyc
│   │           │   │   │   │   ├── entrypoints.cpython-312.pyc
│   │           │   │   │   │   ├── filesystem.cpython-312.pyc
│   │           │   │   │   │   ├── filetypes.cpython-312.pyc
│   │           │   │   │   │   ├── glibc.cpython-312.pyc
│   │           │   │   │   │   ├── hashes.cpython-312.pyc
│   │           │   │   │   │   ├── logging.cpython-312.pyc
│   │           │   │   │   │   ├── misc.cpython-312.pyc
│   │           │   │   │   │   ├── packaging.cpython-312.pyc
│   │           │   │   │   │   ├── retry.cpython-312.pyc
│   │           │   │   │   │   ├── setuptools_build.cpython-312.pyc
│   │           │   │   │   │   ├── subprocess.cpython-312.pyc
│   │           │   │   │   │   ├── temp_dir.cpython-312.pyc
│   │           │   │   │   │   ├── unpacking.cpython-312.pyc
│   │           │   │   │   │   ├── urls.cpython-312.pyc
│   │           │   │   │   │   ├── virtualenv.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── _jaraco_text.py
│   │           │   │   │   ├── _log.py
│   │           │   │   │   ├── appdirs.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── compatibility_tags.py
│   │           │   │   │   ├── datetime.py
│   │           │   │   │   ├── deprecation.py
│   │           │   │   │   ├── direct_url_helpers.py
│   │           │   │   │   ├── egg_link.py
│   │           │   │   │   ├── encoding.py
│   │           │   │   │   ├── entrypoints.py
│   │           │   │   │   ├── filesystem.py
│   │           │   │   │   ├── filetypes.py
│   │           │   │   │   ├── glibc.py
│   │           │   │   │   ├── hashes.py
│   │           │   │   │   ├── logging.py
│   │           │   │   │   ├── misc.py
│   │           │   │   │   ├── packaging.py
│   │           │   │   │   ├── retry.py
│   │           │   │   │   ├── setuptools_build.py
│   │           │   │   │   ├── subprocess.py
│   │           │   │   │   ├── temp_dir.py
│   │           │   │   │   ├── unpacking.py
│   │           │   │   │   ├── urls.py
│   │           │   │   │   ├── virtualenv.py
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── vcs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── bazaar.cpython-312.pyc
│   │           │   │   │   │   ├── git.cpython-312.pyc
│   │           │   │   │   │   ├── mercurial.cpython-312.pyc
│   │           │   │   │   │   ├── subversion.cpython-312.pyc
│   │           │   │   │   │   └── versioncontrol.cpython-312.pyc
│   │           │   │   │   ├── bazaar.py
│   │           │   │   │   ├── git.py
│   │           │   │   │   ├── mercurial.py
│   │           │   │   │   ├── subversion.py
│   │           │   │   │   └── versioncontrol.py
│   │           │   │   └── wheel_builder.py
│   │           │   ├── _vendor
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   └── typing_extensions.cpython-312.pyc
│   │           │   │   ├── cachecontrol
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _cmd.cpython-312.pyc
│   │           │   │   │   │   ├── adapter.cpython-312.pyc
│   │           │   │   │   │   ├── cache.cpython-312.pyc
│   │           │   │   │   │   ├── controller.cpython-312.pyc
│   │           │   │   │   │   ├── filewrapper.cpython-312.pyc
│   │           │   │   │   │   ├── heuristics.cpython-312.pyc
│   │           │   │   │   │   ├── serialize.cpython-312.pyc
│   │           │   │   │   │   └── wrapper.cpython-312.pyc
│   │           │   │   │   ├── _cmd.py
│   │           │   │   │   ├── adapter.py
│   │           │   │   │   ├── cache.py
│   │           │   │   │   ├── caches
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── file_cache.cpython-312.pyc
│   │           │   │   │   │   │   └── redis_cache.cpython-312.pyc
│   │           │   │   │   │   ├── file_cache.py
│   │           │   │   │   │   └── redis_cache.py
│   │           │   │   │   ├── controller.py
│   │           │   │   │   ├── filewrapper.py
│   │           │   │   │   ├── heuristics.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── serialize.py
│   │           │   │   │   └── wrapper.py
│   │           │   │   ├── certifi
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   └── core.cpython-312.pyc
│   │           │   │   │   ├── cacert.pem
│   │           │   │   │   ├── core.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── distlib
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── database.cpython-312.pyc
│   │           │   │   │   │   ├── index.cpython-312.pyc
│   │           │   │   │   │   ├── locators.cpython-312.pyc
│   │           │   │   │   │   ├── manifest.cpython-312.pyc
│   │           │   │   │   │   ├── markers.cpython-312.pyc
│   │           │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   ├── resources.cpython-312.pyc
│   │           │   │   │   │   ├── scripts.cpython-312.pyc
│   │           │   │   │   │   ├── util.cpython-312.pyc
│   │           │   │   │   │   ├── version.cpython-312.pyc
│   │           │   │   │   │   └── wheel.cpython-312.pyc
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── database.py
│   │           │   │   │   ├── index.py
│   │           │   │   │   ├── locators.py
│   │           │   │   │   ├── manifest.py
│   │           │   │   │   ├── markers.py
│   │           │   │   │   ├── metadata.py
│   │           │   │   │   ├── resources.py
│   │           │   │   │   ├── scripts.py
│   │           │   │   │   ├── t32.exe
│   │           │   │   │   ├── t64-arm.exe
│   │           │   │   │   ├── t64.exe
│   │           │   │   │   ├── util.py
│   │           │   │   │   ├── version.py
│   │           │   │   │   ├── w32.exe
│   │           │   │   │   ├── w64-arm.exe
│   │           │   │   │   ├── w64.exe
│   │           │   │   │   └── wheel.py
│   │           │   │   ├── distro
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   └── distro.cpython-312.pyc
│   │           │   │   │   ├── distro.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── idna
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── codec.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── core.cpython-312.pyc
│   │           │   │   │   │   ├── idnadata.cpython-312.pyc
│   │           │   │   │   │   ├── intranges.cpython-312.pyc
│   │           │   │   │   │   ├── package_data.cpython-312.pyc
│   │           │   │   │   │   └── uts46data.cpython-312.pyc
│   │           │   │   │   ├── codec.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── core.py
│   │           │   │   │   ├── idnadata.py
│   │           │   │   │   ├── intranges.py
│   │           │   │   │   ├── package_data.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   └── uts46data.py
│   │           │   │   ├── msgpack
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── ext.cpython-312.pyc
│   │           │   │   │   │   └── fallback.cpython-312.pyc
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── ext.py
│   │           │   │   │   └── fallback.py
│   │           │   │   ├── packaging
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _elffile.cpython-312.pyc
│   │           │   │   │   │   ├── _manylinux.cpython-312.pyc
│   │           │   │   │   │   ├── _musllinux.cpython-312.pyc
│   │           │   │   │   │   ├── _parser.cpython-312.pyc
│   │           │   │   │   │   ├── _structures.cpython-312.pyc
│   │           │   │   │   │   ├── _tokenizer.cpython-312.pyc
│   │           │   │   │   │   ├── markers.cpython-312.pyc
│   │           │   │   │   │   ├── metadata.cpython-312.pyc
│   │           │   │   │   │   ├── requirements.cpython-312.pyc
│   │           │   │   │   │   ├── specifiers.cpython-312.pyc
│   │           │   │   │   │   ├── tags.cpython-312.pyc
│   │           │   │   │   │   ├── utils.cpython-312.pyc
│   │           │   │   │   │   └── version.cpython-312.pyc
│   │           │   │   │   ├── _elffile.py
│   │           │   │   │   ├── _manylinux.py
│   │           │   │   │   ├── _musllinux.py
│   │           │   │   │   ├── _parser.py
│   │           │   │   │   ├── _structures.py
│   │           │   │   │   ├── _tokenizer.py
│   │           │   │   │   ├── markers.py
│   │           │   │   │   ├── metadata.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── requirements.py
│   │           │   │   │   ├── specifiers.py
│   │           │   │   │   ├── tags.py
│   │           │   │   │   ├── utils.py
│   │           │   │   │   └── version.py
│   │           │   │   ├── pkg_resources
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   └── __pycache__
│   │           │   │   │       └── __init__.cpython-312.pyc
│   │           │   │   ├── platformdirs
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── android.cpython-312.pyc
│   │           │   │   │   │   ├── api.cpython-312.pyc
│   │           │   │   │   │   ├── macos.cpython-312.pyc
│   │           │   │   │   │   ├── unix.cpython-312.pyc
│   │           │   │   │   │   ├── version.cpython-312.pyc
│   │           │   │   │   │   └── windows.cpython-312.pyc
│   │           │   │   │   ├── android.py
│   │           │   │   │   ├── api.py
│   │           │   │   │   ├── macos.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── unix.py
│   │           │   │   │   ├── version.py
│   │           │   │   │   └── windows.py
│   │           │   │   ├── pygments
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── cmdline.cpython-312.pyc
│   │           │   │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   │   ├── filter.cpython-312.pyc
│   │           │   │   │   │   ├── formatter.cpython-312.pyc
│   │           │   │   │   │   ├── lexer.cpython-312.pyc
│   │           │   │   │   │   ├── modeline.cpython-312.pyc
│   │           │   │   │   │   ├── plugin.cpython-312.pyc
│   │           │   │   │   │   ├── regexopt.cpython-312.pyc
│   │           │   │   │   │   ├── scanner.cpython-312.pyc
│   │           │   │   │   │   ├── sphinxext.cpython-312.pyc
│   │           │   │   │   │   ├── style.cpython-312.pyc
│   │           │   │   │   │   ├── token.cpython-312.pyc
│   │           │   │   │   │   ├── unistring.cpython-312.pyc
│   │           │   │   │   │   └── util.cpython-312.pyc
│   │           │   │   │   ├── cmdline.py
│   │           │   │   │   ├── console.py
│   │           │   │   │   ├── filter.py
│   │           │   │   │   ├── filters
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   └── __pycache__
│   │           │   │   │   │       └── __init__.cpython-312.pyc
│   │           │   │   │   ├── formatter.py
│   │           │   │   │   ├── formatters
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _mapping.cpython-312.pyc
│   │           │   │   │   │   │   ├── bbcode.cpython-312.pyc
│   │           │   │   │   │   │   ├── groff.cpython-312.pyc
│   │           │   │   │   │   │   ├── html.cpython-312.pyc
│   │           │   │   │   │   │   ├── img.cpython-312.pyc
│   │           │   │   │   │   │   ├── irc.cpython-312.pyc
│   │           │   │   │   │   │   ├── latex.cpython-312.pyc
│   │           │   │   │   │   │   ├── other.cpython-312.pyc
│   │           │   │   │   │   │   ├── pangomarkup.cpython-312.pyc
│   │           │   │   │   │   │   ├── rtf.cpython-312.pyc
│   │           │   │   │   │   │   ├── svg.cpython-312.pyc
│   │           │   │   │   │   │   ├── terminal.cpython-312.pyc
│   │           │   │   │   │   │   └── terminal256.cpython-312.pyc
│   │           │   │   │   │   ├── _mapping.py
│   │           │   │   │   │   ├── bbcode.py
│   │           │   │   │   │   ├── groff.py
│   │           │   │   │   │   ├── html.py
│   │           │   │   │   │   ├── img.py
│   │           │   │   │   │   ├── irc.py
│   │           │   │   │   │   ├── latex.py
│   │           │   │   │   │   ├── other.py
│   │           │   │   │   │   ├── pangomarkup.py
│   │           │   │   │   │   ├── rtf.py
│   │           │   │   │   │   ├── svg.py
│   │           │   │   │   │   ├── terminal.py
│   │           │   │   │   │   └── terminal256.py
│   │           │   │   │   ├── lexer.py
│   │           │   │   │   ├── lexers
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _mapping.cpython-312.pyc
│   │           │   │   │   │   │   └── python.cpython-312.pyc
│   │           │   │   │   │   ├── _mapping.py
│   │           │   │   │   │   └── python.py
│   │           │   │   │   ├── modeline.py
│   │           │   │   │   ├── plugin.py
│   │           │   │   │   ├── regexopt.py
│   │           │   │   │   ├── scanner.py
│   │           │   │   │   ├── sphinxext.py
│   │           │   │   │   ├── style.py
│   │           │   │   │   ├── styles
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── _mapping.cpython-312.pyc
│   │           │   │   │   │   └── _mapping.py
│   │           │   │   │   ├── token.py
│   │           │   │   │   ├── unistring.py
│   │           │   │   │   └── util.py
│   │           │   │   ├── pyproject_hooks
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _compat.cpython-312.pyc
│   │           │   │   │   │   └── _impl.cpython-312.pyc
│   │           │   │   │   ├── _compat.py
│   │           │   │   │   ├── _impl.py
│   │           │   │   │   └── _in_process
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   └── _in_process.cpython-312.pyc
│   │           │   │   │       └── _in_process.py
│   │           │   │   ├── requests
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __version__.cpython-312.pyc
│   │           │   │   │   │   ├── _internal_utils.cpython-312.pyc
│   │           │   │   │   │   ├── adapters.cpython-312.pyc
│   │           │   │   │   │   ├── api.cpython-312.pyc
│   │           │   │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   │   ├── certs.cpython-312.pyc
│   │           │   │   │   │   ├── compat.cpython-312.pyc
│   │           │   │   │   │   ├── cookies.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── help.cpython-312.pyc
│   │           │   │   │   │   ├── hooks.cpython-312.pyc
│   │           │   │   │   │   ├── models.cpython-312.pyc
│   │           │   │   │   │   ├── packages.cpython-312.pyc
│   │           │   │   │   │   ├── sessions.cpython-312.pyc
│   │           │   │   │   │   ├── status_codes.cpython-312.pyc
│   │           │   │   │   │   ├── structures.cpython-312.pyc
│   │           │   │   │   │   └── utils.cpython-312.pyc
│   │           │   │   │   ├── __version__.py
│   │           │   │   │   ├── _internal_utils.py
│   │           │   │   │   ├── adapters.py
│   │           │   │   │   ├── api.py
│   │           │   │   │   ├── auth.py
│   │           │   │   │   ├── certs.py
│   │           │   │   │   ├── compat.py
│   │           │   │   │   ├── cookies.py
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── help.py
│   │           │   │   │   ├── hooks.py
│   │           │   │   │   ├── models.py
│   │           │   │   │   ├── packages.py
│   │           │   │   │   ├── sessions.py
│   │           │   │   │   ├── status_codes.py
│   │           │   │   │   ├── structures.py
│   │           │   │   │   └── utils.py
│   │           │   │   ├── resolvelib
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── providers.cpython-312.pyc
│   │           │   │   │   │   ├── reporters.cpython-312.pyc
│   │           │   │   │   │   ├── resolvers.cpython-312.pyc
│   │           │   │   │   │   └── structs.cpython-312.pyc
│   │           │   │   │   ├── compat
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── collections_abc.cpython-312.pyc
│   │           │   │   │   │   └── collections_abc.py
│   │           │   │   │   ├── providers.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── reporters.py
│   │           │   │   │   ├── resolvers.py
│   │           │   │   │   └── structs.py
│   │           │   │   ├── rich
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __main__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── __main__.cpython-312.pyc
│   │           │   │   │   │   ├── _cell_widths.cpython-312.pyc
│   │           │   │   │   │   ├── _emoji_codes.cpython-312.pyc
│   │           │   │   │   │   ├── _emoji_replace.cpython-312.pyc
│   │           │   │   │   │   ├── _export_format.cpython-312.pyc
│   │           │   │   │   │   ├── _extension.cpython-312.pyc
│   │           │   │   │   │   ├── _fileno.cpython-312.pyc
│   │           │   │   │   │   ├── _inspect.cpython-312.pyc
│   │           │   │   │   │   ├── _log_render.cpython-312.pyc
│   │           │   │   │   │   ├── _loop.cpython-312.pyc
│   │           │   │   │   │   ├── _null_file.cpython-312.pyc
│   │           │   │   │   │   ├── _palettes.cpython-312.pyc
│   │           │   │   │   │   ├── _pick.cpython-312.pyc
│   │           │   │   │   │   ├── _ratio.cpython-312.pyc
│   │           │   │   │   │   ├── _spinners.cpython-312.pyc
│   │           │   │   │   │   ├── _stack.cpython-312.pyc
│   │           │   │   │   │   ├── _timer.cpython-312.pyc
│   │           │   │   │   │   ├── _win32_console.cpython-312.pyc
│   │           │   │   │   │   ├── _windows_renderer.cpython-312.pyc
│   │           │   │   │   │   ├── _windows.cpython-312.pyc
│   │           │   │   │   │   ├── _wrap.cpython-312.pyc
│   │           │   │   │   │   ├── abc.cpython-312.pyc
│   │           │   │   │   │   ├── align.cpython-312.pyc
│   │           │   │   │   │   ├── ansi.cpython-312.pyc
│   │           │   │   │   │   ├── bar.cpython-312.pyc
│   │           │   │   │   │   ├── box.cpython-312.pyc
│   │           │   │   │   │   ├── cells.cpython-312.pyc
│   │           │   │   │   │   ├── color_triplet.cpython-312.pyc
│   │           │   │   │   │   ├── color.cpython-312.pyc
│   │           │   │   │   │   ├── columns.cpython-312.pyc
│   │           │   │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   │   ├── constrain.cpython-312.pyc
│   │           │   │   │   │   ├── containers.cpython-312.pyc
│   │           │   │   │   │   ├── control.cpython-312.pyc
│   │           │   │   │   │   ├── default_styles.cpython-312.pyc
│   │           │   │   │   │   ├── diagnose.cpython-312.pyc
│   │           │   │   │   │   ├── emoji.cpython-312.pyc
│   │           │   │   │   │   ├── errors.cpython-312.pyc
│   │           │   │   │   │   ├── file_proxy.cpython-312.pyc
│   │           │   │   │   │   ├── filesize.cpython-312.pyc
│   │           │   │   │   │   ├── highlighter.cpython-312.pyc
│   │           │   │   │   │   ├── json.cpython-312.pyc
│   │           │   │   │   │   ├── jupyter.cpython-312.pyc
│   │           │   │   │   │   ├── layout.cpython-312.pyc
│   │           │   │   │   │   ├── live_render.cpython-312.pyc
│   │           │   │   │   │   ├── live.cpython-312.pyc
│   │           │   │   │   │   ├── logging.cpython-312.pyc
│   │           │   │   │   │   ├── markup.cpython-312.pyc
│   │           │   │   │   │   ├── measure.cpython-312.pyc
│   │           │   │   │   │   ├── padding.cpython-312.pyc
│   │           │   │   │   │   ├── pager.cpython-312.pyc
│   │           │   │   │   │   ├── palette.cpython-312.pyc
│   │           │   │   │   │   ├── panel.cpython-312.pyc
│   │           │   │   │   │   ├── pretty.cpython-312.pyc
│   │           │   │   │   │   ├── progress_bar.cpython-312.pyc
│   │           │   │   │   │   ├── progress.cpython-312.pyc
│   │           │   │   │   │   ├── prompt.cpython-312.pyc
│   │           │   │   │   │   ├── protocol.cpython-312.pyc
│   │           │   │   │   │   ├── region.cpython-312.pyc
│   │           │   │   │   │   ├── repr.cpython-312.pyc
│   │           │   │   │   │   ├── rule.cpython-312.pyc
│   │           │   │   │   │   ├── scope.cpython-312.pyc
│   │           │   │   │   │   ├── screen.cpython-312.pyc
│   │           │   │   │   │   ├── segment.cpython-312.pyc
│   │           │   │   │   │   ├── spinner.cpython-312.pyc
│   │           │   │   │   │   ├── status.cpython-312.pyc
│   │           │   │   │   │   ├── style.cpython-312.pyc
│   │           │   │   │   │   ├── styled.cpython-312.pyc
│   │           │   │   │   │   ├── syntax.cpython-312.pyc
│   │           │   │   │   │   ├── table.cpython-312.pyc
│   │           │   │   │   │   ├── terminal_theme.cpython-312.pyc
│   │           │   │   │   │   ├── text.cpython-312.pyc
│   │           │   │   │   │   ├── theme.cpython-312.pyc
│   │           │   │   │   │   ├── themes.cpython-312.pyc
│   │           │   │   │   │   ├── traceback.cpython-312.pyc
│   │           │   │   │   │   └── tree.cpython-312.pyc
│   │           │   │   │   ├── _cell_widths.py
│   │           │   │   │   ├── _emoji_codes.py
│   │           │   │   │   ├── _emoji_replace.py
│   │           │   │   │   ├── _export_format.py
│   │           │   │   │   ├── _extension.py
│   │           │   │   │   ├── _fileno.py
│   │           │   │   │   ├── _inspect.py
│   │           │   │   │   ├── _log_render.py
│   │           │   │   │   ├── _loop.py
│   │           │   │   │   ├── _null_file.py
│   │           │   │   │   ├── _palettes.py
│   │           │   │   │   ├── _pick.py
│   │           │   │   │   ├── _ratio.py
│   │           │   │   │   ├── _spinners.py
│   │           │   │   │   ├── _stack.py
│   │           │   │   │   ├── _timer.py
│   │           │   │   │   ├── _win32_console.py
│   │           │   │   │   ├── _windows_renderer.py
│   │           │   │   │   ├── _windows.py
│   │           │   │   │   ├── _wrap.py
│   │           │   │   │   ├── abc.py
│   │           │   │   │   ├── align.py
│   │           │   │   │   ├── ansi.py
│   │           │   │   │   ├── bar.py
│   │           │   │   │   ├── box.py
│   │           │   │   │   ├── cells.py
│   │           │   │   │   ├── color_triplet.py
│   │           │   │   │   ├── color.py
│   │           │   │   │   ├── columns.py
│   │           │   │   │   ├── console.py
│   │           │   │   │   ├── constrain.py
│   │           │   │   │   ├── containers.py
│   │           │   │   │   ├── control.py
│   │           │   │   │   ├── default_styles.py
│   │           │   │   │   ├── diagnose.py
│   │           │   │   │   ├── emoji.py
│   │           │   │   │   ├── errors.py
│   │           │   │   │   ├── file_proxy.py
│   │           │   │   │   ├── filesize.py
│   │           │   │   │   ├── highlighter.py
│   │           │   │   │   ├── json.py
│   │           │   │   │   ├── jupyter.py
│   │           │   │   │   ├── layout.py
│   │           │   │   │   ├── live_render.py
│   │           │   │   │   ├── live.py
│   │           │   │   │   ├── logging.py
│   │           │   │   │   ├── markup.py
│   │           │   │   │   ├── measure.py
│   │           │   │   │   ├── padding.py
│   │           │   │   │   ├── pager.py
│   │           │   │   │   ├── palette.py
│   │           │   │   │   ├── panel.py
│   │           │   │   │   ├── pretty.py
│   │           │   │   │   ├── progress_bar.py
│   │           │   │   │   ├── progress.py
│   │           │   │   │   ├── prompt.py
│   │           │   │   │   ├── protocol.py
│   │           │   │   │   ├── py.typed
│   │           │   │   │   ├── region.py
│   │           │   │   │   ├── repr.py
│   │           │   │   │   ├── rule.py
│   │           │   │   │   ├── scope.py
│   │           │   │   │   ├── screen.py
│   │           │   │   │   ├── segment.py
│   │           │   │   │   ├── spinner.py
│   │           │   │   │   ├── status.py
│   │           │   │   │   ├── style.py
│   │           │   │   │   ├── styled.py
│   │           │   │   │   ├── syntax.py
│   │           │   │   │   ├── table.py
│   │           │   │   │   ├── terminal_theme.py
│   │           │   │   │   ├── text.py
│   │           │   │   │   ├── theme.py
│   │           │   │   │   ├── themes.py
│   │           │   │   │   ├── traceback.py
│   │           │   │   │   └── tree.py
│   │           │   │   ├── tomli
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _parser.cpython-312.pyc
│   │           │   │   │   │   ├── _re.cpython-312.pyc
│   │           │   │   │   │   └── _types.cpython-312.pyc
│   │           │   │   │   ├── _parser.py
│   │           │   │   │   ├── _re.py
│   │           │   │   │   ├── _types.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── truststore
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _api.cpython-312.pyc
│   │           │   │   │   │   ├── _macos.cpython-312.pyc
│   │           │   │   │   │   ├── _openssl.cpython-312.pyc
│   │           │   │   │   │   ├── _ssl_constants.cpython-312.pyc
│   │           │   │   │   │   └── _windows.cpython-312.pyc
│   │           │   │   │   ├── _api.py
│   │           │   │   │   ├── _macos.py
│   │           │   │   │   ├── _openssl.py
│   │           │   │   │   ├── _ssl_constants.py
│   │           │   │   │   ├── _windows.py
│   │           │   │   │   └── py.typed
│   │           │   │   ├── typing_extensions.py
│   │           │   │   ├── urllib3
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── _collections.cpython-312.pyc
│   │           │   │   │   │   ├── _version.cpython-312.pyc
│   │           │   │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   │   ├── connectionpool.cpython-312.pyc
│   │           │   │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   │   ├── fields.cpython-312.pyc
│   │           │   │   │   │   ├── filepost.cpython-312.pyc
│   │           │   │   │   │   ├── poolmanager.cpython-312.pyc
│   │           │   │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   │   └── response.cpython-312.pyc
│   │           │   │   │   ├── _collections.py
│   │           │   │   │   ├── _version.py
│   │           │   │   │   ├── connection.py
│   │           │   │   │   ├── connectionpool.py
│   │           │   │   │   ├── contrib
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   ├── _appengine_environ.cpython-312.pyc
│   │           │   │   │   │   │   ├── appengine.cpython-312.pyc
│   │           │   │   │   │   │   ├── ntlmpool.cpython-312.pyc
│   │           │   │   │   │   │   ├── pyopenssl.cpython-312.pyc
│   │           │   │   │   │   │   ├── securetransport.cpython-312.pyc
│   │           │   │   │   │   │   └── socks.cpython-312.pyc
│   │           │   │   │   │   ├── _appengine_environ.py
│   │           │   │   │   │   ├── _securetransport
│   │           │   │   │   │   │   ├── __init__.py
│   │           │   │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   │   ├── bindings.cpython-312.pyc
│   │           │   │   │   │   │   │   └── low_level.cpython-312.pyc
│   │           │   │   │   │   │   ├── bindings.py
│   │           │   │   │   │   │   └── low_level.py
│   │           │   │   │   │   ├── appengine.py
│   │           │   │   │   │   ├── ntlmpool.py
│   │           │   │   │   │   ├── pyopenssl.py
│   │           │   │   │   │   ├── securetransport.py
│   │           │   │   │   │   └── socks.py
│   │           │   │   │   ├── exceptions.py
│   │           │   │   │   ├── fields.py
│   │           │   │   │   ├── filepost.py
│   │           │   │   │   ├── packages
│   │           │   │   │   │   ├── __init__.py
│   │           │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   └── six.cpython-312.pyc
│   │           │   │   │   │   ├── backports
│   │           │   │   │   │   │   ├── __init__.py
│   │           │   │   │   │   │   ├── __pycache__
│   │           │   │   │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   │   │   ├── makefile.cpython-312.pyc
│   │           │   │   │   │   │   │   └── weakref_finalize.cpython-312.pyc
│   │           │   │   │   │   │   ├── makefile.py
│   │           │   │   │   │   │   └── weakref_finalize.py
│   │           │   │   │   │   └── six.py
│   │           │   │   │   ├── poolmanager.py
│   │           │   │   │   ├── request.py
│   │           │   │   │   ├── response.py
│   │           │   │   │   └── util
│   │           │   │   │       ├── __init__.py
│   │           │   │   │       ├── __pycache__
│   │           │   │   │       │   ├── __init__.cpython-312.pyc
│   │           │   │   │       │   ├── connection.cpython-312.pyc
│   │           │   │   │       │   ├── proxy.cpython-312.pyc
│   │           │   │   │       │   ├── queue.cpython-312.pyc
│   │           │   │   │       │   ├── request.cpython-312.pyc
│   │           │   │   │       │   ├── response.cpython-312.pyc
│   │           │   │   │       │   ├── retry.cpython-312.pyc
│   │           │   │   │       │   ├── ssl_.cpython-312.pyc
│   │           │   │   │       │   ├── ssl_match_hostname.cpython-312.pyc
│   │           │   │   │       │   ├── ssltransport.cpython-312.pyc
│   │           │   │   │       │   ├── timeout.cpython-312.pyc
│   │           │   │   │       │   ├── url.cpython-312.pyc
│   │           │   │   │       │   └── wait.cpython-312.pyc
│   │           │   │   │       ├── connection.py
│   │           │   │   │       ├── proxy.py
│   │           │   │   │       ├── queue.py
│   │           │   │   │       ├── request.py
│   │           │   │   │       ├── response.py
│   │           │   │   │       ├── retry.py
│   │           │   │   │       ├── ssl_.py
│   │           │   │   │       ├── ssl_match_hostname.py
│   │           │   │   │       ├── ssltransport.py
│   │           │   │   │       ├── timeout.py
│   │           │   │   │       ├── url.py
│   │           │   │   │       └── wait.py
│   │           │   │   └── vendor.txt
│   │           │   └── py.typed
│   │           ├── pip-24.2.dist-info
│   │           │   ├── AUTHORS.txt
│   │           │   ├── entry_points.txt
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── requests
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __version__.cpython-312.pyc
│   │           │   │   ├── _internal_utils.cpython-312.pyc
│   │           │   │   ├── adapters.cpython-312.pyc
│   │           │   │   ├── api.cpython-312.pyc
│   │           │   │   ├── auth.cpython-312.pyc
│   │           │   │   ├── certs.cpython-312.pyc
│   │           │   │   ├── compat.cpython-312.pyc
│   │           │   │   ├── cookies.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── help.cpython-312.pyc
│   │           │   │   ├── hooks.cpython-312.pyc
│   │           │   │   ├── models.cpython-312.pyc
│   │           │   │   ├── packages.cpython-312.pyc
│   │           │   │   ├── sessions.cpython-312.pyc
│   │           │   │   ├── status_codes.cpython-312.pyc
│   │           │   │   ├── structures.cpython-312.pyc
│   │           │   │   └── utils.cpython-312.pyc
│   │           │   ├── __version__.py
│   │           │   ├── _internal_utils.py
│   │           │   ├── adapters.py
│   │           │   ├── api.py
│   │           │   ├── auth.py
│   │           │   ├── certs.py
│   │           │   ├── compat.py
│   │           │   ├── cookies.py
│   │           │   ├── exceptions.py
│   │           │   ├── help.py
│   │           │   ├── hooks.py
│   │           │   ├── models.py
│   │           │   ├── packages.py
│   │           │   ├── sessions.py
│   │           │   ├── status_codes.py
│   │           │   ├── structures.py
│   │           │   └── utils.py
│   │           ├── requests-2.32.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── soupsieve
│   │           │   ├── __init__.py
│   │           │   ├── __meta__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── __meta__.cpython-312.pyc
│   │           │   │   ├── css_match.cpython-312.pyc
│   │           │   │   ├── css_parser.cpython-312.pyc
│   │           │   │   ├── css_types.cpython-312.pyc
│   │           │   │   ├── pretty.cpython-312.pyc
│   │           │   │   └── util.cpython-312.pyc
│   │           │   ├── css_match.py
│   │           │   ├── css_parser.py
│   │           │   ├── css_types.py
│   │           │   ├── pretty.py
│   │           │   ├── py.typed
│   │           │   └── util.py
│   │           ├── soupsieve-2.6.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   └── LICENSE.md
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── urllib3
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _base_connection.cpython-312.pyc
│   │           │   │   ├── _collections.cpython-312.pyc
│   │           │   │   ├── _request_methods.cpython-312.pyc
│   │           │   │   ├── _version.cpython-312.pyc
│   │           │   │   ├── connection.cpython-312.pyc
│   │           │   │   ├── connectionpool.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── fields.cpython-312.pyc
│   │           │   │   ├── filepost.cpython-312.pyc
│   │           │   │   ├── poolmanager.cpython-312.pyc
│   │           │   │   └── response.cpython-312.pyc
│   │           │   ├── _base_connection.py
│   │           │   ├── _collections.py
│   │           │   ├── _request_methods.py
│   │           │   ├── _version.py
│   │           │   ├── connection.py
│   │           │   ├── connectionpool.py
│   │           │   ├── contrib
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── pyopenssl.cpython-312.pyc
│   │           │   │   │   └── socks.cpython-312.pyc
│   │           │   │   ├── emscripten
│   │           │   │   │   ├── __init__.py
│   │           │   │   │   ├── __pycache__
│   │           │   │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   │   ├── fetch.cpython-312.pyc
│   │           │   │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   │   └── response.cpython-312.pyc
│   │           │   │   │   ├── connection.py
│   │           │   │   │   ├── emscripten_fetch_worker.js
│   │           │   │   │   ├── fetch.py
│   │           │   │   │   ├── request.py
│   │           │   │   │   └── response.py
│   │           │   │   ├── pyopenssl.py
│   │           │   │   └── socks.py
│   │           │   ├── exceptions.py
│   │           │   ├── fields.py
│   │           │   ├── filepost.py
│   │           │   ├── http2
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── connection.cpython-312.pyc
│   │           │   │   │   └── probe.cpython-312.pyc
│   │           │   │   ├── connection.py
│   │           │   │   └── probe.py
│   │           │   ├── poolmanager.py
│   │           │   ├── py.typed
│   │           │   ├── response.py
│   │           │   └── util
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   ├── __init__.cpython-312.pyc
│   │           │       │   ├── connection.cpython-312.pyc
│   │           │       │   ├── proxy.cpython-312.pyc
│   │           │       │   ├── request.cpython-312.pyc
│   │           │       │   ├── response.cpython-312.pyc
│   │           │       │   ├── retry.cpython-312.pyc
│   │           │       │   ├── ssl_.cpython-312.pyc
│   │           │       │   ├── ssl_match_hostname.cpython-312.pyc
│   │           │       │   ├── ssltransport.cpython-312.pyc
│   │           │       │   ├── timeout.cpython-312.pyc
│   │           │       │   ├── url.cpython-312.pyc
│   │           │       │   ├── util.cpython-312.pyc
│   │           │       │   └── wait.cpython-312.pyc
│   │           │       ├── connection.py
│   │           │       ├── proxy.py
│   │           │       ├── request.py
│   │           │       ├── response.py
│   │           │       ├── retry.py
│   │           │       ├── ssl_.py
│   │           │       ├── ssl_match_hostname.py
│   │           │       ├── ssltransport.py
│   │           │       ├── timeout.py
│   │           │       ├── url.py
│   │           │       ├── util.py
│   │           │       └── wait.py
│   │           ├── urllib3-2.2.3.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── licenses
│   │           │   │   └── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   └── WHEEL
│   │           ├── useragent
│   │           │   ├── __init__.py
│   │           │   ├── __init__.pyc
│   │           │   ├── __pycache__
│   │           │   │   └── __init__.cpython-312.pyc
│   │           │   ├── resources
│   │           │   │   └── user_agent_data.json
│   │           │   └── test
│   │           │       ├── __init__.py
│   │           │       ├── __pycache__
│   │           │       │   └── __init__.cpython-312.pyc
│   │           │       ├── test_additional_os.json
│   │           │       ├── test_browser.json
│   │           │       ├── test_device.json
│   │           │       ├── test_firefox.json
│   │           │       ├── test_os.json
│   │           │       └── test_pgts_browser.json
│   │           ├── useragent-0.1.1.dist-info
│   │           │   ├── INSTALLER
│   │           │   ├── LICENSE.txt
│   │           │   ├── METADATA
│   │           │   ├── RECORD
│   │           │   ├── REQUESTED
│   │           │   ├── top_level.txt
│   │           │   └── WHEEL
│   │           ├── werkzeug
│   │           │   ├── __init__.py
│   │           │   ├── __pycache__
│   │           │   │   ├── __init__.cpython-312.pyc
│   │           │   │   ├── _internal.cpython-312.pyc
│   │           │   │   ├── _reloader.cpython-312.pyc
│   │           │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   ├── formparser.cpython-312.pyc
│   │           │   │   ├── http.cpython-312.pyc
│   │           │   │   ├── local.cpython-312.pyc
│   │           │   │   ├── security.cpython-312.pyc
│   │           │   │   ├── serving.cpython-312.pyc
│   │           │   │   ├── test.cpython-312.pyc
│   │           │   │   ├── testapp.cpython-312.pyc
│   │           │   │   ├── urls.cpython-312.pyc
│   │           │   │   ├── user_agent.cpython-312.pyc
│   │           │   │   ├── utils.cpython-312.pyc
│   │           │   │   └── wsgi.cpython-312.pyc
│   │           │   ├── _internal.py
│   │           │   ├── _reloader.py
│   │           │   ├── datastructures
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── accept.cpython-312.pyc
│   │           │   │   │   ├── auth.cpython-312.pyc
│   │           │   │   │   ├── cache_control.cpython-312.pyc
│   │           │   │   │   ├── csp.cpython-312.pyc
│   │           │   │   │   ├── etag.cpython-312.pyc
│   │           │   │   │   ├── file_storage.cpython-312.pyc
│   │           │   │   │   ├── headers.cpython-312.pyc
│   │           │   │   │   ├── mixins.cpython-312.pyc
│   │           │   │   │   ├── range.cpython-312.pyc
│   │           │   │   │   └── structures.cpython-312.pyc
│   │           │   │   ├── accept.py
│   │           │   │   ├── accept.pyi
│   │           │   │   ├── auth.py
│   │           │   │   ├── cache_control.py
│   │           │   │   ├── cache_control.pyi
│   │           │   │   ├── csp.py
│   │           │   │   ├── csp.pyi
│   │           │   │   ├── etag.py
│   │           │   │   ├── etag.pyi
│   │           │   │   ├── file_storage.py
│   │           │   │   ├── file_storage.pyi
│   │           │   │   ├── headers.py
│   │           │   │   ├── headers.pyi
│   │           │   │   ├── mixins.py
│   │           │   │   ├── mixins.pyi
│   │           │   │   ├── range.py
│   │           │   │   ├── range.pyi
│   │           │   │   ├── structures.py
│   │           │   │   └── structures.pyi
│   │           │   ├── debug
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── console.cpython-312.pyc
│   │           │   │   │   ├── repr.cpython-312.pyc
│   │           │   │   │   └── tbtools.cpython-312.pyc
│   │           │   │   ├── console.py
│   │           │   │   ├── repr.py
│   │           │   │   ├── shared
│   │           │   │   │   ├── console.png
│   │           │   │   │   ├── debugger.js
│   │           │   │   │   ├── ICON_LICENSE.md
│   │           │   │   │   ├── less.png
│   │           │   │   │   ├── more.png
│   │           │   │   │   └── style.css
│   │           │   │   └── tbtools.py
│   │           │   ├── exceptions.py
│   │           │   ├── formparser.py
│   │           │   ├── http.py
│   │           │   ├── local.py
│   │           │   ├── middleware
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── dispatcher.cpython-312.pyc
│   │           │   │   │   ├── http_proxy.cpython-312.pyc
│   │           │   │   │   ├── lint.cpython-312.pyc
│   │           │   │   │   ├── profiler.cpython-312.pyc
│   │           │   │   │   ├── proxy_fix.cpython-312.pyc
│   │           │   │   │   └── shared_data.cpython-312.pyc
│   │           │   │   ├── dispatcher.py
│   │           │   │   ├── http_proxy.py
│   │           │   │   ├── lint.py
│   │           │   │   ├── profiler.py
│   │           │   │   ├── proxy_fix.py
│   │           │   │   └── shared_data.py
│   │           │   ├── py.typed
│   │           │   ├── routing
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── converters.cpython-312.pyc
│   │           │   │   │   ├── exceptions.cpython-312.pyc
│   │           │   │   │   ├── map.cpython-312.pyc
│   │           │   │   │   ├── matcher.cpython-312.pyc
│   │           │   │   │   └── rules.cpython-312.pyc
│   │           │   │   ├── converters.py
│   │           │   │   ├── exceptions.py
│   │           │   │   ├── map.py
│   │           │   │   ├── matcher.py
│   │           │   │   └── rules.py
│   │           │   ├── sansio
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── http.cpython-312.pyc
│   │           │   │   │   ├── multipart.cpython-312.pyc
│   │           │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   ├── response.cpython-312.pyc
│   │           │   │   │   └── utils.cpython-312.pyc
│   │           │   │   ├── http.py
│   │           │   │   ├── multipart.py
│   │           │   │   ├── request.py
│   │           │   │   ├── response.py
│   │           │   │   └── utils.py
│   │           │   ├── security.py
│   │           │   ├── serving.py
│   │           │   ├── test.py
│   │           │   ├── testapp.py
│   │           │   ├── urls.py
│   │           │   ├── user_agent.py
│   │           │   ├── utils.py
│   │           │   ├── wrappers
│   │           │   │   ├── __init__.py
│   │           │   │   ├── __pycache__
│   │           │   │   │   ├── __init__.cpython-312.pyc
│   │           │   │   │   ├── request.cpython-312.pyc
│   │           │   │   │   └── response.cpython-312.pyc
│   │           │   │   ├── request.py
│   │           │   │   └── response.py
│   │           │   └── wsgi.py
│   │           └── werkzeug-3.0.4.dist-info
│   │               ├── INSTALLER
│   │               ├── LICENSE.txt
│   │               ├── METADATA
│   │               ├── RECORD
│   │               └── WHEEL
│   ├── pyvenv.cfg
│   ├── static
│   │   └── styles.css
│   ├── templates
│   │   └── index.html
│   └── test.py
├── cline_config.json
├── mcp_server.py
├── README.md
├── search_results.json
├── settings.json
└── test_files
    ├── text1.txt
    └── text2.txt
```

# Files

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

```python
   1 | import inspect
   2 | import os
   3 | import platform
   4 | import sys
   5 | import threading
   6 | import zlib
   7 | from abc import ABC, abstractmethod
   8 | from dataclasses import dataclass, field
   9 | from datetime import datetime
  10 | from functools import wraps
  11 | from getpass import getpass
  12 | from html import escape
  13 | from inspect import isclass
  14 | from itertools import islice
  15 | from math import ceil
  16 | from time import monotonic
  17 | from types import FrameType, ModuleType, TracebackType
  18 | from typing import (
  19 |     IO,
  20 |     TYPE_CHECKING,
  21 |     Any,
  22 |     Callable,
  23 |     Dict,
  24 |     Iterable,
  25 |     List,
  26 |     Mapping,
  27 |     NamedTuple,
  28 |     Optional,
  29 |     TextIO,
  30 |     Tuple,
  31 |     Type,
  32 |     Union,
  33 |     cast,
  34 | )
  35 | 
  36 | from pip._vendor.rich._null_file import NULL_FILE
  37 | 
  38 | if sys.version_info >= (3, 8):
  39 |     from typing import Literal, Protocol, runtime_checkable
  40 | else:
  41 |     from pip._vendor.typing_extensions import (
  42 |         Literal,
  43 |         Protocol,
  44 |         runtime_checkable,
  45 |     )  # pragma: no cover
  46 | 
  47 | from . import errors, themes
  48 | from ._emoji_replace import _emoji_replace
  49 | from ._export_format import CONSOLE_HTML_FORMAT, CONSOLE_SVG_FORMAT
  50 | from ._fileno import get_fileno
  51 | from ._log_render import FormatTimeCallable, LogRender
  52 | from .align import Align, AlignMethod
  53 | from .color import ColorSystem, blend_rgb
  54 | from .control import Control
  55 | from .emoji import EmojiVariant
  56 | from .highlighter import NullHighlighter, ReprHighlighter
  57 | from .markup import render as render_markup
  58 | from .measure import Measurement, measure_renderables
  59 | from .pager import Pager, SystemPager
  60 | from .pretty import Pretty, is_expandable
  61 | from .protocol import rich_cast
  62 | from .region import Region
  63 | from .scope import render_scope
  64 | from .screen import Screen
  65 | from .segment import Segment
  66 | from .style import Style, StyleType
  67 | from .styled import Styled
  68 | from .terminal_theme import DEFAULT_TERMINAL_THEME, SVG_EXPORT_THEME, TerminalTheme
  69 | from .text import Text, TextType
  70 | from .theme import Theme, ThemeStack
  71 | 
  72 | if TYPE_CHECKING:
  73 |     from ._windows import WindowsConsoleFeatures
  74 |     from .live import Live
  75 |     from .status import Status
  76 | 
  77 | JUPYTER_DEFAULT_COLUMNS = 115
  78 | JUPYTER_DEFAULT_LINES = 100
  79 | WINDOWS = platform.system() == "Windows"
  80 | 
  81 | HighlighterType = Callable[[Union[str, "Text"]], "Text"]
  82 | JustifyMethod = Literal["default", "left", "center", "right", "full"]
  83 | OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"]
  84 | 
  85 | 
  86 | class NoChange:
  87 |     pass
  88 | 
  89 | 
  90 | NO_CHANGE = NoChange()
  91 | 
  92 | try:
  93 |     _STDIN_FILENO = sys.__stdin__.fileno()
  94 | except Exception:
  95 |     _STDIN_FILENO = 0
  96 | try:
  97 |     _STDOUT_FILENO = sys.__stdout__.fileno()
  98 | except Exception:
  99 |     _STDOUT_FILENO = 1
 100 | try:
 101 |     _STDERR_FILENO = sys.__stderr__.fileno()
 102 | except Exception:
 103 |     _STDERR_FILENO = 2
 104 | 
 105 | _STD_STREAMS = (_STDIN_FILENO, _STDOUT_FILENO, _STDERR_FILENO)
 106 | _STD_STREAMS_OUTPUT = (_STDOUT_FILENO, _STDERR_FILENO)
 107 | 
 108 | 
 109 | _TERM_COLORS = {
 110 |     "kitty": ColorSystem.EIGHT_BIT,
 111 |     "256color": ColorSystem.EIGHT_BIT,
 112 |     "16color": ColorSystem.STANDARD,
 113 | }
 114 | 
 115 | 
 116 | class ConsoleDimensions(NamedTuple):
 117 |     """Size of the terminal."""
 118 | 
 119 |     width: int
 120 |     """The width of the console in 'cells'."""
 121 |     height: int
 122 |     """The height of the console in lines."""
 123 | 
 124 | 
 125 | @dataclass
 126 | class ConsoleOptions:
 127 |     """Options for __rich_console__ method."""
 128 | 
 129 |     size: ConsoleDimensions
 130 |     """Size of console."""
 131 |     legacy_windows: bool
 132 |     """legacy_windows: flag for legacy windows."""
 133 |     min_width: int
 134 |     """Minimum width of renderable."""
 135 |     max_width: int
 136 |     """Maximum width of renderable."""
 137 |     is_terminal: bool
 138 |     """True if the target is a terminal, otherwise False."""
 139 |     encoding: str
 140 |     """Encoding of terminal."""
 141 |     max_height: int
 142 |     """Height of container (starts as terminal)"""
 143 |     justify: Optional[JustifyMethod] = None
 144 |     """Justify value override for renderable."""
 145 |     overflow: Optional[OverflowMethod] = None
 146 |     """Overflow value override for renderable."""
 147 |     no_wrap: Optional[bool] = False
 148 |     """Disable wrapping for text."""
 149 |     highlight: Optional[bool] = None
 150 |     """Highlight override for render_str."""
 151 |     markup: Optional[bool] = None
 152 |     """Enable markup when rendering strings."""
 153 |     height: Optional[int] = None
 154 | 
 155 |     @property
 156 |     def ascii_only(self) -> bool:
 157 |         """Check if renderables should use ascii only."""
 158 |         return not self.encoding.startswith("utf")
 159 | 
 160 |     def copy(self) -> "ConsoleOptions":
 161 |         """Return a copy of the options.
 162 | 
 163 |         Returns:
 164 |             ConsoleOptions: a copy of self.
 165 |         """
 166 |         options: ConsoleOptions = ConsoleOptions.__new__(ConsoleOptions)
 167 |         options.__dict__ = self.__dict__.copy()
 168 |         return options
 169 | 
 170 |     def update(
 171 |         self,
 172 |         *,
 173 |         width: Union[int, NoChange] = NO_CHANGE,
 174 |         min_width: Union[int, NoChange] = NO_CHANGE,
 175 |         max_width: Union[int, NoChange] = NO_CHANGE,
 176 |         justify: Union[Optional[JustifyMethod], NoChange] = NO_CHANGE,
 177 |         overflow: Union[Optional[OverflowMethod], NoChange] = NO_CHANGE,
 178 |         no_wrap: Union[Optional[bool], NoChange] = NO_CHANGE,
 179 |         highlight: Union[Optional[bool], NoChange] = NO_CHANGE,
 180 |         markup: Union[Optional[bool], NoChange] = NO_CHANGE,
 181 |         height: Union[Optional[int], NoChange] = NO_CHANGE,
 182 |     ) -> "ConsoleOptions":
 183 |         """Update values, return a copy."""
 184 |         options = self.copy()
 185 |         if not isinstance(width, NoChange):
 186 |             options.min_width = options.max_width = max(0, width)
 187 |         if not isinstance(min_width, NoChange):
 188 |             options.min_width = min_width
 189 |         if not isinstance(max_width, NoChange):
 190 |             options.max_width = max_width
 191 |         if not isinstance(justify, NoChange):
 192 |             options.justify = justify
 193 |         if not isinstance(overflow, NoChange):
 194 |             options.overflow = overflow
 195 |         if not isinstance(no_wrap, NoChange):
 196 |             options.no_wrap = no_wrap
 197 |         if not isinstance(highlight, NoChange):
 198 |             options.highlight = highlight
 199 |         if not isinstance(markup, NoChange):
 200 |             options.markup = markup
 201 |         if not isinstance(height, NoChange):
 202 |             if height is not None:
 203 |                 options.max_height = height
 204 |             options.height = None if height is None else max(0, height)
 205 |         return options
 206 | 
 207 |     def update_width(self, width: int) -> "ConsoleOptions":
 208 |         """Update just the width, return a copy.
 209 | 
 210 |         Args:
 211 |             width (int): New width (sets both min_width and max_width)
 212 | 
 213 |         Returns:
 214 |             ~ConsoleOptions: New console options instance.
 215 |         """
 216 |         options = self.copy()
 217 |         options.min_width = options.max_width = max(0, width)
 218 |         return options
 219 | 
 220 |     def update_height(self, height: int) -> "ConsoleOptions":
 221 |         """Update the height, and return a copy.
 222 | 
 223 |         Args:
 224 |             height (int): New height
 225 | 
 226 |         Returns:
 227 |             ~ConsoleOptions: New Console options instance.
 228 |         """
 229 |         options = self.copy()
 230 |         options.max_height = options.height = height
 231 |         return options
 232 | 
 233 |     def reset_height(self) -> "ConsoleOptions":
 234 |         """Return a copy of the options with height set to ``None``.
 235 | 
 236 |         Returns:
 237 |             ~ConsoleOptions: New console options instance.
 238 |         """
 239 |         options = self.copy()
 240 |         options.height = None
 241 |         return options
 242 | 
 243 |     def update_dimensions(self, width: int, height: int) -> "ConsoleOptions":
 244 |         """Update the width and height, and return a copy.
 245 | 
 246 |         Args:
 247 |             width (int): New width (sets both min_width and max_width).
 248 |             height (int): New height.
 249 | 
 250 |         Returns:
 251 |             ~ConsoleOptions: New console options instance.
 252 |         """
 253 |         options = self.copy()
 254 |         options.min_width = options.max_width = max(0, width)
 255 |         options.height = options.max_height = height
 256 |         return options
 257 | 
 258 | 
 259 | @runtime_checkable
 260 | class RichCast(Protocol):
 261 |     """An object that may be 'cast' to a console renderable."""
 262 | 
 263 |     def __rich__(
 264 |         self,
 265 |     ) -> Union["ConsoleRenderable", "RichCast", str]:  # pragma: no cover
 266 |         ...
 267 | 
 268 | 
 269 | @runtime_checkable
 270 | class ConsoleRenderable(Protocol):
 271 |     """An object that supports the console protocol."""
 272 | 
 273 |     def __rich_console__(
 274 |         self, console: "Console", options: "ConsoleOptions"
 275 |     ) -> "RenderResult":  # pragma: no cover
 276 |         ...
 277 | 
 278 | 
 279 | # A type that may be rendered by Console.
 280 | RenderableType = Union[ConsoleRenderable, RichCast, str]
 281 | """A string or any object that may be rendered by Rich."""
 282 | 
 283 | # The result of calling a __rich_console__ method.
 284 | RenderResult = Iterable[Union[RenderableType, Segment]]
 285 | 
 286 | _null_highlighter = NullHighlighter()
 287 | 
 288 | 
 289 | class CaptureError(Exception):
 290 |     """An error in the Capture context manager."""
 291 | 
 292 | 
 293 | class NewLine:
 294 |     """A renderable to generate new line(s)"""
 295 | 
 296 |     def __init__(self, count: int = 1) -> None:
 297 |         self.count = count
 298 | 
 299 |     def __rich_console__(
 300 |         self, console: "Console", options: "ConsoleOptions"
 301 |     ) -> Iterable[Segment]:
 302 |         yield Segment("\n" * self.count)
 303 | 
 304 | 
 305 | class ScreenUpdate:
 306 |     """Render a list of lines at a given offset."""
 307 | 
 308 |     def __init__(self, lines: List[List[Segment]], x: int, y: int) -> None:
 309 |         self._lines = lines
 310 |         self.x = x
 311 |         self.y = y
 312 | 
 313 |     def __rich_console__(
 314 |         self, console: "Console", options: ConsoleOptions
 315 |     ) -> RenderResult:
 316 |         x = self.x
 317 |         move_to = Control.move_to
 318 |         for offset, line in enumerate(self._lines, self.y):
 319 |             yield move_to(x, offset)
 320 |             yield from line
 321 | 
 322 | 
 323 | class Capture:
 324 |     """Context manager to capture the result of printing to the console.
 325 |     See :meth:`~rich.console.Console.capture` for how to use.
 326 | 
 327 |     Args:
 328 |         console (Console): A console instance to capture output.
 329 |     """
 330 | 
 331 |     def __init__(self, console: "Console") -> None:
 332 |         self._console = console
 333 |         self._result: Optional[str] = None
 334 | 
 335 |     def __enter__(self) -> "Capture":
 336 |         self._console.begin_capture()
 337 |         return self
 338 | 
 339 |     def __exit__(
 340 |         self,
 341 |         exc_type: Optional[Type[BaseException]],
 342 |         exc_val: Optional[BaseException],
 343 |         exc_tb: Optional[TracebackType],
 344 |     ) -> None:
 345 |         self._result = self._console.end_capture()
 346 | 
 347 |     def get(self) -> str:
 348 |         """Get the result of the capture."""
 349 |         if self._result is None:
 350 |             raise CaptureError(
 351 |                 "Capture result is not available until context manager exits."
 352 |             )
 353 |         return self._result
 354 | 
 355 | 
 356 | class ThemeContext:
 357 |     """A context manager to use a temporary theme. See :meth:`~rich.console.Console.use_theme` for usage."""
 358 | 
 359 |     def __init__(self, console: "Console", theme: Theme, inherit: bool = True) -> None:
 360 |         self.console = console
 361 |         self.theme = theme
 362 |         self.inherit = inherit
 363 | 
 364 |     def __enter__(self) -> "ThemeContext":
 365 |         self.console.push_theme(self.theme)
 366 |         return self
 367 | 
 368 |     def __exit__(
 369 |         self,
 370 |         exc_type: Optional[Type[BaseException]],
 371 |         exc_val: Optional[BaseException],
 372 |         exc_tb: Optional[TracebackType],
 373 |     ) -> None:
 374 |         self.console.pop_theme()
 375 | 
 376 | 
 377 | class PagerContext:
 378 |     """A context manager that 'pages' content. See :meth:`~rich.console.Console.pager` for usage."""
 379 | 
 380 |     def __init__(
 381 |         self,
 382 |         console: "Console",
 383 |         pager: Optional[Pager] = None,
 384 |         styles: bool = False,
 385 |         links: bool = False,
 386 |     ) -> None:
 387 |         self._console = console
 388 |         self.pager = SystemPager() if pager is None else pager
 389 |         self.styles = styles
 390 |         self.links = links
 391 | 
 392 |     def __enter__(self) -> "PagerContext":
 393 |         self._console._enter_buffer()
 394 |         return self
 395 | 
 396 |     def __exit__(
 397 |         self,
 398 |         exc_type: Optional[Type[BaseException]],
 399 |         exc_val: Optional[BaseException],
 400 |         exc_tb: Optional[TracebackType],
 401 |     ) -> None:
 402 |         if exc_type is None:
 403 |             with self._console._lock:
 404 |                 buffer: List[Segment] = self._console._buffer[:]
 405 |                 del self._console._buffer[:]
 406 |                 segments: Iterable[Segment] = buffer
 407 |                 if not self.styles:
 408 |                     segments = Segment.strip_styles(segments)
 409 |                 elif not self.links:
 410 |                     segments = Segment.strip_links(segments)
 411 |                 content = self._console._render_buffer(segments)
 412 |             self.pager.show(content)
 413 |         self._console._exit_buffer()
 414 | 
 415 | 
 416 | class ScreenContext:
 417 |     """A context manager that enables an alternative screen. See :meth:`~rich.console.Console.screen` for usage."""
 418 | 
 419 |     def __init__(
 420 |         self, console: "Console", hide_cursor: bool, style: StyleType = ""
 421 |     ) -> None:
 422 |         self.console = console
 423 |         self.hide_cursor = hide_cursor
 424 |         self.screen = Screen(style=style)
 425 |         self._changed = False
 426 | 
 427 |     def update(
 428 |         self, *renderables: RenderableType, style: Optional[StyleType] = None
 429 |     ) -> None:
 430 |         """Update the screen.
 431 | 
 432 |         Args:
 433 |             renderable (RenderableType, optional): Optional renderable to replace current renderable,
 434 |                 or None for no change. Defaults to None.
 435 |             style: (Style, optional): Replacement style, or None for no change. Defaults to None.
 436 |         """
 437 |         if renderables:
 438 |             self.screen.renderable = (
 439 |                 Group(*renderables) if len(renderables) > 1 else renderables[0]
 440 |             )
 441 |         if style is not None:
 442 |             self.screen.style = style
 443 |         self.console.print(self.screen, end="")
 444 | 
 445 |     def __enter__(self) -> "ScreenContext":
 446 |         self._changed = self.console.set_alt_screen(True)
 447 |         if self._changed and self.hide_cursor:
 448 |             self.console.show_cursor(False)
 449 |         return self
 450 | 
 451 |     def __exit__(
 452 |         self,
 453 |         exc_type: Optional[Type[BaseException]],
 454 |         exc_val: Optional[BaseException],
 455 |         exc_tb: Optional[TracebackType],
 456 |     ) -> None:
 457 |         if self._changed:
 458 |             self.console.set_alt_screen(False)
 459 |             if self.hide_cursor:
 460 |                 self.console.show_cursor(True)
 461 | 
 462 | 
 463 | class Group:
 464 |     """Takes a group of renderables and returns a renderable object that renders the group.
 465 | 
 466 |     Args:
 467 |         renderables (Iterable[RenderableType]): An iterable of renderable objects.
 468 |         fit (bool, optional): Fit dimension of group to contents, or fill available space. Defaults to True.
 469 |     """
 470 | 
 471 |     def __init__(self, *renderables: "RenderableType", fit: bool = True) -> None:
 472 |         self._renderables = renderables
 473 |         self.fit = fit
 474 |         self._render: Optional[List[RenderableType]] = None
 475 | 
 476 |     @property
 477 |     def renderables(self) -> List["RenderableType"]:
 478 |         if self._render is None:
 479 |             self._render = list(self._renderables)
 480 |         return self._render
 481 | 
 482 |     def __rich_measure__(
 483 |         self, console: "Console", options: "ConsoleOptions"
 484 |     ) -> "Measurement":
 485 |         if self.fit:
 486 |             return measure_renderables(console, options, self.renderables)
 487 |         else:
 488 |             return Measurement(options.max_width, options.max_width)
 489 | 
 490 |     def __rich_console__(
 491 |         self, console: "Console", options: "ConsoleOptions"
 492 |     ) -> RenderResult:
 493 |         yield from self.renderables
 494 | 
 495 | 
 496 | def group(fit: bool = True) -> Callable[..., Callable[..., Group]]:
 497 |     """A decorator that turns an iterable of renderables in to a group.
 498 | 
 499 |     Args:
 500 |         fit (bool, optional): Fit dimension of group to contents, or fill available space. Defaults to True.
 501 |     """
 502 | 
 503 |     def decorator(
 504 |         method: Callable[..., Iterable[RenderableType]]
 505 |     ) -> Callable[..., Group]:
 506 |         """Convert a method that returns an iterable of renderables in to a Group."""
 507 | 
 508 |         @wraps(method)
 509 |         def _replace(*args: Any, **kwargs: Any) -> Group:
 510 |             renderables = method(*args, **kwargs)
 511 |             return Group(*renderables, fit=fit)
 512 | 
 513 |         return _replace
 514 | 
 515 |     return decorator
 516 | 
 517 | 
 518 | def _is_jupyter() -> bool:  # pragma: no cover
 519 |     """Check if we're running in a Jupyter notebook."""
 520 |     try:
 521 |         get_ipython  # type: ignore[name-defined]
 522 |     except NameError:
 523 |         return False
 524 |     ipython = get_ipython()  # type: ignore[name-defined]
 525 |     shell = ipython.__class__.__name__
 526 |     if (
 527 |         "google.colab" in str(ipython.__class__)
 528 |         or os.getenv("DATABRICKS_RUNTIME_VERSION")
 529 |         or shell == "ZMQInteractiveShell"
 530 |     ):
 531 |         return True  # Jupyter notebook or qtconsole
 532 |     elif shell == "TerminalInteractiveShell":
 533 |         return False  # Terminal running IPython
 534 |     else:
 535 |         return False  # Other type (?)
 536 | 
 537 | 
 538 | COLOR_SYSTEMS = {
 539 |     "standard": ColorSystem.STANDARD,
 540 |     "256": ColorSystem.EIGHT_BIT,
 541 |     "truecolor": ColorSystem.TRUECOLOR,
 542 |     "windows": ColorSystem.WINDOWS,
 543 | }
 544 | 
 545 | _COLOR_SYSTEMS_NAMES = {system: name for name, system in COLOR_SYSTEMS.items()}
 546 | 
 547 | 
 548 | @dataclass
 549 | class ConsoleThreadLocals(threading.local):
 550 |     """Thread local values for Console context."""
 551 | 
 552 |     theme_stack: ThemeStack
 553 |     buffer: List[Segment] = field(default_factory=list)
 554 |     buffer_index: int = 0
 555 | 
 556 | 
 557 | class RenderHook(ABC):
 558 |     """Provides hooks in to the render process."""
 559 | 
 560 |     @abstractmethod
 561 |     def process_renderables(
 562 |         self, renderables: List[ConsoleRenderable]
 563 |     ) -> List[ConsoleRenderable]:
 564 |         """Called with a list of objects to render.
 565 | 
 566 |         This method can return a new list of renderables, or modify and return the same list.
 567 | 
 568 |         Args:
 569 |             renderables (List[ConsoleRenderable]): A number of renderable objects.
 570 | 
 571 |         Returns:
 572 |             List[ConsoleRenderable]: A replacement list of renderables.
 573 |         """
 574 | 
 575 | 
 576 | _windows_console_features: Optional["WindowsConsoleFeatures"] = None
 577 | 
 578 | 
 579 | def get_windows_console_features() -> "WindowsConsoleFeatures":  # pragma: no cover
 580 |     global _windows_console_features
 581 |     if _windows_console_features is not None:
 582 |         return _windows_console_features
 583 |     from ._windows import get_windows_console_features
 584 | 
 585 |     _windows_console_features = get_windows_console_features()
 586 |     return _windows_console_features
 587 | 
 588 | 
 589 | def detect_legacy_windows() -> bool:
 590 |     """Detect legacy Windows."""
 591 |     return WINDOWS and not get_windows_console_features().vt
 592 | 
 593 | 
 594 | class Console:
 595 |     """A high level console interface.
 596 | 
 597 |     Args:
 598 |         color_system (str, optional): The color system supported by your terminal,
 599 |             either ``"standard"``, ``"256"`` or ``"truecolor"``. Leave as ``"auto"`` to autodetect.
 600 |         force_terminal (Optional[bool], optional): Enable/disable terminal control codes, or None to auto-detect terminal. Defaults to None.
 601 |         force_jupyter (Optional[bool], optional): Enable/disable Jupyter rendering, or None to auto-detect Jupyter. Defaults to None.
 602 |         force_interactive (Optional[bool], optional): Enable/disable interactive mode, or None to auto detect. Defaults to None.
 603 |         soft_wrap (Optional[bool], optional): Set soft wrap default on print method. Defaults to False.
 604 |         theme (Theme, optional): An optional style theme object, or ``None`` for default theme.
 605 |         stderr (bool, optional): Use stderr rather than stdout if ``file`` is not specified. Defaults to False.
 606 |         file (IO, optional): A file object where the console should write to. Defaults to stdout.
 607 |         quiet (bool, Optional): Boolean to suppress all output. Defaults to False.
 608 |         width (int, optional): The width of the terminal. Leave as default to auto-detect width.
 609 |         height (int, optional): The height of the terminal. Leave as default to auto-detect height.
 610 |         style (StyleType, optional): Style to apply to all output, or None for no style. Defaults to None.
 611 |         no_color (Optional[bool], optional): Enabled no color mode, or None to auto detect. Defaults to None.
 612 |         tab_size (int, optional): Number of spaces used to replace a tab character. Defaults to 8.
 613 |         record (bool, optional): Boolean to enable recording of terminal output,
 614 |             required to call :meth:`export_html`, :meth:`export_svg`, and :meth:`export_text`. Defaults to False.
 615 |         markup (bool, optional): Boolean to enable :ref:`console_markup`. Defaults to True.
 616 |         emoji (bool, optional): Enable emoji code. Defaults to True.
 617 |         emoji_variant (str, optional): Optional emoji variant, either "text" or "emoji". Defaults to None.
 618 |         highlight (bool, optional): Enable automatic highlighting. Defaults to True.
 619 |         log_time (bool, optional): Boolean to enable logging of time by :meth:`log` methods. Defaults to True.
 620 |         log_path (bool, optional): Boolean to enable the logging of the caller by :meth:`log`. Defaults to True.
 621 |         log_time_format (Union[str, TimeFormatterCallable], optional): If ``log_time`` is enabled, either string for strftime or callable that formats the time. Defaults to "[%X] ".
 622 |         highlighter (HighlighterType, optional): Default highlighter.
 623 |         legacy_windows (bool, optional): Enable legacy Windows mode, or ``None`` to auto detect. Defaults to ``None``.
 624 |         safe_box (bool, optional): Restrict box options that don't render on legacy Windows.
 625 |         get_datetime (Callable[[], datetime], optional): Callable that gets the current time as a datetime.datetime object (used by Console.log),
 626 |             or None for datetime.now.
 627 |         get_time (Callable[[], time], optional): Callable that gets the current time in seconds, default uses time.monotonic.
 628 |     """
 629 | 
 630 |     _environ: Mapping[str, str] = os.environ
 631 | 
 632 |     def __init__(
 633 |         self,
 634 |         *,
 635 |         color_system: Optional[
 636 |             Literal["auto", "standard", "256", "truecolor", "windows"]
 637 |         ] = "auto",
 638 |         force_terminal: Optional[bool] = None,
 639 |         force_jupyter: Optional[bool] = None,
 640 |         force_interactive: Optional[bool] = None,
 641 |         soft_wrap: bool = False,
 642 |         theme: Optional[Theme] = None,
 643 |         stderr: bool = False,
 644 |         file: Optional[IO[str]] = None,
 645 |         quiet: bool = False,
 646 |         width: Optional[int] = None,
 647 |         height: Optional[int] = None,
 648 |         style: Optional[StyleType] = None,
 649 |         no_color: Optional[bool] = None,
 650 |         tab_size: int = 8,
 651 |         record: bool = False,
 652 |         markup: bool = True,
 653 |         emoji: bool = True,
 654 |         emoji_variant: Optional[EmojiVariant] = None,
 655 |         highlight: bool = True,
 656 |         log_time: bool = True,
 657 |         log_path: bool = True,
 658 |         log_time_format: Union[str, FormatTimeCallable] = "[%X]",
 659 |         highlighter: Optional["HighlighterType"] = ReprHighlighter(),
 660 |         legacy_windows: Optional[bool] = None,
 661 |         safe_box: bool = True,
 662 |         get_datetime: Optional[Callable[[], datetime]] = None,
 663 |         get_time: Optional[Callable[[], float]] = None,
 664 |         _environ: Optional[Mapping[str, str]] = None,
 665 |     ):
 666 |         # Copy of os.environ allows us to replace it for testing
 667 |         if _environ is not None:
 668 |             self._environ = _environ
 669 | 
 670 |         self.is_jupyter = _is_jupyter() if force_jupyter is None else force_jupyter
 671 |         if self.is_jupyter:
 672 |             if width is None:
 673 |                 jupyter_columns = self._environ.get("JUPYTER_COLUMNS")
 674 |                 if jupyter_columns is not None and jupyter_columns.isdigit():
 675 |                     width = int(jupyter_columns)
 676 |                 else:
 677 |                     width = JUPYTER_DEFAULT_COLUMNS
 678 |             if height is None:
 679 |                 jupyter_lines = self._environ.get("JUPYTER_LINES")
 680 |                 if jupyter_lines is not None and jupyter_lines.isdigit():
 681 |                     height = int(jupyter_lines)
 682 |                 else:
 683 |                     height = JUPYTER_DEFAULT_LINES
 684 | 
 685 |         self.tab_size = tab_size
 686 |         self.record = record
 687 |         self._markup = markup
 688 |         self._emoji = emoji
 689 |         self._emoji_variant: Optional[EmojiVariant] = emoji_variant
 690 |         self._highlight = highlight
 691 |         self.legacy_windows: bool = (
 692 |             (detect_legacy_windows() and not self.is_jupyter)
 693 |             if legacy_windows is None
 694 |             else legacy_windows
 695 |         )
 696 | 
 697 |         if width is None:
 698 |             columns = self._environ.get("COLUMNS")
 699 |             if columns is not None and columns.isdigit():
 700 |                 width = int(columns) - self.legacy_windows
 701 |         if height is None:
 702 |             lines = self._environ.get("LINES")
 703 |             if lines is not None and lines.isdigit():
 704 |                 height = int(lines)
 705 | 
 706 |         self.soft_wrap = soft_wrap
 707 |         self._width = width
 708 |         self._height = height
 709 | 
 710 |         self._color_system: Optional[ColorSystem]
 711 | 
 712 |         self._force_terminal = None
 713 |         if force_terminal is not None:
 714 |             self._force_terminal = force_terminal
 715 | 
 716 |         self._file = file
 717 |         self.quiet = quiet
 718 |         self.stderr = stderr
 719 | 
 720 |         if color_system is None:
 721 |             self._color_system = None
 722 |         elif color_system == "auto":
 723 |             self._color_system = self._detect_color_system()
 724 |         else:
 725 |             self._color_system = COLOR_SYSTEMS[color_system]
 726 | 
 727 |         self._lock = threading.RLock()
 728 |         self._log_render = LogRender(
 729 |             show_time=log_time,
 730 |             show_path=log_path,
 731 |             time_format=log_time_format,
 732 |         )
 733 |         self.highlighter: HighlighterType = highlighter or _null_highlighter
 734 |         self.safe_box = safe_box
 735 |         self.get_datetime = get_datetime or datetime.now
 736 |         self.get_time = get_time or monotonic
 737 |         self.style = style
 738 |         self.no_color = (
 739 |             no_color if no_color is not None else "NO_COLOR" in self._environ
 740 |         )
 741 |         self.is_interactive = (
 742 |             (self.is_terminal and not self.is_dumb_terminal)
 743 |             if force_interactive is None
 744 |             else force_interactive
 745 |         )
 746 | 
 747 |         self._record_buffer_lock = threading.RLock()
 748 |         self._thread_locals = ConsoleThreadLocals(
 749 |             theme_stack=ThemeStack(themes.DEFAULT if theme is None else theme)
 750 |         )
 751 |         self._record_buffer: List[Segment] = []
 752 |         self._render_hooks: List[RenderHook] = []
 753 |         self._live: Optional["Live"] = None
 754 |         self._is_alt_screen = False
 755 | 
 756 |     def __repr__(self) -> str:
 757 |         return f"<console width={self.width} {self._color_system!s}>"
 758 | 
 759 |     @property
 760 |     def file(self) -> IO[str]:
 761 |         """Get the file object to write to."""
 762 |         file = self._file or (sys.stderr if self.stderr else sys.stdout)
 763 |         file = getattr(file, "rich_proxied_file", file)
 764 |         if file is None:
 765 |             file = NULL_FILE
 766 |         return file
 767 | 
 768 |     @file.setter
 769 |     def file(self, new_file: IO[str]) -> None:
 770 |         """Set a new file object."""
 771 |         self._file = new_file
 772 | 
 773 |     @property
 774 |     def _buffer(self) -> List[Segment]:
 775 |         """Get a thread local buffer."""
 776 |         return self._thread_locals.buffer
 777 | 
 778 |     @property
 779 |     def _buffer_index(self) -> int:
 780 |         """Get a thread local buffer."""
 781 |         return self._thread_locals.buffer_index
 782 | 
 783 |     @_buffer_index.setter
 784 |     def _buffer_index(self, value: int) -> None:
 785 |         self._thread_locals.buffer_index = value
 786 | 
 787 |     @property
 788 |     def _theme_stack(self) -> ThemeStack:
 789 |         """Get the thread local theme stack."""
 790 |         return self._thread_locals.theme_stack
 791 | 
 792 |     def _detect_color_system(self) -> Optional[ColorSystem]:
 793 |         """Detect color system from env vars."""
 794 |         if self.is_jupyter:
 795 |             return ColorSystem.TRUECOLOR
 796 |         if not self.is_terminal or self.is_dumb_terminal:
 797 |             return None
 798 |         if WINDOWS:  # pragma: no cover
 799 |             if self.legacy_windows:  # pragma: no cover
 800 |                 return ColorSystem.WINDOWS
 801 |             windows_console_features = get_windows_console_features()
 802 |             return (
 803 |                 ColorSystem.TRUECOLOR
 804 |                 if windows_console_features.truecolor
 805 |                 else ColorSystem.EIGHT_BIT
 806 |             )
 807 |         else:
 808 |             color_term = self._environ.get("COLORTERM", "").strip().lower()
 809 |             if color_term in ("truecolor", "24bit"):
 810 |                 return ColorSystem.TRUECOLOR
 811 |             term = self._environ.get("TERM", "").strip().lower()
 812 |             _term_name, _hyphen, colors = term.rpartition("-")
 813 |             color_system = _TERM_COLORS.get(colors, ColorSystem.STANDARD)
 814 |             return color_system
 815 | 
 816 |     def _enter_buffer(self) -> None:
 817 |         """Enter in to a buffer context, and buffer all output."""
 818 |         self._buffer_index += 1
 819 | 
 820 |     def _exit_buffer(self) -> None:
 821 |         """Leave buffer context, and render content if required."""
 822 |         self._buffer_index -= 1
 823 |         self._check_buffer()
 824 | 
 825 |     def set_live(self, live: "Live") -> None:
 826 |         """Set Live instance. Used by Live context manager.
 827 | 
 828 |         Args:
 829 |             live (Live): Live instance using this Console.
 830 | 
 831 |         Raises:
 832 |             errors.LiveError: If this Console has a Live context currently active.
 833 |         """
 834 |         with self._lock:
 835 |             if self._live is not None:
 836 |                 raise errors.LiveError("Only one live display may be active at once")
 837 |             self._live = live
 838 | 
 839 |     def clear_live(self) -> None:
 840 |         """Clear the Live instance."""
 841 |         with self._lock:
 842 |             self._live = None
 843 | 
 844 |     def push_render_hook(self, hook: RenderHook) -> None:
 845 |         """Add a new render hook to the stack.
 846 | 
 847 |         Args:
 848 |             hook (RenderHook): Render hook instance.
 849 |         """
 850 |         with self._lock:
 851 |             self._render_hooks.append(hook)
 852 | 
 853 |     def pop_render_hook(self) -> None:
 854 |         """Pop the last renderhook from the stack."""
 855 |         with self._lock:
 856 |             self._render_hooks.pop()
 857 | 
 858 |     def __enter__(self) -> "Console":
 859 |         """Own context manager to enter buffer context."""
 860 |         self._enter_buffer()
 861 |         return self
 862 | 
 863 |     def __exit__(self, exc_type: Any, exc_value: Any, traceback: Any) -> None:
 864 |         """Exit buffer context."""
 865 |         self._exit_buffer()
 866 | 
 867 |     def begin_capture(self) -> None:
 868 |         """Begin capturing console output. Call :meth:`end_capture` to exit capture mode and return output."""
 869 |         self._enter_buffer()
 870 | 
 871 |     def end_capture(self) -> str:
 872 |         """End capture mode and return captured string.
 873 | 
 874 |         Returns:
 875 |             str: Console output.
 876 |         """
 877 |         render_result = self._render_buffer(self._buffer)
 878 |         del self._buffer[:]
 879 |         self._exit_buffer()
 880 |         return render_result
 881 | 
 882 |     def push_theme(self, theme: Theme, *, inherit: bool = True) -> None:
 883 |         """Push a new theme on to the top of the stack, replacing the styles from the previous theme.
 884 |         Generally speaking, you should call :meth:`~rich.console.Console.use_theme` to get a context manager, rather
 885 |         than calling this method directly.
 886 | 
 887 |         Args:
 888 |             theme (Theme): A theme instance.
 889 |             inherit (bool, optional): Inherit existing styles. Defaults to True.
 890 |         """
 891 |         self._theme_stack.push_theme(theme, inherit=inherit)
 892 | 
 893 |     def pop_theme(self) -> None:
 894 |         """Remove theme from top of stack, restoring previous theme."""
 895 |         self._theme_stack.pop_theme()
 896 | 
 897 |     def use_theme(self, theme: Theme, *, inherit: bool = True) -> ThemeContext:
 898 |         """Use a different theme for the duration of the context manager.
 899 | 
 900 |         Args:
 901 |             theme (Theme): Theme instance to user.
 902 |             inherit (bool, optional): Inherit existing console styles. Defaults to True.
 903 | 
 904 |         Returns:
 905 |             ThemeContext: [description]
 906 |         """
 907 |         return ThemeContext(self, theme, inherit)
 908 | 
 909 |     @property
 910 |     def color_system(self) -> Optional[str]:
 911 |         """Get color system string.
 912 | 
 913 |         Returns:
 914 |             Optional[str]: "standard", "256" or "truecolor".
 915 |         """
 916 | 
 917 |         if self._color_system is not None:
 918 |             return _COLOR_SYSTEMS_NAMES[self._color_system]
 919 |         else:
 920 |             return None
 921 | 
 922 |     @property
 923 |     def encoding(self) -> str:
 924 |         """Get the encoding of the console file, e.g. ``"utf-8"``.
 925 | 
 926 |         Returns:
 927 |             str: A standard encoding string.
 928 |         """
 929 |         return (getattr(self.file, "encoding", "utf-8") or "utf-8").lower()
 930 | 
 931 |     @property
 932 |     def is_terminal(self) -> bool:
 933 |         """Check if the console is writing to a terminal.
 934 | 
 935 |         Returns:
 936 |             bool: True if the console writing to a device capable of
 937 |             understanding terminal codes, otherwise False.
 938 |         """
 939 |         if self._force_terminal is not None:
 940 |             return self._force_terminal
 941 | 
 942 |         if hasattr(sys.stdin, "__module__") and sys.stdin.__module__.startswith(
 943 |             "idlelib"
 944 |         ):
 945 |             # Return False for Idle which claims to be a tty but can't handle ansi codes
 946 |             return False
 947 | 
 948 |         if self.is_jupyter:
 949 |             # return False for Jupyter, which may have FORCE_COLOR set
 950 |             return False
 951 | 
 952 |         # If FORCE_COLOR env var has any value at all, we assume a terminal.
 953 |         force_color = self._environ.get("FORCE_COLOR")
 954 |         if force_color is not None:
 955 |             self._force_terminal = True
 956 |             return True
 957 | 
 958 |         isatty: Optional[Callable[[], bool]] = getattr(self.file, "isatty", None)
 959 |         try:
 960 |             return False if isatty is None else isatty()
 961 |         except ValueError:
 962 |             # in some situation (at the end of a pytest run for example) isatty() can raise
 963 |             # ValueError: I/O operation on closed file
 964 |             # return False because we aren't in a terminal anymore
 965 |             return False
 966 | 
 967 |     @property
 968 |     def is_dumb_terminal(self) -> bool:
 969 |         """Detect dumb terminal.
 970 | 
 971 |         Returns:
 972 |             bool: True if writing to a dumb terminal, otherwise False.
 973 | 
 974 |         """
 975 |         _term = self._environ.get("TERM", "")
 976 |         is_dumb = _term.lower() in ("dumb", "unknown")
 977 |         return self.is_terminal and is_dumb
 978 | 
 979 |     @property
 980 |     def options(self) -> ConsoleOptions:
 981 |         """Get default console options."""
 982 |         return ConsoleOptions(
 983 |             max_height=self.size.height,
 984 |             size=self.size,
 985 |             legacy_windows=self.legacy_windows,
 986 |             min_width=1,
 987 |             max_width=self.width,
 988 |             encoding=self.encoding,
 989 |             is_terminal=self.is_terminal,
 990 |         )
 991 | 
 992 |     @property
 993 |     def size(self) -> ConsoleDimensions:
 994 |         """Get the size of the console.
 995 | 
 996 |         Returns:
 997 |             ConsoleDimensions: A named tuple containing the dimensions.
 998 |         """
 999 | 
1000 |         if self._width is not None and self._height is not None:
1001 |             return ConsoleDimensions(self._width - self.legacy_windows, self._height)
1002 | 
1003 |         if self.is_dumb_terminal:
1004 |             return ConsoleDimensions(80, 25)
1005 | 
1006 |         width: Optional[int] = None
1007 |         height: Optional[int] = None
1008 | 
1009 |         if WINDOWS:  # pragma: no cover
1010 |             try:
1011 |                 width, height = os.get_terminal_size()
1012 |             except (AttributeError, ValueError, OSError):  # Probably not a terminal
1013 |                 pass
1014 |         else:
1015 |             for file_descriptor in _STD_STREAMS:
1016 |                 try:
1017 |                     width, height = os.get_terminal_size(file_descriptor)
1018 |                 except (AttributeError, ValueError, OSError):
1019 |                     pass
1020 |                 else:
1021 |                     break
1022 | 
1023 |         columns = self._environ.get("COLUMNS")
1024 |         if columns is not None and columns.isdigit():
1025 |             width = int(columns)
1026 |         lines = self._environ.get("LINES")
1027 |         if lines is not None and lines.isdigit():
1028 |             height = int(lines)
1029 | 
1030 |         # get_terminal_size can report 0, 0 if run from pseudo-terminal
1031 |         width = width or 80
1032 |         height = height or 25
1033 |         return ConsoleDimensions(
1034 |             width - self.legacy_windows if self._width is None else self._width,
1035 |             height if self._height is None else self._height,
1036 |         )
1037 | 
1038 |     @size.setter
1039 |     def size(self, new_size: Tuple[int, int]) -> None:
1040 |         """Set a new size for the terminal.
1041 | 
1042 |         Args:
1043 |             new_size (Tuple[int, int]): New width and height.
1044 |         """
1045 |         width, height = new_size
1046 |         self._width = width
1047 |         self._height = height
1048 | 
1049 |     @property
1050 |     def width(self) -> int:
1051 |         """Get the width of the console.
1052 | 
1053 |         Returns:
1054 |             int: The width (in characters) of the console.
1055 |         """
1056 |         return self.size.width
1057 | 
1058 |     @width.setter
1059 |     def width(self, width: int) -> None:
1060 |         """Set width.
1061 | 
1062 |         Args:
1063 |             width (int): New width.
1064 |         """
1065 |         self._width = width
1066 | 
1067 |     @property
1068 |     def height(self) -> int:
1069 |         """Get the height of the console.
1070 | 
1071 |         Returns:
1072 |             int: The height (in lines) of the console.
1073 |         """
1074 |         return self.size.height
1075 | 
1076 |     @height.setter
1077 |     def height(self, height: int) -> None:
1078 |         """Set height.
1079 | 
1080 |         Args:
1081 |             height (int): new height.
1082 |         """
1083 |         self._height = height
1084 | 
1085 |     def bell(self) -> None:
1086 |         """Play a 'bell' sound (if supported by the terminal)."""
1087 |         self.control(Control.bell())
1088 | 
1089 |     def capture(self) -> Capture:
1090 |         """A context manager to *capture* the result of print() or log() in a string,
1091 |         rather than writing it to the console.
1092 | 
1093 |         Example:
1094 |             >>> from rich.console import Console
1095 |             >>> console = Console()
1096 |             >>> with console.capture() as capture:
1097 |             ...     console.print("[bold magenta]Hello World[/]")
1098 |             >>> print(capture.get())
1099 | 
1100 |         Returns:
1101 |             Capture: Context manager with disables writing to the terminal.
1102 |         """
1103 |         capture = Capture(self)
1104 |         return capture
1105 | 
1106 |     def pager(
1107 |         self, pager: Optional[Pager] = None, styles: bool = False, links: bool = False
1108 |     ) -> PagerContext:
1109 |         """A context manager to display anything printed within a "pager". The pager application
1110 |         is defined by the system and will typically support at least pressing a key to scroll.
1111 | 
1112 |         Args:
1113 |             pager (Pager, optional): A pager object, or None to use :class:`~rich.pager.SystemPager`. Defaults to None.
1114 |             styles (bool, optional): Show styles in pager. Defaults to False.
1115 |             links (bool, optional): Show links in pager. Defaults to False.
1116 | 
1117 |         Example:
1118 |             >>> from rich.console import Console
1119 |             >>> from rich.__main__ import make_test_card
1120 |             >>> console = Console()
1121 |             >>> with console.pager():
1122 |                     console.print(make_test_card())
1123 | 
1124 |         Returns:
1125 |             PagerContext: A context manager.
1126 |         """
1127 |         return PagerContext(self, pager=pager, styles=styles, links=links)
1128 | 
1129 |     def line(self, count: int = 1) -> None:
1130 |         """Write new line(s).
1131 | 
1132 |         Args:
1133 |             count (int, optional): Number of new lines. Defaults to 1.
1134 |         """
1135 | 
1136 |         assert count >= 0, "count must be >= 0"
1137 |         self.print(NewLine(count))
1138 | 
1139 |     def clear(self, home: bool = True) -> None:
1140 |         """Clear the screen.
1141 | 
1142 |         Args:
1143 |             home (bool, optional): Also move the cursor to 'home' position. Defaults to True.
1144 |         """
1145 |         if home:
1146 |             self.control(Control.clear(), Control.home())
1147 |         else:
1148 |             self.control(Control.clear())
1149 | 
1150 |     def status(
1151 |         self,
1152 |         status: RenderableType,
1153 |         *,
1154 |         spinner: str = "dots",
1155 |         spinner_style: StyleType = "status.spinner",
1156 |         speed: float = 1.0,
1157 |         refresh_per_second: float = 12.5,
1158 |     ) -> "Status":
1159 |         """Display a status and spinner.
1160 | 
1161 |         Args:
1162 |             status (RenderableType): A status renderable (str or Text typically).
1163 |             spinner (str, optional): Name of spinner animation (see python -m rich.spinner). Defaults to "dots".
1164 |             spinner_style (StyleType, optional): Style of spinner. Defaults to "status.spinner".
1165 |             speed (float, optional): Speed factor for spinner animation. Defaults to 1.0.
1166 |             refresh_per_second (float, optional): Number of refreshes per second. Defaults to 12.5.
1167 | 
1168 |         Returns:
1169 |             Status: A Status object that may be used as a context manager.
1170 |         """
1171 |         from .status import Status
1172 | 
1173 |         status_renderable = Status(
1174 |             status,
1175 |             console=self,
1176 |             spinner=spinner,
1177 |             spinner_style=spinner_style,
1178 |             speed=speed,
1179 |             refresh_per_second=refresh_per_second,
1180 |         )
1181 |         return status_renderable
1182 | 
1183 |     def show_cursor(self, show: bool = True) -> bool:
1184 |         """Show or hide the cursor.
1185 | 
1186 |         Args:
1187 |             show (bool, optional): Set visibility of the cursor.
1188 |         """
1189 |         if self.is_terminal:
1190 |             self.control(Control.show_cursor(show))
1191 |             return True
1192 |         return False
1193 | 
1194 |     def set_alt_screen(self, enable: bool = True) -> bool:
1195 |         """Enables alternative screen mode.
1196 | 
1197 |         Note, if you enable this mode, you should ensure that is disabled before
1198 |         the application exits. See :meth:`~rich.Console.screen` for a context manager
1199 |         that handles this for you.
1200 | 
1201 |         Args:
1202 |             enable (bool, optional): Enable (True) or disable (False) alternate screen. Defaults to True.
1203 | 
1204 |         Returns:
1205 |             bool: True if the control codes were written.
1206 | 
1207 |         """
1208 |         changed = False
1209 |         if self.is_terminal and not self.legacy_windows:
1210 |             self.control(Control.alt_screen(enable))
1211 |             changed = True
1212 |             self._is_alt_screen = enable
1213 |         return changed
1214 | 
1215 |     @property
1216 |     def is_alt_screen(self) -> bool:
1217 |         """Check if the alt screen was enabled.
1218 | 
1219 |         Returns:
1220 |             bool: True if the alt screen was enabled, otherwise False.
1221 |         """
1222 |         return self._is_alt_screen
1223 | 
1224 |     def set_window_title(self, title: str) -> bool:
1225 |         """Set the title of the console terminal window.
1226 | 
1227 |         Warning: There is no means within Rich of "resetting" the window title to its
1228 |         previous value, meaning the title you set will persist even after your application
1229 |         exits.
1230 | 
1231 |         ``fish`` shell resets the window title before and after each command by default,
1232 |         negating this issue. Windows Terminal and command prompt will also reset the title for you.
1233 |         Most other shells and terminals, however, do not do this.
1234 | 
1235 |         Some terminals may require configuration changes before you can set the title.
1236 |         Some terminals may not support setting the title at all.
1237 | 
1238 |         Other software (including the terminal itself, the shell, custom prompts, plugins, etc.)
1239 |         may also set the terminal window title. This could result in whatever value you write
1240 |         using this method being overwritten.
1241 | 
1242 |         Args:
1243 |             title (str): The new title of the terminal window.
1244 | 
1245 |         Returns:
1246 |             bool: True if the control code to change the terminal title was
1247 |                 written, otherwise False. Note that a return value of True
1248 |                 does not guarantee that the window title has actually changed,
1249 |                 since the feature may be unsupported/disabled in some terminals.
1250 |         """
1251 |         if self.is_terminal:
1252 |             self.control(Control.title(title))
1253 |             return True
1254 |         return False
1255 | 
1256 |     def screen(
1257 |         self, hide_cursor: bool = True, style: Optional[StyleType] = None
1258 |     ) -> "ScreenContext":
1259 |         """Context manager to enable and disable 'alternative screen' mode.
1260 | 
1261 |         Args:
1262 |             hide_cursor (bool, optional): Also hide the cursor. Defaults to False.
1263 |             style (Style, optional): Optional style for screen. Defaults to None.
1264 | 
1265 |         Returns:
1266 |             ~ScreenContext: Context which enables alternate screen on enter, and disables it on exit.
1267 |         """
1268 |         return ScreenContext(self, hide_cursor=hide_cursor, style=style or "")
1269 | 
1270 |     def measure(
1271 |         self, renderable: RenderableType, *, options: Optional[ConsoleOptions] = None
1272 |     ) -> Measurement:
1273 |         """Measure a renderable. Returns a :class:`~rich.measure.Measurement` object which contains
1274 |         information regarding the number of characters required to print the renderable.
1275 | 
1276 |         Args:
1277 |             renderable (RenderableType): Any renderable or string.
1278 |             options (Optional[ConsoleOptions], optional): Options to use when measuring, or None
1279 |                 to use default options. Defaults to None.
1280 | 
1281 |         Returns:
1282 |             Measurement: A measurement of the renderable.
1283 |         """
1284 |         measurement = Measurement.get(self, options or self.options, renderable)
1285 |         return measurement
1286 | 
1287 |     def render(
1288 |         self, renderable: RenderableType, options: Optional[ConsoleOptions] = None
1289 |     ) -> Iterable[Segment]:
1290 |         """Render an object in to an iterable of `Segment` instances.
1291 | 
1292 |         This method contains the logic for rendering objects with the console protocol.
1293 |         You are unlikely to need to use it directly, unless you are extending the library.
1294 | 
1295 |         Args:
1296 |             renderable (RenderableType): An object supporting the console protocol, or
1297 |                 an object that may be converted to a string.
1298 |             options (ConsoleOptions, optional): An options object, or None to use self.options. Defaults to None.
1299 | 
1300 |         Returns:
1301 |             Iterable[Segment]: An iterable of segments that may be rendered.
1302 |         """
1303 | 
1304 |         _options = options or self.options
1305 |         if _options.max_width < 1:
1306 |             # No space to render anything. This prevents potential recursion errors.
1307 |             return
1308 |         render_iterable: RenderResult
1309 | 
1310 |         renderable = rich_cast(renderable)
1311 |         if hasattr(renderable, "__rich_console__") and not isclass(renderable):
1312 |             render_iterable = renderable.__rich_console__(self, _options)  # type: ignore[union-attr]
1313 |         elif isinstance(renderable, str):
1314 |             text_renderable = self.render_str(
1315 |                 renderable, highlight=_options.highlight, markup=_options.markup
1316 |             )
1317 |             render_iterable = text_renderable.__rich_console__(self, _options)
1318 |         else:
1319 |             raise errors.NotRenderableError(
1320 |                 f"Unable to render {renderable!r}; "
1321 |                 "A str, Segment or object with __rich_console__ method is required"
1322 |             )
1323 | 
1324 |         try:
1325 |             iter_render = iter(render_iterable)
1326 |         except TypeError:
1327 |             raise errors.NotRenderableError(
1328 |                 f"object {render_iterable!r} is not renderable"
1329 |             )
1330 |         _Segment = Segment
1331 |         _options = _options.reset_height()
1332 |         for render_output in iter_render:
1333 |             if isinstance(render_output, _Segment):
1334 |                 yield render_output
1335 |             else:
1336 |                 yield from self.render(render_output, _options)
1337 | 
1338 |     def render_lines(
1339 |         self,
1340 |         renderable: RenderableType,
1341 |         options: Optional[ConsoleOptions] = None,
1342 |         *,
1343 |         style: Optional[Style] = None,
1344 |         pad: bool = True,
1345 |         new_lines: bool = False,
1346 |     ) -> List[List[Segment]]:
1347 |         """Render objects in to a list of lines.
1348 | 
1349 |         The output of render_lines is useful when further formatting of rendered console text
1350 |         is required, such as the Panel class which draws a border around any renderable object.
1351 | 
1352 |         Args:
1353 |             renderable (RenderableType): Any object renderable in the console.
1354 |             options (Optional[ConsoleOptions], optional): Console options, or None to use self.options. Default to ``None``.
1355 |             style (Style, optional): Optional style to apply to renderables. Defaults to ``None``.
1356 |             pad (bool, optional): Pad lines shorter than render width. Defaults to ``True``.
1357 |             new_lines (bool, optional): Include "\n" characters at end of lines.
1358 | 
1359 |         Returns:
1360 |             List[List[Segment]]: A list of lines, where a line is a list of Segment objects.
1361 |         """
1362 |         with self._lock:
1363 |             render_options = options or self.options
1364 |             _rendered = self.render(renderable, render_options)
1365 |             if style:
1366 |                 _rendered = Segment.apply_style(_rendered, style)
1367 | 
1368 |             render_height = render_options.height
1369 |             if render_height is not None:
1370 |                 render_height = max(0, render_height)
1371 | 
1372 |             lines = list(
1373 |                 islice(
1374 |                     Segment.split_and_crop_lines(
1375 |                         _rendered,
1376 |                         render_options.max_width,
1377 |                         include_new_lines=new_lines,
1378 |                         pad=pad,
1379 |                         style=style,
1380 |                     ),
1381 |                     None,
1382 |                     render_height,
1383 |                 )
1384 |             )
1385 |             if render_options.height is not None:
1386 |                 extra_lines = render_options.height - len(lines)
1387 |                 if extra_lines > 0:
1388 |                     pad_line = [
1389 |                         [Segment(" " * render_options.max_width, style), Segment("\n")]
1390 |                         if new_lines
1391 |                         else [Segment(" " * render_options.max_width, style)]
1392 |                     ]
1393 |                     lines.extend(pad_line * extra_lines)
1394 | 
1395 |             return lines
1396 | 
1397 |     def render_str(
1398 |         self,
1399 |         text: str,
1400 |         *,
1401 |         style: Union[str, Style] = "",
1402 |         justify: Optional[JustifyMethod] = None,
1403 |         overflow: Optional[OverflowMethod] = None,
1404 |         emoji: Optional[bool] = None,
1405 |         markup: Optional[bool] = None,
1406 |         highlight: Optional[bool] = None,
1407 |         highlighter: Optional[HighlighterType] = None,
1408 |     ) -> "Text":
1409 |         """Convert a string to a Text instance. This is called automatically if
1410 |         you print or log a string.
1411 | 
1412 |         Args:
1413 |             text (str): Text to render.
1414 |             style (Union[str, Style], optional): Style to apply to rendered text.
1415 |             justify (str, optional): Justify method: "default", "left", "center", "full", or "right". Defaults to ``None``.
1416 |             overflow (str, optional): Overflow method: "crop", "fold", or "ellipsis". Defaults to ``None``.
1417 |             emoji (Optional[bool], optional): Enable emoji, or ``None`` to use Console default.
1418 |             markup (Optional[bool], optional): Enable markup, or ``None`` to use Console default.
1419 |             highlight (Optional[bool], optional): Enable highlighting, or ``None`` to use Console default.
1420 |             highlighter (HighlighterType, optional): Optional highlighter to apply.
1421 |         Returns:
1422 |             ConsoleRenderable: Renderable object.
1423 | 
1424 |         """
1425 |         emoji_enabled = emoji or (emoji is None and self._emoji)
1426 |         markup_enabled = markup or (markup is None and self._markup)
1427 |         highlight_enabled = highlight or (highlight is None and self._highlight)
1428 | 
1429 |         if markup_enabled:
1430 |             rich_text = render_markup(
1431 |                 text,
1432 |                 style=style,
1433 |                 emoji=emoji_enabled,
1434 |                 emoji_variant=self._emoji_variant,
1435 |             )
1436 |             rich_text.justify = justify
1437 |             rich_text.overflow = overflow
1438 |         else:
1439 |             rich_text = Text(
1440 |                 _emoji_replace(text, default_variant=self._emoji_variant)
1441 |                 if emoji_enabled
1442 |                 else text,
1443 |                 justify=justify,
1444 |                 overflow=overflow,
1445 |                 style=style,
1446 |             )
1447 | 
1448 |         _highlighter = (highlighter or self.highlighter) if highlight_enabled else None
1449 |         if _highlighter is not None:
1450 |             highlight_text = _highlighter(str(rich_text))
1451 |             highlight_text.copy_styles(rich_text)
1452 |             return highlight_text
1453 | 
1454 |         return rich_text
1455 | 
1456 |     def get_style(
1457 |         self, name: Union[str, Style], *, default: Optional[Union[Style, str]] = None
1458 |     ) -> Style:
1459 |         """Get a Style instance by its theme name or parse a definition.
1460 | 
1461 |         Args:
1462 |             name (str): The name of a style or a style definition.
1463 | 
1464 |         Returns:
1465 |             Style: A Style object.
1466 | 
1467 |         Raises:
1468 |             MissingStyle: If no style could be parsed from name.
1469 | 
1470 |         """
1471 |         if isinstance(name, Style):
1472 |             return name
1473 | 
1474 |         try:
1475 |             style = self._theme_stack.get(name)
1476 |             if style is None:
1477 |                 style = Style.parse(name)
1478 |             return style.copy() if style.link else style
1479 |         except errors.StyleSyntaxError as error:
1480 |             if default is not None:
1481 |                 return self.get_style(default)
1482 |             raise errors.MissingStyle(
1483 |                 f"Failed to get style {name!r}; {error}"
1484 |             ) from None
1485 | 
1486 |     def _collect_renderables(
1487 |         self,
1488 |         objects: Iterable[Any],
1489 |         sep: str,
1490 |         end: str,
1491 |         *,
1492 |         justify: Optional[JustifyMethod] = None,
1493 |         emoji: Optional[bool] = None,
1494 |         markup: Optional[bool] = None,
1495 |         highlight: Optional[bool] = None,
1496 |     ) -> List[ConsoleRenderable]:
1497 |         """Combine a number of renderables and text into one renderable.
1498 | 
1499 |         Args:
1500 |             objects (Iterable[Any]): Anything that Rich can render.
1501 |             sep (str): String to write between print data.
1502 |             end (str): String to write at end of print data.
1503 |             justify (str, optional): One of "left", "right", "center", or "full". Defaults to ``None``.
1504 |             emoji (Optional[bool], optional): Enable emoji code, or ``None`` to use console default.
1505 |             markup (Optional[bool], optional): Enable markup, or ``None`` to use console default.
1506 |             highlight (Optional[bool], optional): Enable automatic highlighting, or ``None`` to use console default.
1507 | 
1508 |         Returns:
1509 |             List[ConsoleRenderable]: A list of things to render.
1510 |         """
1511 |         renderables: List[ConsoleRenderable] = []
1512 |         _append = renderables.append
1513 |         text: List[Text] = []
1514 |         append_text = text.append
1515 | 
1516 |         append = _append
1517 |         if justify in ("left", "center", "right"):
1518 | 
1519 |             def align_append(renderable: RenderableType) -> None:
1520 |                 _append(Align(renderable, cast(AlignMethod, justify)))
1521 | 
1522 |             append = align_append
1523 | 
1524 |         _highlighter: HighlighterType = _null_highlighter
1525 |         if highlight or (highlight is None and self._highlight):
1526 |             _highlighter = self.highlighter
1527 | 
1528 |         def check_text() -> None:
1529 |             if text:
1530 |                 sep_text = Text(sep, justify=justify, end=end)
1531 |                 append(sep_text.join(text))
1532 |                 text.clear()
1533 | 
1534 |         for renderable in objects:
1535 |             renderable = rich_cast(renderable)
1536 |             if isinstance(renderable, str):
1537 |                 append_text(
1538 |                     self.render_str(
1539 |                         renderable, emoji=emoji, markup=markup, highlighter=_highlighter
1540 |                     )
1541 |                 )
1542 |             elif isinstance(renderable, Text):
1543 |                 append_text(renderable)
1544 |             elif isinstance(renderable, ConsoleRenderable):
1545 |                 check_text()
1546 |                 append(renderable)
1547 |             elif is_expandable(renderable):
1548 |                 check_text()
1549 |                 append(Pretty(renderable, highlighter=_highlighter))
1550 |             else:
1551 |                 append_text(_highlighter(str(renderable)))
1552 | 
1553 |         check_text()
1554 | 
1555 |         if self.style is not None:
1556 |             style = self.get_style(self.style)
1557 |             renderables = [Styled(renderable, style) for renderable in renderables]
1558 | 
1559 |         return renderables
1560 | 
1561 |     def rule(
1562 |         self,
1563 |         title: TextType = "",
1564 |         *,
1565 |         characters: str = "─",
1566 |         style: Union[str, Style] = "rule.line",
1567 |         align: AlignMethod = "center",
1568 |     ) -> None:
1569 |         """Draw a line with optional centered title.
1570 | 
1571 |         Args:
1572 |             title (str, optional): Text to render over the rule. Defaults to "".
1573 |             characters (str, optional): Character(s) to form the line. Defaults to "─".
1574 |             style (str, optional): Style of line. Defaults to "rule.line".
1575 |             align (str, optional): How to align the title, one of "left", "center", or "right". Defaults to "center".
1576 |         """
1577 |         from .rule import Rule
1578 | 
1579 |         rule = Rule(title=title, characters=characters, style=style, align=align)
1580 |         self.print(rule)
1581 | 
1582 |     def control(self, *control: Control) -> None:
1583 |         """Insert non-printing control codes.
1584 | 
1585 |         Args:
1586 |             control_codes (str): Control codes, such as those that may move the cursor.
1587 |         """
1588 |         if not self.is_dumb_terminal:
1589 |             with self:
1590 |                 self._buffer.extend(_control.segment for _control in control)
1591 | 
1592 |     def out(
1593 |         self,
1594 |         *objects: Any,
1595 |         sep: str = " ",
1596 |         end: str = "\n",
1597 |         style: Optional[Union[str, Style]] = None,
1598 |         highlight: Optional[bool] = None,
1599 |     ) -> None:
1600 |         """Output to the terminal. This is a low-level way of writing to the terminal which unlike
1601 |         :meth:`~rich.console.Console.print` won't pretty print, wrap text, or apply markup, but will
1602 |         optionally apply highlighting and a basic style.
1603 | 
1604 |         Args:
1605 |             sep (str, optional): String to write between print data. Defaults to " ".
1606 |             end (str, optional): String to write at end of print data. Defaults to "\\\\n".
1607 |             style (Union[str, Style], optional): A style to apply to output. Defaults to None.
1608 |             highlight (Optional[bool], optional): Enable automatic highlighting, or ``None`` to use
1609 |                 console default. Defaults to ``None``.
1610 |         """
1611 |         raw_output: str = sep.join(str(_object) for _object in objects)
1612 |         self.print(
1613 |             raw_output,
1614 |             style=style,
1615 |             highlight=highlight,
1616 |             emoji=False,
1617 |             markup=False,
1618 |             no_wrap=True,
1619 |             overflow="ignore",
1620 |             crop=False,
1621 |             end=end,
1622 |         )
1623 | 
1624 |     def print(
1625 |         self,
1626 |         *objects: Any,
1627 |         sep: str = " ",
1628 |         end: str = "\n",
1629 |         style: Optional[Union[str, Style]] = None,
1630 |         justify: Optional[JustifyMethod] = None,
1631 |         overflow: Optional[OverflowMethod] = None,
1632 |         no_wrap: Optional[bool] = None,
1633 |         emoji: Optional[bool] = None,
1634 |         markup: Optional[bool] = None,
1635 |         highlight: Optional[bool] = None,
1636 |         width: Optional[int] = None,
1637 |         height: Optional[int] = None,
1638 |         crop: bool = True,
1639 |         soft_wrap: Optional[bool] = None,
1640 |         new_line_start: bool = False,
1641 |     ) -> None:
1642 |         """Print to the console.
1643 | 
1644 |         Args:
1645 |             objects (positional args): Objects to log to the terminal.
1646 |             sep (str, optional): String to write between print data. Defaults to " ".
1647 |             end (str, optional): String to write at end of print data. Defaults to "\\\\n".
1648 |             style (Union[str, Style], optional): A style to apply to output. Defaults to None.
1649 |             justify (str, optional): Justify method: "default", "left", "right", "center", or "full". Defaults to ``None``.
1650 |             overflow (str, optional): Overflow method: "ignore", "crop", "fold", or "ellipsis". Defaults to None.
1651 |             no_wrap (Optional[bool], optional): Disable word wrapping. Defaults to None.
1652 |             emoji (Optional[bool], optional): Enable emoji code, or ``None`` to use console default. Defaults to ``None``.
1653 |             markup (Optional[bool], optional): Enable markup, or ``None`` to use console default. Defaults to ``None``.
1654 |             highlight (Optional[bool], optional): Enable automatic highlighting, or ``None`` to use console default. Defaults to ``None``.
1655 |             width (Optional[int], optional): Width of output, or ``None`` to auto-detect. Defaults to ``None``.
1656 |             crop (Optional[bool], optional): Crop output to width of terminal. Defaults to True.
1657 |             soft_wrap (bool, optional): Enable soft wrap mode which disables word wrapping and cropping of text or ``None`` for
1658 |                 Console default. Defaults to ``None``.
1659 |             new_line_start (bool, False): Insert a new line at the start if the output contains more than one line. Defaults to ``False``.
1660 |         """
1661 |         if not objects:
1662 |             objects = (NewLine(),)
1663 | 
1664 |         if soft_wrap is None:
1665 |             soft_wrap = self.soft_wrap
1666 |         if soft_wrap:
1667 |             if no_wrap is None:
1668 |                 no_wrap = True
1669 |             if overflow is None:
1670 |                 overflow = "ignore"
1671 |             crop = False
1672 |         render_hooks = self._render_hooks[:]
1673 |         with self:
1674 |             renderables = self._collect_renderables(
1675 |                 objects,
1676 |                 sep,
1677 |                 end,
1678 |                 justify=justify,
1679 |                 emoji=emoji,
1680 |                 markup=markup,
1681 |                 highlight=highlight,
1682 |             )
1683 |             for hook in render_hooks:
1684 |                 renderables = hook.process_renderables(renderables)
1685 |             render_options = self.options.update(
1686 |                 justify=justify,
1687 |                 overflow=overflow,
1688 |                 width=min(width, self.width) if width is not None else NO_CHANGE,
1689 |                 height=height,
1690 |                 no_wrap=no_wrap,
1691 |                 markup=markup,
1692 |                 highlight=highlight,
1693 |             )
1694 | 
1695 |             new_segments: List[Segment] = []
1696 |             extend = new_segments.extend
1697 |             render = self.render
1698 |             if style is None:
1699 |                 for renderable in renderables:
1700 |                     extend(render(renderable, render_options))
1701 |             else:
1702 |                 for renderable in renderables:
1703 |                     extend(
1704 |                         Segment.apply_style(
1705 |                             render(renderable, render_options), self.get_style(style)
1706 |                         )
1707 |                     )
1708 |             if new_line_start:
1709 |                 if (
1710 |                     len("".join(segment.text for segment in new_segments).splitlines())
1711 |                     > 1
1712 |                 ):
1713 |                     new_segments.insert(0, Segment.line())
1714 |             if crop:
1715 |                 buffer_extend = self._buffer.extend
1716 |                 for line in Segment.split_and_crop_lines(
1717 |                     new_segments, self.width, pad=False
1718 |                 ):
1719 |                     buffer_extend(line)
1720 |             else:
1721 |                 self._buffer.extend(new_segments)
1722 | 
1723 |     def print_json(
1724 |         self,
1725 |         json: Optional[str] = None,
1726 |         *,
1727 |         data: Any = None,
1728 |         indent: Union[None, int, str] = 2,
1729 |         highlight: bool = True,
1730 |         skip_keys: bool = False,
1731 |         ensure_ascii: bool = False,
1732 |         check_circular: bool = True,
1733 |         allow_nan: bool = True,
1734 |         default: Optional[Callable[[Any], Any]] = None,
1735 |         sort_keys: bool = False,
1736 |     ) -> None:
1737 |         """Pretty prints JSON. Output will be valid JSON.
1738 | 
1739 |         Args:
1740 |             json (Optional[str]): A string containing JSON.
1741 |             data (Any): If json is not supplied, then encode this data.
1742 |             indent (Union[None, int, str], optional): Number of spaces to indent. Defaults to 2.
1743 |             highlight (bool, optional): Enable highlighting of output: Defaults to True.
1744 |             skip_keys (bool, optional): Skip keys not of a basic type. Defaults to False.
1745 |             ensure_ascii (bool, optional): Escape all non-ascii characters. Defaults to False.
1746 |             check_circular (bool, optional): Check for circular references. Defaults to True.
1747 |             allow_nan (bool, optional): Allow NaN and Infinity values. Defaults to True.
1748 |             default (Callable, optional): A callable that converts values that can not be encoded
1749 |                 in to something that can be JSON encoded. Defaults to None.
1750 |             sort_keys (bool, optional): Sort dictionary keys. Defaults to False.
1751 |         """
1752 |         from pip._vendor.rich.json import JSON
1753 | 
1754 |         if json is None:
1755 |             json_renderable = JSON.from_data(
1756 |                 data,
1757 |                 indent=indent,
1758 |                 highlight=highlight,
1759 |                 skip_keys=skip_keys,
1760 |                 ensure_ascii=ensure_ascii,
1761 |                 check_circular=check_circular,
1762 |                 allow_nan=allow_nan,
1763 |                 default=default,
1764 |                 sort_keys=sort_keys,
1765 |             )
1766 |         else:
1767 |             if not isinstance(json, str):
1768 |                 raise TypeError(
1769 |                     f"json must be str. Did you mean print_json(data={json!r}) ?"
1770 |                 )
1771 |             json_renderable = JSON(
1772 |                 json,
1773 |                 indent=indent,
1774 |                 highlight=highlight,
1775 |                 skip_keys=skip_keys,
1776 |                 ensure_ascii=ensure_ascii,
1777 |                 check_circular=check_circular,
1778 |                 allow_nan=allow_nan,
1779 |                 default=default,
1780 |                 sort_keys=sort_keys,
1781 |             )
1782 |         self.print(json_renderable, soft_wrap=True)
1783 | 
1784 |     def update_screen(
1785 |         self,
1786 |         renderable: RenderableType,
1787 |         *,
1788 |         region: Optional[Region] = None,
1789 |         options: Optional[ConsoleOptions] = None,
1790 |     ) -> None:
1791 |         """Update the screen at a given offset.
1792 | 
1793 |         Args:
1794 |             renderable (RenderableType): A Rich renderable.
1795 |             region (Region, optional): Region of screen to update, or None for entire screen. Defaults to None.
1796 |             x (int, optional): x offset. Defaults to 0.
1797 |             y (int, optional): y offset. Defaults to 0.
1798 | 
1799 |         Raises:
1800 |             errors.NoAltScreen: If the Console isn't in alt screen mode.
1801 | 
1802 |         """
1803 |         if not self.is_alt_screen:
1804 |             raise errors.NoAltScreen("Alt screen must be enabled to call update_screen")
1805 |         render_options = options or self.options
1806 |         if region is None:
1807 |             x = y = 0
1808 |             render_options = render_options.update_dimensions(
1809 |                 render_options.max_width, render_options.height or self.height
1810 |             )
1811 |         else:
1812 |             x, y, width, height = region
1813 |             render_options = render_options.update_dimensions(width, height)
1814 | 
1815 |         lines = self.render_lines(renderable, options=render_options)
1816 |         self.update_screen_lines(lines, x, y)
1817 | 
1818 |     def update_screen_lines(
1819 |         self, lines: List[List[Segment]], x: int = 0, y: int = 0
1820 |     ) -> None:
1821 |         """Update lines of the screen at a given offset.
1822 | 
1823 |         Args:
1824 |             lines (List[List[Segment]]): Rendered lines (as produced by :meth:`~rich.Console.render_lines`).
1825 |             x (int, optional): x offset (column no). Defaults to 0.
1826 |             y (int, optional): y offset (column no). Defaults to 0.
1827 | 
1828 |         Raises:
1829 |             errors.NoAltScreen: If the Console isn't in alt screen mode.
1830 |         """
1831 |         if not self.is_alt_screen:
1832 |             raise errors.NoAltScreen("Alt screen must be enabled to call update_screen")
1833 |         screen_update = ScreenUpdate(lines, x, y)
1834 |         segments = self.render(screen_update)
1835 |         self._buffer.extend(segments)
1836 |         self._check_buffer()
1837 | 
1838 |     def print_exception(
1839 |         self,
1840 |         *,
1841 |         width: Optional[int] = 100,
1842 |         extra_lines: int = 3,
1843 |         theme: Optional[str] = None,
1844 |         word_wrap: bool = False,
1845 |         show_locals: bool = False,
1846 |         suppress: Iterable[Union[str, ModuleType]] = (),
1847 |         max_frames: int = 100,
1848 |     ) -> None:
1849 |         """Prints a rich render of the last exception and traceback.
1850 | 
1851 |         Args:
1852 |             width (Optional[int], optional): Number of characters used to render code. Defaults to 100.
1853 |             extra_lines (int, optional): Additional lines of code to render. Defaults to 3.
1854 |             theme (str, optional): Override pygments theme used in traceback
1855 |             word_wrap (bool, optional): Enable word wrapping of long lines. Defaults to False.
1856 |             show_locals (bool, optional): Enable display of local variables. Defaults to False.
1857 |             suppress (Iterable[Union[str, ModuleType]]): Optional sequence of modules or paths to exclude from traceback.
1858 |             max_frames (int): Maximum number of frames to show in a traceback, 0 for no maximum. Defaults to 100.
1859 |         """
1860 |         from .traceback import Traceback
1861 | 
1862 |         traceback = Traceback(
1863 |             width=width,
1864 |             extra_lines=extra_lines,
1865 |             theme=theme,
1866 |             word_wrap=word_wrap,
1867 |             show_locals=show_locals,
1868 |             suppress=suppress,
1869 |             max_frames=max_frames,
1870 |         )
1871 |         self.print(traceback)
1872 | 
1873 |     @staticmethod
1874 |     def _caller_frame_info(
1875 |         offset: int,
1876 |         currentframe: Callable[[], Optional[FrameType]] = inspect.currentframe,
1877 |     ) -> Tuple[str, int, Dict[str, Any]]:
1878 |         """Get caller frame information.
1879 | 
1880 |         Args:
1881 |             offset (int): the caller offset within the current frame stack.
1882 |             currentframe (Callable[[], Optional[FrameType]], optional): the callable to use to
1883 |                 retrieve the current frame. Defaults to ``inspect.currentframe``.
1884 | 
1885 |         Returns:
1886 |             Tuple[str, int, Dict[str, Any]]: A tuple containing the filename, the line number and
1887 |                 the dictionary of local variables associated with the caller frame.
1888 | 
1889 |         Raises:
1890 |             RuntimeError: If the stack offset is invalid.
1891 |         """
1892 |         # Ignore the frame of this local helper
1893 |         offset += 1
1894 | 
1895 |         frame = currentframe()
1896 |         if frame is not None:
1897 |             # Use the faster currentframe where implemented
1898 |             while offset and frame is not None:
1899 |                 frame = frame.f_back
1900 |                 offset -= 1
1901 |             assert frame is not None
1902 |             return frame.f_code.co_filename, frame.f_lineno, frame.f_locals
1903 |         else:
1904 |             # Fallback to the slower stack
1905 |             frame_info = inspect.stack()[offset]
1906 |             return frame_info.filename, frame_info.lineno, frame_info.frame.f_locals
1907 | 
1908 |     def log(
1909 |         self,
1910 |         *objects: Any,
1911 |         sep: str = " ",
1912 |         end: str = "\n",
1913 |         style: Optional[Union[str, Style]] = None,
1914 |         justify: Optional[JustifyMethod] = None,
1915 |         emoji: Optional[bool] = None,
1916 |         markup: Optional[bool] = None,
1917 |         highlight: Optional[bool] = None,
1918 |         log_locals: bool = False,
1919 |         _stack_offset: int = 1,
1920 |     ) -> None:
1921 |         """Log rich content to the terminal.
1922 | 
1923 |         Args:
1924 |             objects (positional args): Objects to log to the terminal.
1925 |             sep (str, optional): String to write between print data. Defaults to " ".
1926 |             end (str, optional): String to write at end of print data. Defaults to "\\\\n".
1927 |             style (Union[str, Style], optional): A style to apply to output. Defaults to None.
1928 |             justify (str, optional): One of "left", "right", "center", or "full". Defaults to ``None``.
1929 |             emoji (Optional[bool], optional): Enable emoji code, or ``None`` to use console default. Defaults to None.
1930 |             markup (Optional[bool], optional): Enable markup, or ``None`` to use console default. Defaults to None.
1931 |             highlight (Optional[bool], optional): Enable automatic highlighting, or ``None`` to use console default. Defaults to None.
1932 |             log_locals (bool, optional): Boolean to enable logging of locals where ``log()``
1933 |                 was called. Defaults to False.
1934 |             _stack_offset (int, optional): Offset of caller from end of call stack. Defaults to 1.
1935 |         """
1936 |         if not objects:
1937 |             objects = (NewLine(),)
1938 | 
1939 |         render_hooks = self._render_hooks[:]
1940 | 
1941 |         with self:
1942 |             renderables = self._collect_renderables(
1943 |                 objects,
1944 |                 sep,
1945 |                 end,
1946 |                 justify=justify,
1947 |                 emoji=emoji,
1948 |                 markup=markup,
1949 |                 highlight=highlight,
1950 |             )
1951 |             if style is not None:
1952 |                 renderables = [Styled(renderable, style) for renderable in renderables]
1953 | 
1954 |             filename, line_no, locals = self._caller_frame_info(_stack_offset)
1955 |             link_path = None if filename.startswith("<") else os.path.abspath(filename)
1956 |             path = filename.rpartition(os.sep)[-1]
1957 |             if log_locals:
1958 |                 locals_map = {
1959 |                     key: value
1960 |                     for key, value in locals.items()
1961 |                     if not key.startswith("__")
1962 |                 }
1963 |                 renderables.append(render_scope(locals_map, title="[i]locals"))
1964 | 
1965 |             renderables = [
1966 |                 self._log_render(
1967 |                     self,
1968 |                     renderables,
1969 |                     log_time=self.get_datetime(),
1970 |                     path=path,
1971 |                     line_no=line_no,
1972 |                     link_path=link_path,
1973 |                 )
1974 |             ]
1975 |             for hook in render_hooks:
1976 |                 renderables = hook.process_renderables(renderables)
1977 |             new_segments: List[Segment] = []
1978 |             extend = new_segments.extend
1979 |             render = self.render
1980 |             render_options = self.options
1981 |             for renderable in renderables:
1982 |                 extend(render(renderable, render_options))
1983 |             buffer_extend = self._buffer.extend
1984 |             for line in Segment.split_and_crop_lines(
1985 |                 new_segments, self.width, pad=False
1986 |             ):
1987 |                 buffer_extend(line)
1988 | 
1989 |     def _check_buffer(self) -> None:
1990 |         """Check if the buffer may be rendered. Render it if it can (e.g. Console.quiet is False)
1991 |         Rendering is supported on Windows, Unix and Jupyter environments. For
1992 |         legacy Windows consoles, the win32 API is called directly.
1993 |         This method will also record what it renders if recording is enabled via Console.record.
1994 |         """
1995 |         if self.quiet:
1996 |             del self._buffer[:]
1997 |             return
1998 |         with self._lock:
1999 |             if self.record:
2000 |                 with self._record_buffer_lock:
2001 |                     self._record_buffer.extend(self._buffer[:])
2002 | 
2003 |             if self._buffer_index == 0:
2004 |                 if self.is_jupyter:  # pragma: no cover
2005 |                     from .jupyter import display
2006 | 
2007 |                     display(self._buffer, self._render_buffer(self._buffer[:]))
2008 |                     del self._buffer[:]
2009 |                 else:
2010 |                     if WINDOWS:
2011 |                         use_legacy_windows_render = False
2012 |                         if self.legacy_windows:
2013 |                             fileno = get_fileno(self.file)
2014 |                             if fileno is not None:
2015 |                                 use_legacy_windows_render = (
2016 |                                     fileno in _STD_STREAMS_OUTPUT
2017 |                                 )
2018 | 
2019 |                         if use_legacy_windows_render:
2020 |                             from pip._vendor.rich._win32_console import LegacyWindowsTerm
2021 |                             from pip._vendor.rich._windows_renderer import legacy_windows_render
2022 | 
2023 |                             buffer = self._buffer[:]
2024 |                             if self.no_color and self._color_system:
2025 |                                 buffer = list(Segment.remove_color(buffer))
2026 | 
2027 |                             legacy_windows_render(buffer, LegacyWindowsTerm(self.file))
2028 |                         else:
2029 |                             # Either a non-std stream on legacy Windows, or modern Windows.
2030 |                             text = self._render_buffer(self._buffer[:])
2031 |                             # https://bugs.python.org/issue37871
2032 |                             # https://github.com/python/cpython/issues/82052
2033 |                             # We need to avoid writing more than 32Kb in a single write, due to the above bug
2034 |                             write = self.file.write
2035 |                             # Worse case scenario, every character is 4 bytes of utf-8
2036 |                             MAX_WRITE = 32 * 1024 // 4
2037 |                             try:
2038 |                                 if len(text) <= MAX_WRITE:
2039 |                                     write(text)
2040 |                                 else:
2041 |                                     batch: List[str] = []
2042 |                                     batch_append = batch.append
2043 |                                     size = 0
2044 |                                     for line in text.splitlines(True):
2045 |                                         if size + len(line) > MAX_WRITE and batch:
2046 |                                             write("".join(batch))
2047 |                                             batch.clear()
2048 |                                             size = 0
2049 |                                         batch_append(line)
2050 |                                         size += len(line)
2051 |                                     if batch:
2052 |                                         write("".join(batch))
2053 |                                         batch.clear()
2054 |                             except UnicodeEncodeError as error:
2055 |                                 error.reason = f"{error.reason}\n*** You may need to add PYTHONIOENCODING=utf-8 to your environment ***"
2056 |                                 raise
2057 |                     else:
2058 |                         text = self._render_buffer(self._buffer[:])
2059 |                         try:
2060 |                             self.file.write(text)
2061 |                         except UnicodeEncodeError as error:
2062 |                             error.reason = f"{error.reason}\n*** You may need to add PYTHONIOENCODING=utf-8 to your environment ***"
2063 |                             raise
2064 | 
2065 |                     self.file.flush()
2066 |                     del self._buffer[:]
2067 | 
2068 |     def _render_buffer(self, buffer: Iterable[Segment]) -> str:
2069 |         """Render buffered output, and clear buffer."""
2070 |         output: List[str] = []
2071 |         append = output.append
2072 |         color_system = self._color_system
2073 |         legacy_windows = self.legacy_windows
2074 |         not_terminal = not self.is_terminal
2075 |         if self.no_color and color_system:
2076 |             buffer = Segment.remove_color(buffer)
2077 |         for text, style, control in buffer:
2078 |             if style:
2079 |                 append(
2080 |                     style.render(
2081 |                         text,
2082 |                         color_system=color_system,
2083 |                         legacy_windows=legacy_windows,
2084 |                     )
2085 |                 )
2086 |             elif not (not_terminal and control):
2087 |                 append(text)
2088 | 
2089 |         rendered = "".join(output)
2090 |         return rendered
2091 | 
2092 |     def input(
2093 |         self,
2094 |         prompt: TextType = "",
2095 |         *,
2096 |         markup: bool = True,
2097 |         emoji: bool = True,
2098 |         password: bool = False,
2099 |         stream: Optional[TextIO] = None,
2100 |     ) -> str:
2101 |         """Displays a prompt and waits for input from the user. The prompt may contain color / style.
2102 | 
2103 |         It works in the same way as Python's builtin :func:`input` function and provides elaborate line editing and history features if Python's builtin :mod:`readline` module is previously loaded.
2104 | 
2105 |         Args:
2106 |             prompt (Union[str, Text]): Text to render in the prompt.
2107 |             markup (bool, optional): Enable console markup (requires a str prompt). Defaults to True.
2108 |             emoji (bool, optional): Enable emoji (requires a str prompt). Defaults to True.
2109 |             password: (bool, optional): Hide typed text. Defaults to False.
2110 |             stream: (TextIO, optional): Optional file to read input from (rather than stdin). Defaults to None.
2111 | 
2112 |         Returns:
2113 |             str: Text read from stdin.
2114 |         """
2115 |         if prompt:
2116 |             self.print(prompt, markup=markup, emoji=emoji, end="")
2117 |         if password:
2118 |             result = getpass("", stream=stream)
2119 |         else:
2120 |             if stream:
2121 |                 result = stream.readline()
2122 |             else:
2123 |                 result = input()
2124 |         return result
2125 | 
2126 |     def export_text(self, *, clear: bool = True, styles: bool = False) -> str:
2127 |         """Generate text from console contents (requires record=True argument in constructor).
2128 | 
2129 |         Args:
2130 |             clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``.
2131 |             styles (bool, optional): If ``True``, ansi escape codes will be included. ``False`` for plain text.
2132 |                 Defaults to ``False``.
2133 | 
2134 |         Returns:
2135 |             str: String containing console contents.
2136 | 
2137 |         """
2138 |         assert (
2139 |             self.record
2140 |         ), "To export console contents set record=True in the constructor or instance"
2141 | 
2142 |         with self._record_buffer_lock:
2143 |             if styles:
2144 |                 text = "".join(
2145 |                     (style.render(text) if style else text)
2146 |                     for text, style, _ in self._record_buffer
2147 |                 )
2148 |             else:
2149 |                 text = "".join(
2150 |                     segment.text
2151 |                     for segment in self._record_buffer
2152 |                     if not segment.control
2153 |                 )
2154 |             if clear:
2155 |                 del self._record_buffer[:]
2156 |         return text
2157 | 
2158 |     def save_text(self, path: str, *, clear: bool = True, styles: bool = False) -> None:
2159 |         """Generate text from console and save to a given location (requires record=True argument in constructor).
2160 | 
2161 |         Args:
2162 |             path (str): Path to write text files.
2163 |             clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``.
2164 |             styles (bool, optional): If ``True``, ansi style codes will be included. ``False`` for plain text.
2165 |                 Defaults to ``False``.
2166 | 
2167 |         """
2168 |         text = self.export_text(clear=clear, styles=styles)
2169 |         with open(path, "wt", encoding="utf-8") as write_file:
2170 |             write_file.write(text)
2171 | 
2172 |     def export_html(
2173 |         self,
2174 |         *,
2175 |         theme: Optional[TerminalTheme] = None,
2176 |         clear: bool = True,
2177 |         code_format: Optional[str] = None,
2178 |         inline_styles: bool = False,
2179 |     ) -> str:
2180 |         """Generate HTML from console contents (requires record=True argument in constructor).
2181 | 
2182 |         Args:
2183 |             theme (TerminalTheme, optional): TerminalTheme object containing console colors.
2184 |             clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``.
2185 |             code_format (str, optional): Format string to render HTML. In addition to '{foreground}',
2186 |                 '{background}', and '{code}', should contain '{stylesheet}' if inline_styles is ``False``.
2187 |             inline_styles (bool, optional): If ``True`` styles will be inlined in to spans, which makes files
2188 |                 larger but easier to cut and paste markup. If ``False``, styles will be embedded in a style tag.
2189 |                 Defaults to False.
2190 | 
2191 |         Returns:
2192 |             str: String containing console contents as HTML.
2193 |         """
2194 |         assert (
2195 |             self.record
2196 |         ), "To export console contents set record=True in the constructor or instance"
2197 |         fragments: List[str] = []
2198 |         append = fragments.append
2199 |         _theme = theme or DEFAULT_TERMINAL_THEME
2200 |         stylesheet = ""
2201 | 
2202 |         render_code_format = CONSOLE_HTML_FORMAT if code_format is None else code_format
2203 | 
2204 |         with self._record_buffer_lock:
2205 |             if inline_styles:
2206 |                 for text, style, _ in Segment.filter_control(
2207 |                     Segment.simplify(self._record_buffer)
2208 |                 ):
2209 |                     text = escape(text)
2210 |                     if style:
2211 |                         rule = style.get_html_style(_theme)
2212 |                         if style.link:
2213 |                             text = f'<a href="{style.link}">{text}</a>'
2214 |                         text = f'<span style="{rule}">{text}</span>' if rule else text
2215 |                     append(text)
2216 |             else:
2217 |                 styles: Dict[str, int] = {}
2218 |                 for text, style, _ in Segment.filter_control(
2219 |                     Segment.simplify(self._record_buffer)
2220 |                 ):
2221 |                     text = escape(text)
2222 |                     if style:
2223 |                         rule = style.get_html_style(_theme)
2224 |                         style_number = styles.setdefault(rule, len(styles) + 1)
2225 |                         if style.link:
2226 |                             text = f'<a class="r{style_number}" href="{style.link}">{text}</a>'
2227 |                         else:
2228 |                             text = f'<span class="r{style_number}">{text}</span>'
2229 |                     append(text)
2230 |                 stylesheet_rules: List[str] = []
2231 |                 stylesheet_append = stylesheet_rules.append
2232 |                 for style_rule, style_number in styles.items():
2233 |                     if style_rule:
2234 |                         stylesheet_append(f".r{style_number} {{{style_rule}}}")
2235 |                 stylesheet = "\n".join(stylesheet_rules)
2236 | 
2237 |             rendered_code = render_code_format.format(
2238 |                 code="".join(fragments),
2239 |                 stylesheet=stylesheet,
2240 |                 foreground=_theme.foreground_color.hex,
2241 |                 background=_theme.background_color.hex,
2242 |             )
2243 |             if clear:
2244 |                 del self._record_buffer[:]
2245 |         return rendered_code
2246 | 
2247 |     def save_html(
2248 |         self,
2249 |         path: str,
2250 |         *,
2251 |         theme: Optional[TerminalTheme] = None,
2252 |         clear: bool = True,
2253 |         code_format: str = CONSOLE_HTML_FORMAT,
2254 |         inline_styles: bool = False,
2255 |     ) -> None:
2256 |         """Generate HTML from console contents and write to a file (requires record=True argument in constructor).
2257 | 
2258 |         Args:
2259 |             path (str): Path to write html file.
2260 |             theme (TerminalTheme, optional): TerminalTheme object containing console colors.
2261 |             clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``.
2262 |             code_format (str, optional): Format string to render HTML. In addition to '{foreground}',
2263 |                 '{background}', and '{code}', should contain '{stylesheet}' if inline_styles is ``False``.
2264 |             inline_styles (bool, optional): If ``True`` styles will be inlined in to spans, which makes files
2265 |                 larger but easier to cut and paste markup. If ``False``, styles will be embedded in a style tag.
2266 |                 Defaults to False.
2267 | 
2268 |         """
2269 |         html = self.export_html(
2270 |             theme=theme,
2271 |             clear=clear,
2272 |             code_format=code_format,
2273 |             inline_styles=inline_styles,
2274 |         )
2275 |         with open(path, "wt", encoding="utf-8") as write_file:
2276 |             write_file.write(html)
2277 | 
2278 |     def export_svg(
2279 |         self,
2280 |         *,
2281 |         title: str = "Rich",
2282 |         theme: Optional[TerminalTheme] = None,
2283 |         clear: bool = True,
2284 |         code_format: str = CONSOLE_SVG_FORMAT,
2285 |         font_aspect_ratio: float = 0.61,
2286 |         unique_id: Optional[str] = None,
2287 |     ) -> str:
2288 |         """
2289 |         Generate an SVG from the console contents (requires record=True in Console constructor).
2290 | 
2291 |         Args:
2292 |             title (str, optional): The title of the tab in the output image
2293 |             theme (TerminalTheme, optional): The ``TerminalTheme`` object to use to style the terminal
2294 |             clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``
2295 |             code_format (str, optional): Format string used to generate the SVG. Rich will inject a number of variables
2296 |                 into the string in order to form the final SVG output. The default template used and the variables
2297 |                 injected by Rich can be found by inspecting the ``console.CONSOLE_SVG_FORMAT`` variable.
2298 |             font_aspect_ratio (float, optional): The width to height ratio of the font used in the ``code_format``
2299 |                 string. Defaults to 0.61, which is the width to height ratio of Fira Code (the default font).
2300 |                 If you aren't specifying a different font inside ``code_format``, you probably don't need this.
2301 |             unique_id (str, optional): unique id that is used as the prefix for various elements (CSS styles, node
2302 |                 ids). If not set, this defaults to a computed value based on the recorded content.
2303 |         """
2304 | 
2305 |         from pip._vendor.rich.cells import cell_len
2306 | 
2307 |         style_cache: Dict[Style, str] = {}
2308 | 
2309 |         def get_svg_style(style: Style) -> str:
2310 |             """Convert a Style to CSS rules for SVG."""
2311 |             if style in style_cache:
2312 |                 return style_cache[style]
2313 |             css_rules = []
2314 |             color = (
2315 |                 _theme.foreground_color
2316 |                 if (style.color is None or style.color.is_default)
2317 |                 else style.color.get_truecolor(_theme)
2318 |             )
2319 |             bgcolor = (
2320 |                 _theme.background_color
2321 |                 if (style.bgcolor is None or style.bgcolor.is_default)
2322 |                 else style.bgcolor.get_truecolor(_theme)
2323 |             )
2324 |             if style.reverse:
2325 |                 color, bgcolor = bgcolor, color
2326 |             if style.dim:
2327 |                 color = blend_rgb(color, bgcolor, 0.4)
2328 |             css_rules.append(f"fill: {color.hex}")
2329 |             if style.bold:
2330 |                 css_rules.append("font-weight: bold")
2331 |             if style.italic:
2332 |                 css_rules.append("font-style: italic;")
2333 |             if style.underline:
2334 |                 css_rules.append("text-decoration: underline;")
2335 |             if style.strike:
2336 |                 css_rules.append("text-decoration: line-through;")
2337 | 
2338 |             css = ";".join(css_rules)
2339 |             style_cache[style] = css
2340 |             return css
2341 | 
2342 |         _theme = theme or SVG_EXPORT_THEME
2343 | 
2344 |         width = self.width
2345 |         char_height = 20
2346 |         char_width = char_height * font_aspect_ratio
2347 |         line_height = char_height * 1.22
2348 | 
2349 |         margin_top = 1
2350 |         margin_right = 1
2351 |         margin_bottom = 1
2352 |         margin_left = 1
2353 | 
2354 |         padding_top = 40
2355 |         padding_right = 8
2356 |         padding_bottom = 8
2357 |         padding_left = 8
2358 | 
2359 |         padding_width = padding_left + padding_right
2360 |         padding_height = padding_top + padding_bottom
2361 |         margin_width = margin_left + margin_right
2362 |         margin_height = margin_top + margin_bottom
2363 | 
2364 |         text_backgrounds: List[str] = []
2365 |         text_group: List[str] = []
2366 |         classes: Dict[str, int] = {}
2367 |         style_no = 1
2368 | 
2369 |         def escape_text(text: str) -> str:
2370 |             """HTML escape text and replace spaces with nbsp."""
2371 |             return escape(text).replace(" ", "&#160;")
2372 | 
2373 |         def make_tag(
2374 |             name: str, content: Optional[str] = None, **attribs: object
2375 |         ) -> str:
2376 |             """Make a tag from name, content, and attributes."""
2377 | 
2378 |             def stringify(value: object) -> str:
2379 |                 if isinstance(value, (float)):
2380 |                     return format(value, "g")
2381 |                 return str(value)
2382 | 
2383 |             tag_attribs = " ".join(
2384 |                 f'{k.lstrip("_").replace("_", "-")}="{stringify(v)}"'
2385 |                 for k, v in attribs.items()
2386 |             )
2387 |             return (
2388 |                 f"<{name} {tag_attribs}>{content}</{name}>"
2389 |                 if content
2390 |                 else f"<{name} {tag_attribs}/>"
2391 |             )
2392 | 
2393 |         with self._record_buffer_lock:
2394 |             segments = list(Segment.filter_control(self._record_buffer))
2395 |             if clear:
2396 |                 self._record_buffer.clear()
2397 | 
2398 |         if unique_id is None:
2399 |             unique_id = "terminal-" + str(
2400 |                 zlib.adler32(
2401 |                     ("".join(repr(segment) for segment in segments)).encode(
2402 |                         "utf-8",
2403 |                         "ignore",
2404 |                     )
2405 |                     + title.encode("utf-8", "ignore")
2406 |                 )
2407 |             )
2408 |         y = 0
2409 |         for y, line in enumerate(Segment.split_and_crop_lines(segments, length=width)):
2410 |             x = 0
2411 |             for text, style, _control in line:
2412 |                 style = style or Style()
2413 |                 rules = get_svg_style(style)
2414 |                 if rules not in classes:
2415 |                     classes[rules] = style_no
2416 |                     style_no += 1
2417 |                 class_name = f"r{classes[rules]}"
2418 | 
2419 |                 if style.reverse:
2420 |                     has_background = True
2421 |                     background = (
2422 |                         _theme.foreground_color.hex
2423 |                         if style.color is None
2424 |                         else style.color.get_truecolor(_theme).hex
2425 |                     )
2426 |                 else:
2427 |                     bgcolor = style.bgcolor
2428 |                     has_background = bgcolor is not None and not bgcolor.is_default
2429 |                     background = (
2430 |                         _theme.background_color.hex
2431 |                         if style.bgcolor is None
2432 |                         else style.bgcolor.get_truecolor(_theme).hex
2433 |                     )
2434 | 
2435 |                 text_length = cell_len(text)
2436 |                 if has_background:
2437 |                     text_backgrounds.append(
2438 |                         make_tag(
2439 |                             "rect",
2440 |                             fill=background,
2441 |                             x=x * char_width,
2442 |                             y=y * line_height + 1.5,
2443 |                             width=char_width * text_length,
2444 |                             height=line_height + 0.25,
2445 |                             shape_rendering="crispEdges",
2446 |                         )
2447 |                     )
2448 | 
2449 |                 if text != " " * len(text):
2450 |                     text_group.append(
2451 |                         make_tag(
2452 |                             "text",
2453 |                             escape_text(text),
2454 |                             _class=f"{unique_id}-{class_name}",
2455 |                             x=x * char_width,
2456 |                             y=y * line_height + char_height,
2457 |                             textLength=char_width * len(text),
2458 |                             clip_path=f"url(#{unique_id}-line-{y})",
2459 |                         )
2460 |                     )
2461 |                 x += cell_len(text)
2462 | 
2463 |         line_offsets = [line_no * line_height + 1.5 for line_no in range(y)]
2464 |         lines = "\n".join(
2465 |             f"""<clipPath id="{unique_id}-line-{line_no}">
2466 |     {make_tag("rect", x=0, y=offset, width=char_width * width, height=line_height + 0.25)}
2467 |             </clipPath>"""
2468 |             for line_no, offset in enumerate(line_offsets)
2469 |         )
2470 | 
2471 |         styles = "\n".join(
2472 |             f".{unique_id}-r{rule_no} {{ {css} }}" for css, rule_no in classes.items()
2473 |         )
2474 |         backgrounds = "".join(text_backgrounds)
2475 |         matrix = "".join(text_group)
2476 | 
2477 |         terminal_width = ceil(width * char_width + padding_width)
2478 |         terminal_height = (y + 1) * line_height + padding_height
2479 |         chrome = make_tag(
2480 |             "rect",
2481 |             fill=_theme.background_color.hex,
2482 |             stroke="rgba(255,255,255,0.35)",
2483 |             stroke_width="1",
2484 |             x=margin_left,
2485 |             y=margin_top,
2486 |             width=terminal_width,
2487 |             height=terminal_height,
2488 |             rx=8,
2489 |         )
2490 | 
2491 |         title_color = _theme.foreground_color.hex
2492 |         if title:
2493 |             chrome += make_tag(
2494 |                 "text",
2495 |                 escape_text(title),
2496 |                 _class=f"{unique_id}-title",
2497 |                 fill=title_color,
2498 |                 text_anchor="middle",
2499 |                 x=terminal_width // 2,
2500 |                 y=margin_top + char_height + 6,
2501 |             )
2502 |         chrome += f"""
2503 |             <g transform="translate(26,22)">
2504 |             <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
2505 |             <circle cx="22" cy="0" r="7" fill="#febc2e"/>
2506 |             <circle cx="44" cy="0" r="7" fill="#28c840"/>
2507 |             </g>
2508 |         """
2509 | 
2510 |         svg = code_format.format(
2511 |             unique_id=unique_id,
2512 |             char_width=char_width,
2513 |             char_height=char_height,
2514 |             line_height=line_height,
2515 |             terminal_width=char_width * width - 1,
2516 |             terminal_height=(y + 1) * line_height - 1,
2517 |             width=terminal_width + margin_width,
2518 |             height=terminal_height + margin_height,
2519 |             terminal_x=margin_left + padding_left,
2520 |             terminal_y=margin_top + padding_top,
2521 |             styles=styles,
2522 |             chrome=chrome,
2523 |             backgrounds=backgrounds,
2524 |             matrix=matrix,
2525 |             lines=lines,
2526 |         )
2527 |         return svg
2528 | 
2529 |     def save_svg(
2530 |         self,
2531 |         path: str,
2532 |         *,
2533 |         title: str = "Rich",
2534 |         theme: Optional[TerminalTheme] = None,
2535 |         clear: bool = True,
2536 |         code_format: str = CONSOLE_SVG_FORMAT,
2537 |         font_aspect_ratio: float = 0.61,
2538 |         unique_id: Optional[str] = None,
2539 |     ) -> None:
2540 |         """Generate an SVG file from the console contents (requires record=True in Console constructor).
2541 | 
2542 |         Args:
2543 |             path (str): The path to write the SVG to.
2544 |             title (str, optional): The title of the tab in the output image
2545 |             theme (TerminalTheme, optional): The ``TerminalTheme`` object to use to style the terminal
2546 |             clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``
2547 |             code_format (str, optional): Format string used to generate the SVG. Rich will inject a number of variables
2548 |                 into the string in order to form the final SVG output. The default template used and the variables
2549 |                 injected by Rich can be found by inspecting the ``console.CONSOLE_SVG_FORMAT`` variable.
2550 |             font_aspect_ratio (float, optional): The width to height ratio of the font used in the ``code_format``
2551 |                 string. Defaults to 0.61, which is the width to height ratio of Fira Code (the default font).
2552 |                 If you aren't specifying a different font inside ``code_format``, you probably don't need this.
2553 |             unique_id (str, optional): unique id that is used as the prefix for various elements (CSS styles, node
2554 |                 ids). If not set, this defaults to a computed value based on the recorded content.
2555 |         """
2556 |         svg = self.export_svg(
2557 |             title=title,
2558 |             theme=theme,
2559 |             clear=clear,
2560 |             code_format=code_format,
2561 |             font_aspect_ratio=font_aspect_ratio,
2562 |             unique_id=unique_id,
2563 |         )
2564 |         with open(path, "wt", encoding="utf-8") as write_file:
2565 |             write_file.write(svg)
2566 | 
2567 | 
2568 | def _svg_hash(svg_main_code: str) -> str:
2569 |     """Returns a unique hash for the given SVG main code.
2570 | 
2571 |     Args:
2572 |         svg_main_code (str): The content we're going to inject in the SVG envelope.
2573 | 
2574 |     Returns:
2575 |         str: a hash of the given content
2576 |     """
2577 |     return str(zlib.adler32(svg_main_code.encode()))
2578 | 
2579 | 
2580 | if __name__ == "__main__":  # pragma: no cover
2581 |     console = Console(record=True)
2582 | 
2583 |     console.log(
2584 |         "JSONRPC [i]request[/i]",
2585 |         5,
2586 |         1.3,
2587 |         True,
2588 |         False,
2589 |         None,
2590 |         {
2591 |             "jsonrpc": "2.0",
2592 |             "method": "subtract",
2593 |             "params": {"minuend": 42, "subtrahend": 23},
2594 |             "id": 3,
2595 |         },
2596 |     )
2597 | 
2598 |     console.log("Hello, World!", "{'a': 1}", repr(console))
2599 | 
2600 |     console.print(
2601 |         {
2602 |             "name": None,
2603 |             "empty": [],
2604 |             "quiz": {
2605 |                 "sport": {
2606 |                     "answered": True,
2607 |                     "q1": {
2608 |                         "question": "Which one is correct team name in NBA?",
2609 |                         "options": [
2610 |                             "New York Bulls",
2611 |                             "Los Angeles Kings",
2612 |                             "Golden State Warriors",
2613 |                             "Huston Rocket",
2614 |                         ],
2615 |                         "answer": "Huston Rocket",
2616 |                     },
2617 |                 },
2618 |                 "maths": {
2619 |                     "answered": False,
2620 |                     "q1": {
2621 |                         "question": "5 + 7 = ?",
2622 |                         "options": [10, 11, 12, 13],
2623 |                         "answer": 12,
2624 |                     },
2625 |                     "q2": {
2626 |                         "question": "12 - 8 = ?",
2627 |                         "options": [1, 2, 3, 4],
2628 |                         "answer": 4,
2629 |                     },
2630 |                 },
2631 |             },
2632 |         }
2633 |     )
2634 | 
```
Page 163/168FirstPrevNextLast