From fef259fbefe7d5a86507c5e8a2a1a58a37e10b6c Mon Sep 17 00:00:00 2001 From: Sam Mirazi Date: Sun, 1 Jun 2025 11:36:09 -0700 Subject: [PATCH] show benchmark table -ok --- .../Lib/site-packages/markdown_it/__init__.py | 5 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 343 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 540 bytes .../__pycache__/_punycode.cpython-312.pyc | Bin 0 -> 2633 bytes .../__pycache__/main.cpython-312.pyc | Bin 0 -> 17007 bytes .../__pycache__/parser_block.cpython-312.pyc | Bin 0 -> 4067 bytes .../__pycache__/parser_core.cpython-312.pyc | Bin 0 -> 1830 bytes .../__pycache__/parser_inline.cpython-312.pyc | Bin 0 -> 5305 bytes .../__pycache__/renderer.cpython-312.pyc | Bin 0 -> 11828 bytes .../__pycache__/ruler.cpython-312.pyc | Bin 0 -> 12207 bytes .../__pycache__/token.cpython-312.pyc | Bin 0 -> 7854 bytes .../__pycache__/tree.cpython-312.pyc | Bin 0 -> 15831 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 8363 bytes .../Lib/site-packages/markdown_it/_compat.py | 11 + .../site-packages/markdown_it/_punycode.py | 67 + .../site-packages/markdown_it/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 212 bytes .../cli/__pycache__/parse.cpython-312.pyc | Bin 0 -> 4526 bytes .../site-packages/markdown_it/cli/parse.py | 109 + .../markdown_it/common/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 215 bytes .../__pycache__/entities.cpython-312.pyc | Bin 0 -> 581 bytes .../__pycache__/html_blocks.cpython-312.pyc | Bin 0 -> 799 bytes .../__pycache__/html_re.cpython-312.pyc | Bin 0 -> 1361 bytes .../__pycache__/normalize_url.cpython-312.pyc | Bin 0 -> 3324 bytes .../common/__pycache__/utils.cpython-312.pyc | Bin 0 -> 10095 bytes .../markdown_it/common/entities.py | 4 + .../markdown_it/common/html_blocks.py | 68 + .../markdown_it/common/html_re.py | 40 + .../markdown_it/common/normalize_url.py | 81 + .../site-packages/markdown_it/common/utils.py | 318 + .../markdown_it/helpers/__init__.py | 6 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 481 bytes .../parse_link_destination.cpython-312.pyc | Bin 0 -> 2204 bytes .../parse_link_label.cpython-312.pyc | Bin 0 -> 1448 bytes .../parse_link_title.cpython-312.pyc | Bin 0 -> 1966 bytes .../helpers/parse_link_destination.py | 86 + .../markdown_it/helpers/parse_link_label.py | 43 + .../markdown_it/helpers/parse_link_title.py | 60 + .venv/Lib/site-packages/markdown_it/main.py | 355 ++ .../site-packages/markdown_it/parser_block.py | 111 + .../site-packages/markdown_it/parser_core.py | 45 + .../markdown_it/parser_inline.py | 147 + .venv/Lib/site-packages/markdown_it/port.yaml | 48 + .../markdown_it/presets/__init__.py | 28 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1631 bytes .../__pycache__/commonmark.cpython-312.pyc | Bin 0 -> 1176 bytes .../__pycache__/default.cpython-312.pyc | Bin 0 -> 692 bytes .../presets/__pycache__/zero.cpython-312.pyc | Bin 0 -> 953 bytes .../markdown_it/presets/commonmark.py | 74 + .../markdown_it/presets/default.py | 35 + .../site-packages/markdown_it/presets/zero.py | 43 + .venv/Lib/site-packages/markdown_it/py.typed | 1 + .../Lib/site-packages/markdown_it/renderer.py | 336 ++ .venv/Lib/site-packages/markdown_it/ruler.py | 276 + .../markdown_it/rules_block/__init__.py | 27 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 702 bytes .../__pycache__/blockquote.cpython-312.pyc | Bin 0 -> 6927 bytes .../__pycache__/code.cpython-312.pyc | Bin 0 -> 1401 bytes .../__pycache__/fence.cpython-312.pyc | Bin 0 -> 2547 bytes .../__pycache__/heading.cpython-312.pyc | Bin 0 -> 2646 bytes .../__pycache__/hr.cpython-312.pyc | Bin 0 -> 1776 bytes .../__pycache__/html_block.cpython-312.pyc | Bin 0 -> 3630 bytes .../__pycache__/lheading.cpython-312.pyc | Bin 0 -> 2952 bytes .../__pycache__/list.cpython-312.pyc | Bin 0 -> 8053 bytes .../__pycache__/paragraph.cpython-312.pyc | Bin 0 -> 2192 bytes .../__pycache__/reference.cpython-312.pyc | Bin 0 -> 5713 bytes .../__pycache__/state_block.cpython-312.pyc | Bin 0 -> 9217 bytes .../__pycache__/table.cpython-312.pyc | Bin 0 -> 7221 bytes .../markdown_it/rules_block/blockquote.py | 299 + .../markdown_it/rules_block/code.py | 35 + .../markdown_it/rules_block/fence.py | 101 + .../markdown_it/rules_block/heading.py | 68 + .../markdown_it/rules_block/hr.py | 55 + .../markdown_it/rules_block/html_block.py | 90 + .../markdown_it/rules_block/lheading.py | 86 + .../markdown_it/rules_block/list.py | 345 ++ .../markdown_it/rules_block/paragraph.py | 65 + .../markdown_it/rules_block/reference.py | 215 + .../markdown_it/rules_block/state_block.py | 261 + .../markdown_it/rules_block/table.py | 236 + .../markdown_it/rules_core/__init__.py | 19 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 566 bytes .../__pycache__/block.cpython-312.pyc | Bin 0 -> 998 bytes .../__pycache__/inline.cpython-312.pyc | Bin 0 -> 837 bytes .../__pycache__/linkify.cpython-312.pyc | Bin 0 -> 5324 bytes .../__pycache__/normalize.cpython-312.pyc | Bin 0 -> 826 bytes .../__pycache__/replacements.cpython-312.pyc | Bin 0 -> 4939 bytes .../__pycache__/smartquotes.cpython-312.pyc | Bin 0 -> 6170 bytes .../__pycache__/state_core.cpython-312.pyc | Bin 0 -> 1108 bytes .../__pycache__/text_join.cpython-312.pyc | Bin 0 -> 1481 bytes .../markdown_it/rules_core/block.py | 13 + .../markdown_it/rules_core/inline.py | 10 + .../markdown_it/rules_core/linkify.py | 149 + .../markdown_it/rules_core/normalize.py | 18 + .../markdown_it/rules_core/replacements.py | 126 + .../markdown_it/rules_core/smartquotes.py | 202 + .../markdown_it/rules_core/state_core.py | 25 + .../markdown_it/rules_core/text_join.py | 34 + .../markdown_it/rules_inline/__init__.py | 31 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 833 bytes .../__pycache__/autolink.cpython-312.pyc | Bin 0 -> 2793 bytes .../__pycache__/backticks.cpython-312.pyc | Bin 0 -> 2581 bytes .../__pycache__/balance_pairs.cpython-312.pyc | Bin 0 -> 3269 bytes .../__pycache__/emphasis.cpython-312.pyc | Bin 0 -> 3879 bytes .../__pycache__/entity.cpython-312.pyc | Bin 0 -> 2482 bytes .../__pycache__/escape.cpython-312.pyc | Bin 0 -> 1939 bytes .../fragments_join.cpython-312.pyc | Bin 0 -> 1964 bytes .../__pycache__/html_inline.cpython-312.pyc | Bin 0 -> 2005 bytes .../__pycache__/image.cpython-312.pyc | Bin 0 -> 4208 bytes .../__pycache__/link.cpython-312.pyc | Bin 0 -> 4080 bytes .../__pycache__/linkify.cpython-312.pyc | Bin 0 -> 2750 bytes .../__pycache__/newline.cpython-312.pyc | Bin 0 -> 1794 bytes .../__pycache__/state_inline.cpython-312.pyc | Bin 0 -> 5990 bytes .../__pycache__/strikethrough.cpython-312.pyc | Bin 0 -> 4229 bytes .../__pycache__/text.cpython-312.pyc | Bin 0 -> 1031 bytes .../markdown_it/rules_inline/autolink.py | 77 + .../markdown_it/rules_inline/backticks.py | 72 + .../markdown_it/rules_inline/balance_pairs.py | 137 + .../markdown_it/rules_inline/emphasis.py | 102 + .../markdown_it/rules_inline/entity.py | 53 + .../markdown_it/rules_inline/escape.py | 92 + .../rules_inline/fragments_join.py | 43 + .../markdown_it/rules_inline/html_inline.py | 43 + .../markdown_it/rules_inline/image.py | 148 + .../markdown_it/rules_inline/link.py | 151 + .../markdown_it/rules_inline/linkify.py | 61 + .../markdown_it/rules_inline/newline.py | 43 + .../markdown_it/rules_inline/state_inline.py | 166 + .../markdown_it/rules_inline/strikethrough.py | 127 + .../markdown_it/rules_inline/text.py | 53 + .venv/Lib/site-packages/markdown_it/token.py | 180 + .venv/Lib/site-packages/markdown_it/tree.py | 345 ++ .venv/Lib/site-packages/markdown_it/utils.py | 176 + .../markdown_it_py-3.0.0.dist-info/INSTALLER | 1 + .../markdown_it_py-3.0.0.dist-info/LICENSE | 21 + .../LICENSE.markdown-it | 22 + .../markdown_it_py-3.0.0.dist-info/METADATA | 205 + .../markdown_it_py-3.0.0.dist-info/RECORD | 142 + .../markdown_it_py-3.0.0.dist-info/WHEEL | 4 + .../entry_points.txt | 3 + .../mdurl-0.1.2.dist-info/INSTALLER | 1 + .../mdurl-0.1.2.dist-info/LICENSE | 46 + .../mdurl-0.1.2.dist-info/METADATA | 32 + .../mdurl-0.1.2.dist-info/RECORD | 18 + .../site-packages/mdurl-0.1.2.dist-info/WHEEL | 4 + .venv/Lib/site-packages/mdurl/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 664 bytes .../mdurl/__pycache__/_decode.cpython-312.pyc | Bin 0 -> 3839 bytes .../mdurl/__pycache__/_encode.cpython-312.pyc | Bin 0 -> 2892 bytes .../mdurl/__pycache__/_format.cpython-312.pyc | Bin 0 -> 1232 bytes .../mdurl/__pycache__/_parse.cpython-312.pyc | Bin 0 -> 7269 bytes .../mdurl/__pycache__/_url.cpython-312.pyc | Bin 0 -> 687 bytes .venv/Lib/site-packages/mdurl/_decode.py | 104 + .venv/Lib/site-packages/mdurl/_encode.py | 85 + .venv/Lib/site-packages/mdurl/_format.py | 27 + .venv/Lib/site-packages/mdurl/_parse.py | 304 + .venv/Lib/site-packages/mdurl/_url.py | 14 + .venv/Lib/site-packages/mdurl/py.typed | 1 + .../pygments-2.19.1.dist-info/INSTALLER | 1 + .../pygments-2.19.1.dist-info/METADATA | 58 + .../pygments-2.19.1.dist-info/RECORD | 682 +++ .../pygments-2.19.1.dist-info/WHEEL | 4 + .../entry_points.txt | 2 + .../licenses/AUTHORS | 291 + .../licenses/LICENSE | 25 + .venv/Lib/site-packages/pygments/__init__.py | 82 + .venv/Lib/site-packages/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3478 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 797 bytes .../__pycache__/cmdline.cpython-312.pyc | Bin 0 -> 26478 bytes .../__pycache__/console.cpython-312.pyc | Bin 0 -> 2642 bytes .../__pycache__/filter.cpython-312.pyc | Bin 0 -> 3235 bytes .../__pycache__/formatter.cpython-312.pyc | Bin 0 -> 4710 bytes .../__pycache__/lexer.cpython-312.pyc | Bin 0 -> 38665 bytes .../__pycache__/modeline.cpython-312.pyc | Bin 0 -> 1573 bytes .../__pycache__/plugin.cpython-312.pyc | Bin 0 -> 2622 bytes .../__pycache__/regexopt.cpython-312.pyc | Bin 0 -> 4091 bytes .../__pycache__/scanner.cpython-312.pyc | Bin 0 -> 4770 bytes .../__pycache__/sphinxext.cpython-312.pyc | Bin 0 -> 12082 bytes .../__pycache__/style.cpython-312.pyc | Bin 0 -> 6695 bytes .../__pycache__/token.cpython-312.pyc | Bin 0 -> 8203 bytes .../__pycache__/unistring.cpython-312.pyc | Bin 0 -> 32986 bytes .../pygments/__pycache__/util.cpython-312.pyc | Bin 0 -> 14083 bytes .venv/Lib/site-packages/pygments/cmdline.py | 668 +++ .venv/Lib/site-packages/pygments/console.py | 70 + .venv/Lib/site-packages/pygments/filter.py | 70 + .../pygments/filters/__init__.py | 940 +++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 37877 bytes .venv/Lib/site-packages/pygments/formatter.py | 129 + .../pygments/formatters/__init__.py | 157 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 6880 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 4229 bytes .../__pycache__/bbcode.cpython-312.pyc | Bin 0 -> 4212 bytes .../__pycache__/groff.cpython-312.pyc | Bin 0 -> 7283 bytes .../__pycache__/html.cpython-312.pyc | Bin 0 -> 41320 bytes .../__pycache__/img.cpython-312.pyc | Bin 0 -> 28591 bytes .../__pycache__/irc.cpython-312.pyc | Bin 0 -> 6033 bytes .../__pycache__/latex.cpython-312.pyc | Bin 0 -> 20091 bytes .../__pycache__/other.cpython-312.pyc | Bin 0 -> 6843 bytes .../__pycache__/pangomarkup.cpython-312.pyc | Bin 0 -> 2960 bytes .../__pycache__/rtf.cpython-312.pyc | Bin 0 -> 13751 bytes .../__pycache__/svg.cpython-312.pyc | Bin 0 -> 9117 bytes .../__pycache__/terminal.cpython-312.pyc | Bin 0 -> 5785 bytes .../__pycache__/terminal256.cpython-312.pyc | Bin 0 -> 15096 bytes .../pygments/formatters/_mapping.py | 23 + .../pygments/formatters/bbcode.py | 108 + .../pygments/formatters/groff.py | 170 + .../site-packages/pygments/formatters/html.py | 995 +++ .../site-packages/pygments/formatters/img.py | 686 +++ .../site-packages/pygments/formatters/irc.py | 154 + .../pygments/formatters/latex.py | 518 ++ .../pygments/formatters/other.py | 160 + .../pygments/formatters/pangomarkup.py | 83 + .../site-packages/pygments/formatters/rtf.py | 349 ++ .../site-packages/pygments/formatters/svg.py | 185 + .../pygments/formatters/terminal.py | 127 + .../pygments/formatters/terminal256.py | 338 ++ .venv/Lib/site-packages/pygments/lexer.py | 961 +++ .../site-packages/pygments/lexers/__init__.py | 362 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 14587 bytes .../__pycache__/_ada_builtins.cpython-312.pyc | Bin 0 -> 1259 bytes .../__pycache__/_asy_builtins.cpython-312.pyc | Bin 0 -> 17652 bytes .../__pycache__/_cl_builtins.cpython-312.pyc | Bin 0 -> 11688 bytes .../_cocoa_builtins.cpython-312.pyc | Bin 0 -> 97550 bytes .../_csound_builtins.cpython-312.pyc | Bin 0 -> 16400 bytes .../__pycache__/_css_builtins.cpython-312.pyc | Bin 0 -> 9409 bytes .../_googlesql_builtins.cpython-312.pyc | Bin 0 -> 10847 bytes .../_julia_builtins.cpython-312.pyc | Bin 0 -> 8274 bytes .../_lasso_builtins.cpython-312.pyc | Bin 0 -> 76752 bytes .../_lilypond_builtins.cpython-312.pyc | Bin 0 -> 88430 bytes .../__pycache__/_lua_builtins.cpython-312.pyc | Bin 0 -> 8369 bytes .../_luau_builtins.cpython-312.pyc | Bin 0 -> 1073 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 66975 bytes .../__pycache__/_mql_builtins.cpython-312.pyc | Bin 0 -> 18033 bytes .../_mysql_builtins.cpython-312.pyc | Bin 0 -> 19549 bytes .../_openedge_builtins.cpython-312.pyc | Bin 0 -> 34115 bytes .../__pycache__/_php_builtins.cpython-312.pyc | Bin 0 -> 65502 bytes .../_postgres_builtins.cpython-312.pyc | Bin 0 -> 11270 bytes .../_qlik_builtins.cpython-312.pyc | Bin 0 -> 6400 bytes .../_scheme_builtins.cpython-312.pyc | Bin 0 -> 23197 bytes .../_scilab_builtins.cpython-312.pyc | Bin 0 -> 35218 bytes .../_sourcemod_builtins.cpython-312.pyc | Bin 0 -> 21831 bytes .../_stan_builtins.cpython-312.pyc | Bin 0 -> 9976 bytes .../_stata_builtins.cpython-312.pyc | Bin 0 -> 21260 bytes .../_tsql_builtins.cpython-312.pyc | Bin 0 -> 8892 bytes .../__pycache__/_usd_builtins.cpython-312.pyc | Bin 0 -> 1422 bytes .../_vbscript_builtins.cpython-312.pyc | Bin 0 -> 2951 bytes .../__pycache__/_vim_builtins.cpython-312.pyc | Bin 0 -> 30754 bytes .../__pycache__/actionscript.cpython-312.pyc | Bin 0 -> 11139 bytes .../lexers/__pycache__/ada.cpython-312.pyc | Bin 0 -> 5535 bytes .../lexers/__pycache__/agile.cpython-312.pyc | Bin 0 -> 1330 bytes .../__pycache__/algebra.cpython-312.pyc | Bin 0 -> 11015 bytes .../__pycache__/ambient.cpython-312.pyc | Bin 0 -> 3147 bytes .../lexers/__pycache__/amdgpu.cpython-312.pyc | Bin 0 -> 2270 bytes .../lexers/__pycache__/ampl.cpython-312.pyc | Bin 0 -> 4118 bytes .../__pycache__/apdlexer.cpython-312.pyc | Bin 0 -> 19059 bytes .../lexers/__pycache__/apl.cpython-312.pyc | Bin 0 -> 2539 bytes .../__pycache__/archetype.cpython-312.pyc | Bin 0 -> 9211 bytes .../lexers/__pycache__/arrow.cpython-312.pyc | Bin 0 -> 3589 bytes .../lexers/__pycache__/arturo.cpython-312.pyc | Bin 0 -> 9766 bytes .../lexers/__pycache__/asc.cpython-312.pyc | Bin 0 -> 2069 bytes .../lexers/__pycache__/asm.cpython-312.pyc | Bin 0 -> 36033 bytes .../lexers/__pycache__/asn1.cpython-312.pyc | Bin 0 -> 4511 bytes .../__pycache__/automation.cpython-312.pyc | Bin 0 -> 18437 bytes .../lexers/__pycache__/bare.cpython-312.pyc | Bin 0 -> 2896 bytes .../lexers/__pycache__/basic.cpython-312.pyc | Bin 0 -> 26993 bytes .../lexers/__pycache__/bdd.cpython-312.pyc | Bin 0 -> 2105 bytes .../lexers/__pycache__/berry.cpython-312.pyc | Bin 0 -> 3579 bytes .../lexers/__pycache__/bibtex.cpython-312.pyc | Bin 0 -> 5245 bytes .../__pycache__/blueprint.cpython-312.pyc | Bin 0 -> 5333 bytes .../lexers/__pycache__/boa.cpython-312.pyc | Bin 0 -> 3555 bytes .../lexers/__pycache__/bqn.cpython-312.pyc | Bin 0 -> 2569 bytes .../__pycache__/business.cpython-312.pyc | Bin 0 -> 22086 bytes .../lexers/__pycache__/c_cpp.cpython-312.pyc | Bin 0 -> 16115 bytes .../lexers/__pycache__/c_like.cpython-312.pyc | Bin 0 -> 27576 bytes .../__pycache__/capnproto.cpython-312.pyc | Bin 0 -> 2428 bytes .../lexers/__pycache__/carbon.cpython-312.pyc | Bin 0 -> 3566 bytes .../lexers/__pycache__/cddl.cpython-312.pyc | Bin 0 -> 4258 bytes .../lexers/__pycache__/chapel.cpython-312.pyc | Bin 0 -> 4292 bytes .../lexers/__pycache__/clean.cpython-312.pyc | Bin 0 -> 6101 bytes .../lexers/__pycache__/codeql.cpython-312.pyc | Bin 0 -> 2774 bytes .../lexers/__pycache__/comal.cpython-312.pyc | Bin 0 -> 3248 bytes .../__pycache__/compiled.cpython-312.pyc | Bin 0 -> 2021 bytes .../__pycache__/configs.cpython-312.pyc | Bin 0 -> 44522 bytes .../__pycache__/console.cpython-312.pyc | Bin 0 -> 4271 bytes .../lexers/__pycache__/cplint.cpython-312.pyc | Bin 0 -> 1783 bytes .../__pycache__/crystal.cpython-312.pyc | Bin 0 -> 15171 bytes .../lexers/__pycache__/csound.cpython-312.pyc | Bin 0 -> 14142 bytes .../lexers/__pycache__/css.cpython-312.pyc | Bin 0 -> 22118 bytes .../lexers/__pycache__/d.cpython-312.pyc | Bin 0 -> 8357 bytes .../lexers/__pycache__/dalvik.cpython-312.pyc | Bin 0 -> 4567 bytes .../lexers/__pycache__/data.cpython-312.pyc | Bin 0 -> 21184 bytes .../lexers/__pycache__/dax.cpython-312.pyc | Bin 0 -> 6268 bytes .../__pycache__/devicetree.cpython-312.pyc | Bin 0 -> 4068 bytes .../lexers/__pycache__/diff.cpython-312.pyc | Bin 0 -> 5703 bytes .../lexers/__pycache__/dns.cpython-312.pyc | Bin 0 -> 3802 bytes .../lexers/__pycache__/dotnet.cpython-312.pyc | Bin 0 -> 35236 bytes .../lexers/__pycache__/dsls.cpython-312.pyc | Bin 0 -> 33813 bytes .../lexers/__pycache__/dylan.cpython-312.pyc | Bin 0 -> 9748 bytes .../lexers/__pycache__/ecl.cpython-312.pyc | Bin 0 -> 5611 bytes .../lexers/__pycache__/eiffel.cpython-312.pyc | Bin 0 -> 3018 bytes .../lexers/__pycache__/elm.cpython-312.pyc | Bin 0 -> 3262 bytes .../lexers/__pycache__/elpi.cpython-312.pyc | Bin 0 -> 7260 bytes .../lexers/__pycache__/email.cpython-312.pyc | Bin 0 -> 6008 bytes .../lexers/__pycache__/erlang.cpython-312.pyc | Bin 0 -> 20549 bytes .../__pycache__/esoteric.cpython-312.pyc | Bin 0 -> 9785 bytes .../lexers/__pycache__/ezhil.cpython-312.pyc | Bin 0 -> 3884 bytes .../lexers/__pycache__/factor.cpython-312.pyc | Bin 0 -> 16951 bytes .../lexers/__pycache__/fantom.cpython-312.pyc | Bin 0 -> 8020 bytes .../lexers/__pycache__/felix.cpython-312.pyc | Bin 0 -> 8275 bytes .../lexers/__pycache__/fift.cpython-312.pyc | Bin 0 -> 1987 bytes .../__pycache__/floscript.cpython-312.pyc | Bin 0 -> 3005 bytes .../lexers/__pycache__/forth.cpython-312.pyc | Bin 0 -> 5381 bytes .../__pycache__/fortran.cpython-312.pyc | Bin 0 -> 8738 bytes .../lexers/__pycache__/foxpro.cpython-312.pyc | Bin 0 -> 20835 bytes .../__pycache__/freefem.cpython-312.pyc | Bin 0 -> 12806 bytes .../lexers/__pycache__/func.cpython-312.pyc | Bin 0 -> 3361 bytes .../__pycache__/functional.cpython-312.pyc | Bin 0 -> 1071 bytes .../__pycache__/futhark.cpython-312.pyc | Bin 0 -> 4103 bytes .../__pycache__/gcodelexer.cpython-312.pyc | Bin 0 -> 1343 bytes .../__pycache__/gdscript.cpython-312.pyc | Bin 0 -> 7237 bytes .../lexers/__pycache__/gleam.cpython-312.pyc | Bin 0 -> 2735 bytes .../lexers/__pycache__/go.cpython-312.pyc | Bin 0 -> 3410 bytes .../grammar_notation.cpython-312.pyc | Bin 0 -> 7740 bytes .../lexers/__pycache__/graph.cpython-312.pyc | Bin 0 -> 3837 bytes .../__pycache__/graphics.cpython-312.pyc | Bin 0 -> 29723 bytes .../__pycache__/graphql.cpython-312.pyc | Bin 0 -> 4470 bytes .../__pycache__/graphviz.cpython-312.pyc | Bin 0 -> 2244 bytes .../lexers/__pycache__/gsql.cpython-312.pyc | Bin 0 -> 3804 bytes .../lexers/__pycache__/hare.cpython-312.pyc | Bin 0 -> 2977 bytes .../__pycache__/haskell.cpython-312.pyc | Bin 0 -> 30509 bytes .../lexers/__pycache__/haxe.cpython-312.pyc | Bin 0 -> 22307 bytes .../lexers/__pycache__/hdl.cpython-312.pyc | Bin 0 -> 17502 bytes .../__pycache__/hexdump.cpython-312.pyc | Bin 0 -> 3678 bytes .../lexers/__pycache__/html.cpython-312.pyc | Bin 0 -> 20752 bytes .../lexers/__pycache__/idl.cpython-312.pyc | Bin 0 -> 12496 bytes .../lexers/__pycache__/igor.cpython-312.pyc | Bin 0 -> 25721 bytes .../__pycache__/inferno.cpython-312.pyc | Bin 0 -> 3274 bytes .../__pycache__/installers.cpython-312.pyc | Bin 0 -> 13798 bytes .../__pycache__/int_fiction.cpython-312.pyc | Bin 0 -> 48109 bytes .../lexers/__pycache__/iolang.cpython-312.pyc | Bin 0 -> 2238 bytes .../lexers/__pycache__/j.cpython-312.pyc | Bin 0 -> 4330 bytes .../__pycache__/javascript.cpython-312.pyc | Bin 0 -> 57005 bytes .../__pycache__/jmespath.cpython-312.pyc | Bin 0 -> 2428 bytes .../lexers/__pycache__/jslt.cpython-312.pyc | Bin 0 -> 3786 bytes .../lexers/__pycache__/json5.cpython-312.pyc | Bin 0 -> 2908 bytes .../__pycache__/jsonnet.cpython-312.pyc | Bin 0 -> 4884 bytes .../lexers/__pycache__/jsx.cpython-312.pyc | Bin 0 -> 2940 bytes .../lexers/__pycache__/julia.cpython-312.pyc | Bin 0 -> 10963 bytes .../lexers/__pycache__/jvm.cpython-312.pyc | Bin 0 -> 63895 bytes .../lexers/__pycache__/kuin.cpython-312.pyc | Bin 0 -> 9908 bytes .../lexers/__pycache__/kusto.cpython-312.pyc | Bin 0 -> 2870 bytes .../lexers/__pycache__/ldap.cpython-312.pyc | Bin 0 -> 6454 bytes .../lexers/__pycache__/lean.cpython-312.pyc | Bin 0 -> 8019 bytes .../__pycache__/lilypond.cpython-312.pyc | Bin 0 -> 8399 bytes .../lexers/__pycache__/lisp.cpython-312.pyc | Bin 0 -> 121614 bytes .../__pycache__/macaulay2.cpython-312.pyc | Bin 0 -> 23183 bytes .../lexers/__pycache__/make.cpython-312.pyc | Bin 0 -> 6692 bytes .../lexers/__pycache__/maple.cpython-312.pyc | Bin 0 -> 5006 bytes .../lexers/__pycache__/markup.cpython-312.pyc | Bin 0 -> 60434 bytes .../lexers/__pycache__/math.cpython-312.pyc | Bin 0 -> 1067 bytes .../lexers/__pycache__/matlab.cpython-312.pyc | Bin 0 -> 55761 bytes .../lexers/__pycache__/maxima.cpython-312.pyc | Bin 0 -> 3215 bytes .../lexers/__pycache__/meson.cpython-312.pyc | Bin 0 -> 3548 bytes .../lexers/__pycache__/mime.cpython-312.pyc | Bin 0 -> 10144 bytes .../__pycache__/minecraft.cpython-312.pyc | Bin 0 -> 10723 bytes .../lexers/__pycache__/mips.cpython-312.pyc | Bin 0 -> 3462 bytes .../lexers/__pycache__/ml.cpython-312.pyc | Bin 0 -> 26194 bytes .../__pycache__/modeling.cpython-312.pyc | Bin 0 -> 12106 bytes .../__pycache__/modula2.cpython-312.pyc | Bin 0 -> 26445 bytes .../lexers/__pycache__/mojo.cpython-312.pyc | Bin 0 -> 14389 bytes .../lexers/__pycache__/monte.cpython-312.pyc | Bin 0 -> 5140 bytes .../lexers/__pycache__/mosel.cpython-312.pyc | Bin 0 -> 6989 bytes .../lexers/__pycache__/ncl.cpython-312.pyc | Bin 0 -> 45941 bytes .../lexers/__pycache__/nimrod.cpython-312.pyc | Bin 0 -> 6477 bytes .../lexers/__pycache__/nit.cpython-312.pyc | Bin 0 -> 2783 bytes .../lexers/__pycache__/nix.cpython-312.pyc | Bin 0 -> 5495 bytes .../__pycache__/numbair.cpython-312.pyc | Bin 0 -> 2158 bytes .../lexers/__pycache__/oberon.cpython-312.pyc | Bin 0 -> 3772 bytes .../__pycache__/objective.cpython-312.pyc | Bin 0 -> 19491 bytes .../lexers/__pycache__/ooc.cpython-312.pyc | Bin 0 -> 3143 bytes .../__pycache__/openscad.cpython-312.pyc | Bin 0 -> 3755 bytes .../lexers/__pycache__/other.cpython-312.pyc | Bin 0 -> 2477 bytes .../__pycache__/parasail.cpython-312.pyc | Bin 0 -> 2912 bytes .../__pycache__/parsers.cpython-312.pyc | Bin 0 -> 24427 bytes .../lexers/__pycache__/pascal.cpython-312.pyc | Bin 0 -> 23963 bytes .../lexers/__pycache__/pawn.cpython-312.pyc | Bin 0 -> 7887 bytes .../lexers/__pycache__/pddl.cpython-312.pyc | Bin 0 -> 2838 bytes .../lexers/__pycache__/perl.cpython-312.pyc | Bin 0 -> 39035 bytes .../lexers/__pycache__/phix.cpython-312.pyc | Bin 0 -> 18449 bytes .../lexers/__pycache__/php.cpython-312.pyc | Bin 0 -> 14336 bytes .../__pycache__/pointless.cpython-312.pyc | Bin 0 -> 2322 bytes .../lexers/__pycache__/pony.cpython-312.pyc | Bin 0 -> 3451 bytes .../lexers/__pycache__/praat.cpython-312.pyc | Bin 0 -> 10313 bytes .../__pycache__/procfile.cpython-312.pyc | Bin 0 -> 1656 bytes .../lexers/__pycache__/prolog.cpython-312.pyc | Bin 0 -> 10558 bytes .../lexers/__pycache__/promql.cpython-312.pyc | Bin 0 -> 3361 bytes .../lexers/__pycache__/prql.cpython-312.pyc | Bin 0 -> 8409 bytes .../lexers/__pycache__/ptx.cpython-312.pyc | Bin 0 -> 3797 bytes .../lexers/__pycache__/python.cpython-312.pyc | Bin 0 -> 42938 bytes .../lexers/__pycache__/q.cpython-312.pyc | Bin 0 -> 5871 bytes .../lexers/__pycache__/qlik.cpython-312.pyc | Bin 0 -> 3537 bytes .../lexers/__pycache__/qvt.cpython-312.pyc | Bin 0 -> 5405 bytes .../lexers/__pycache__/r.cpython-312.pyc | Bin 0 -> 6110 bytes .../lexers/__pycache__/rdf.cpython-312.pyc | Bin 0 -> 12280 bytes .../lexers/__pycache__/rebol.cpython-312.pyc | Bin 0 -> 19276 bytes .../lexers/__pycache__/rego.cpython-312.pyc | Bin 0 -> 1901 bytes .../__pycache__/resource.cpython-312.pyc | Bin 0 -> 3613 bytes .../lexers/__pycache__/ride.cpython-312.pyc | Bin 0 -> 4515 bytes .../lexers/__pycache__/rita.cpython-312.pyc | Bin 0 -> 1496 bytes .../lexers/__pycache__/rnc.cpython-312.pyc | Bin 0 -> 2038 bytes .../__pycache__/roboconf.cpython-312.pyc | Bin 0 -> 2389 bytes .../robotframework.cpython-312.pyc | Bin 0 -> 29598 bytes .../lexers/__pycache__/ruby.cpython-312.pyc | Bin 0 -> 22568 bytes .../lexers/__pycache__/rust.cpython-312.pyc | Bin 0 -> 7331 bytes .../lexers/__pycache__/sas.cpython-312.pyc | Bin 0 -> 7066 bytes .../lexers/__pycache__/savi.cpython-312.pyc | Bin 0 -> 4007 bytes .../lexers/__pycache__/scdoc.cpython-312.pyc | Bin 0 -> 2845 bytes .../__pycache__/scripting.cpython-312.pyc | Bin 0 -> 71806 bytes .../lexers/__pycache__/sgf.cpython-312.pyc | Bin 0 -> 2106 bytes .../lexers/__pycache__/shell.cpython-312.pyc | Bin 0 -> 37110 bytes .../lexers/__pycache__/sieve.cpython-312.pyc | Bin 0 -> 2776 bytes .../lexers/__pycache__/slash.cpython-312.pyc | Bin 0 -> 8419 bytes .../__pycache__/smalltalk.cpython-312.pyc | Bin 0 -> 6728 bytes .../lexers/__pycache__/smithy.cpython-312.pyc | Bin 0 -> 3153 bytes .../lexers/__pycache__/smv.cpython-312.pyc | Bin 0 -> 2835 bytes .../lexers/__pycache__/snobol.cpython-312.pyc | Bin 0 -> 2531 bytes .../__pycache__/solidity.cpython-312.pyc | Bin 0 -> 3434 bytes .../lexers/__pycache__/soong.cpython-312.pyc | Bin 0 -> 2299 bytes .../lexers/__pycache__/sophia.cpython-312.pyc | Bin 0 -> 3879 bytes .../__pycache__/special.cpython-312.pyc | Bin 0 -> 5441 bytes .../lexers/__pycache__/spice.cpython-312.pyc | Bin 0 -> 3204 bytes .../lexers/__pycache__/sql.cpython-312.pyc | Bin 0 -> 45587 bytes .../__pycache__/srcinfo.cpython-312.pyc | Bin 0 -> 2034 bytes .../lexers/__pycache__/stata.cpython-312.pyc | Bin 0 -> 5186 bytes .../__pycache__/supercollider.cpython-312.pyc | Bin 0 -> 3936 bytes .../__pycache__/tablegen.cpython-312.pyc | Bin 0 -> 3378 bytes .../lexers/__pycache__/tact.cpython-312.pyc | Bin 0 -> 9063 bytes .../lexers/__pycache__/tal.cpython-312.pyc | Bin 0 -> 3000 bytes .../lexers/__pycache__/tcl.cpython-312.pyc | Bin 0 -> 5174 bytes .../lexers/__pycache__/teal.cpython-312.pyc | Bin 0 -> 3583 bytes .../__pycache__/templates.cpython-312.pyc | Bin 0 -> 83664 bytes .../__pycache__/teraterm.cpython-312.pyc | Bin 0 -> 5591 bytes .../__pycache__/testing.cpython-312.pyc | Bin 0 -> 10099 bytes .../lexers/__pycache__/text.cpython-312.pyc | Bin 0 -> 1581 bytes .../__pycache__/textedit.cpython-312.pyc | Bin 0 -> 8540 bytes .../__pycache__/textfmts.cpython-312.pyc | Bin 0 -> 15621 bytes .../__pycache__/theorem.cpython-312.pyc | Bin 0 -> 14934 bytes .../__pycache__/thingsdb.cpython-312.pyc | Bin 0 -> 5645 bytes .../lexers/__pycache__/tlb.cpython-312.pyc | Bin 0 -> 1898 bytes .../lexers/__pycache__/tls.cpython-312.pyc | Bin 0 -> 1956 bytes .../lexers/__pycache__/tnt.cpython-312.pyc | Bin 0 -> 13612 bytes .../__pycache__/trafficscript.cpython-312.pyc | Bin 0 -> 1875 bytes .../__pycache__/typoscript.cpython-312.pyc | Bin 0 -> 7391 bytes .../lexers/__pycache__/typst.cpython-312.pyc | Bin 0 -> 6936 bytes .../lexers/__pycache__/ul4.cpython-312.pyc | Bin 0 -> 8172 bytes .../lexers/__pycache__/unicon.cpython-312.pyc | Bin 0 -> 12539 bytes .../lexers/__pycache__/urbi.cpython-312.pyc | Bin 0 -> 5941 bytes .../lexers/__pycache__/usd.cpython-312.pyc | Bin 0 -> 4054 bytes .../__pycache__/varnish.cpython-312.pyc | Bin 0 -> 6976 bytes .../__pycache__/verification.cpython-312.pyc | Bin 0 -> 4060 bytes .../__pycache__/verifpal.cpython-312.pyc | Bin 0 -> 3002 bytes .../lexers/__pycache__/vip.cpython-312.pyc | Bin 0 -> 5725 bytes .../lexers/__pycache__/vyper.cpython-312.pyc | Bin 0 -> 4955 bytes .../lexers/__pycache__/web.cpython-312.pyc | Bin 0 -> 1345 bytes .../__pycache__/webassembly.cpython-312.pyc | Bin 0 -> 5851 bytes .../lexers/__pycache__/webidl.cpython-312.pyc | Bin 0 -> 8135 bytes .../__pycache__/webmisc.cpython-312.pyc | Bin 0 -> 43572 bytes .../lexers/__pycache__/wgsl.cpython-312.pyc | Bin 0 -> 10881 bytes .../lexers/__pycache__/whiley.cpython-312.pyc | Bin 0 -> 3666 bytes .../lexers/__pycache__/wowtoc.cpython-312.pyc | Bin 0 -> 3271 bytes .../lexers/__pycache__/wren.cpython-312.pyc | Bin 0 -> 3136 bytes .../lexers/__pycache__/x10.cpython-312.pyc | Bin 0 -> 2427 bytes .../lexers/__pycache__/xorg.cpython-312.pyc | Bin 0 -> 1416 bytes .../lexers/__pycache__/yang.cpython-312.pyc | Bin 0 -> 4180 bytes .../lexers/__pycache__/yara.cpython-312.pyc | Bin 0 -> 2762 bytes .../lexers/__pycache__/zig.cpython-312.pyc | Bin 0 -> 3925 bytes .../pygments/lexers/_ada_builtins.py | 103 + .../pygments/lexers/_asy_builtins.py | 1644 +++++ .../pygments/lexers/_cl_builtins.py | 231 + .../pygments/lexers/_cocoa_builtins.py | 75 + .../pygments/lexers/_csound_builtins.py | 1780 ++++++ .../pygments/lexers/_css_builtins.py | 558 ++ .../pygments/lexers/_googlesql_builtins.py | 918 +++ .../pygments/lexers/_julia_builtins.py | 411 ++ .../pygments/lexers/_lasso_builtins.py | 5326 +++++++++++++++++ .../pygments/lexers/_lilypond_builtins.py | 4932 +++++++++++++++ .../pygments/lexers/_lua_builtins.py | 285 + .../pygments/lexers/_luau_builtins.py | 62 + .../site-packages/pygments/lexers/_mapping.py | 602 ++ .../pygments/lexers/_mql_builtins.py | 1171 ++++ .../pygments/lexers/_mysql_builtins.py | 1335 +++++ .../pygments/lexers/_openedge_builtins.py | 2600 ++++++++ .../pygments/lexers/_php_builtins.py | 3325 ++++++++++ .../pygments/lexers/_postgres_builtins.py | 739 +++ .../pygments/lexers/_qlik_builtins.py | 666 +++ .../pygments/lexers/_scheme_builtins.py | 1609 +++++ .../pygments/lexers/_scilab_builtins.py | 3093 ++++++++++ .../pygments/lexers/_sourcemod_builtins.py | 1151 ++++ .../pygments/lexers/_stan_builtins.py | 648 ++ .../pygments/lexers/_stata_builtins.py | 457 ++ .../pygments/lexers/_tsql_builtins.py | 1003 ++++ .../pygments/lexers/_usd_builtins.py | 112 + .../pygments/lexers/_vbscript_builtins.py | 279 + .../pygments/lexers/_vim_builtins.py | 1938 ++++++ .../pygments/lexers/actionscript.py | 243 + .../Lib/site-packages/pygments/lexers/ada.py | 144 + .../site-packages/pygments/lexers/agile.py | 25 + .../site-packages/pygments/lexers/algebra.py | 299 + .../site-packages/pygments/lexers/ambient.py | 75 + .../site-packages/pygments/lexers/amdgpu.py | 54 + .../Lib/site-packages/pygments/lexers/ampl.py | 87 + .../site-packages/pygments/lexers/apdlexer.py | 593 ++ .../Lib/site-packages/pygments/lexers/apl.py | 103 + .../pygments/lexers/archetype.py | 315 + .../site-packages/pygments/lexers/arrow.py | 116 + .../site-packages/pygments/lexers/arturo.py | 249 + .../Lib/site-packages/pygments/lexers/asc.py | 55 + .../Lib/site-packages/pygments/lexers/asm.py | 1051 ++++ .../Lib/site-packages/pygments/lexers/asn1.py | 178 + .../pygments/lexers/automation.py | 379 ++ .../Lib/site-packages/pygments/lexers/bare.py | 101 + .../site-packages/pygments/lexers/basic.py | 656 ++ .../Lib/site-packages/pygments/lexers/bdd.py | 57 + .../site-packages/pygments/lexers/berry.py | 99 + .../site-packages/pygments/lexers/bibtex.py | 159 + .../pygments/lexers/blueprint.py | 173 + .../Lib/site-packages/pygments/lexers/boa.py | 97 + .../Lib/site-packages/pygments/lexers/bqn.py | 112 + .../site-packages/pygments/lexers/business.py | 625 ++ .../site-packages/pygments/lexers/c_cpp.py | 414 ++ .../site-packages/pygments/lexers/c_like.py | 738 +++ .../pygments/lexers/capnproto.py | 74 + .../site-packages/pygments/lexers/carbon.py | 95 + .../Lib/site-packages/pygments/lexers/cddl.py | 172 + .../site-packages/pygments/lexers/chapel.py | 139 + .../site-packages/pygments/lexers/clean.py | 180 + .../site-packages/pygments/lexers/codeql.py | 80 + .../site-packages/pygments/lexers/comal.py | 81 + .../site-packages/pygments/lexers/compiled.py | 35 + .../site-packages/pygments/lexers/configs.py | 1433 +++++ .../site-packages/pygments/lexers/console.py | 114 + .../site-packages/pygments/lexers/cplint.py | 43 + .../site-packages/pygments/lexers/crystal.py | 364 ++ .../site-packages/pygments/lexers/csound.py | 466 ++ .../Lib/site-packages/pygments/lexers/css.py | 602 ++ .venv/Lib/site-packages/pygments/lexers/d.py | 259 + .../site-packages/pygments/lexers/dalvik.py | 126 + .../Lib/site-packages/pygments/lexers/data.py | 763 +++ .../Lib/site-packages/pygments/lexers/dax.py | 135 + .../pygments/lexers/devicetree.py | 108 + .../Lib/site-packages/pygments/lexers/diff.py | 169 + .../Lib/site-packages/pygments/lexers/dns.py | 109 + .../site-packages/pygments/lexers/dotnet.py | 873 +++ .../Lib/site-packages/pygments/lexers/dsls.py | 970 +++ .../site-packages/pygments/lexers/dylan.py | 279 + .../Lib/site-packages/pygments/lexers/ecl.py | 144 + .../site-packages/pygments/lexers/eiffel.py | 68 + .../Lib/site-packages/pygments/lexers/elm.py | 123 + .../Lib/site-packages/pygments/lexers/elpi.py | 175 + .../site-packages/pygments/lexers/email.py | 132 + .../site-packages/pygments/lexers/erlang.py | 526 ++ .../site-packages/pygments/lexers/esoteric.py | 300 + .../site-packages/pygments/lexers/ezhil.py | 76 + .../site-packages/pygments/lexers/factor.py | 363 ++ .../site-packages/pygments/lexers/fantom.py | 251 + .../site-packages/pygments/lexers/felix.py | 275 + .../Lib/site-packages/pygments/lexers/fift.py | 68 + .../pygments/lexers/floscript.py | 81 + .../site-packages/pygments/lexers/forth.py | 178 + .../site-packages/pygments/lexers/fortran.py | 212 + .../site-packages/pygments/lexers/foxpro.py | 427 ++ .../site-packages/pygments/lexers/freefem.py | 893 +++ .../Lib/site-packages/pygments/lexers/func.py | 110 + .../pygments/lexers/functional.py | 21 + .../site-packages/pygments/lexers/futhark.py | 105 + .../pygments/lexers/gcodelexer.py | 35 + .../site-packages/pygments/lexers/gdscript.py | 189 + .../site-packages/pygments/lexers/gleam.py | 74 + .venv/Lib/site-packages/pygments/lexers/go.py | 97 + .../pygments/lexers/grammar_notation.py | 262 + .../site-packages/pygments/lexers/graph.py | 108 + .../site-packages/pygments/lexers/graphics.py | 794 +++ .../site-packages/pygments/lexers/graphql.py | 176 + .../site-packages/pygments/lexers/graphviz.py | 58 + .../Lib/site-packages/pygments/lexers/gsql.py | 103 + .../Lib/site-packages/pygments/lexers/hare.py | 73 + .../site-packages/pygments/lexers/haskell.py | 866 +++ .../Lib/site-packages/pygments/lexers/haxe.py | 935 +++ .../Lib/site-packages/pygments/lexers/hdl.py | 466 ++ .../site-packages/pygments/lexers/hexdump.py | 102 + .../Lib/site-packages/pygments/lexers/html.py | 670 +++ .../Lib/site-packages/pygments/lexers/idl.py | 284 + .../Lib/site-packages/pygments/lexers/igor.py | 435 ++ .../site-packages/pygments/lexers/inferno.py | 95 + .../pygments/lexers/installers.py | 352 ++ .../pygments/lexers/int_fiction.py | 1370 +++++ .../site-packages/pygments/lexers/iolang.py | 61 + .venv/Lib/site-packages/pygments/lexers/j.py | 151 + .../pygments/lexers/javascript.py | 1591 +++++ .../site-packages/pygments/lexers/jmespath.py | 69 + .../Lib/site-packages/pygments/lexers/jslt.py | 94 + .../site-packages/pygments/lexers/json5.py | 83 + .../site-packages/pygments/lexers/jsonnet.py | 169 + .../Lib/site-packages/pygments/lexers/jsx.py | 100 + .../site-packages/pygments/lexers/julia.py | 294 + .../Lib/site-packages/pygments/lexers/jvm.py | 1802 ++++++ .../Lib/site-packages/pygments/lexers/kuin.py | 332 + .../site-packages/pygments/lexers/kusto.py | 93 + .../Lib/site-packages/pygments/lexers/ldap.py | 155 + .../Lib/site-packages/pygments/lexers/lean.py | 241 + .../site-packages/pygments/lexers/lilypond.py | 225 + .../Lib/site-packages/pygments/lexers/lisp.py | 3146 ++++++++++ .../pygments/lexers/macaulay2.py | 1814 ++++++ .../Lib/site-packages/pygments/lexers/make.py | 212 + .../site-packages/pygments/lexers/maple.py | 291 + .../site-packages/pygments/lexers/markup.py | 1654 +++++ .../Lib/site-packages/pygments/lexers/math.py | 21 + .../site-packages/pygments/lexers/matlab.py | 3307 ++++++++++ .../site-packages/pygments/lexers/maxima.py | 84 + .../site-packages/pygments/lexers/meson.py | 139 + .../Lib/site-packages/pygments/lexers/mime.py | 210 + .../pygments/lexers/minecraft.py | 391 ++ .../Lib/site-packages/pygments/lexers/mips.py | 130 + .venv/Lib/site-packages/pygments/lexers/ml.py | 958 +++ .../site-packages/pygments/lexers/modeling.py | 366 ++ .../site-packages/pygments/lexers/modula2.py | 1579 +++++ .../Lib/site-packages/pygments/lexers/mojo.py | 707 +++ .../site-packages/pygments/lexers/monte.py | 203 + .../site-packages/pygments/lexers/mosel.py | 447 ++ .../Lib/site-packages/pygments/lexers/ncl.py | 894 +++ .../site-packages/pygments/lexers/nimrod.py | 199 + .../Lib/site-packages/pygments/lexers/nit.py | 63 + .../Lib/site-packages/pygments/lexers/nix.py | 144 + .../site-packages/pygments/lexers/numbair.py | 63 + .../site-packages/pygments/lexers/oberon.py | 120 + .../pygments/lexers/objective.py | 513 ++ .../Lib/site-packages/pygments/lexers/ooc.py | 84 + .../site-packages/pygments/lexers/openscad.py | 96 + .../site-packages/pygments/lexers/other.py | 41 + .../site-packages/pygments/lexers/parasail.py | 78 + .../site-packages/pygments/lexers/parsers.py | 798 +++ .../site-packages/pygments/lexers/pascal.py | 644 ++ .../Lib/site-packages/pygments/lexers/pawn.py | 202 + .../Lib/site-packages/pygments/lexers/pddl.py | 82 + .../Lib/site-packages/pygments/lexers/perl.py | 733 +++ .../Lib/site-packages/pygments/lexers/phix.py | 363 ++ .../Lib/site-packages/pygments/lexers/php.py | 334 ++ .../pygments/lexers/pointless.py | 70 + .../Lib/site-packages/pygments/lexers/pony.py | 93 + .../site-packages/pygments/lexers/praat.py | 303 + .../site-packages/pygments/lexers/procfile.py | 41 + .../site-packages/pygments/lexers/prolog.py | 318 + .../site-packages/pygments/lexers/promql.py | 176 + .../Lib/site-packages/pygments/lexers/prql.py | 251 + .../Lib/site-packages/pygments/lexers/ptx.py | 119 + .../site-packages/pygments/lexers/python.py | 1201 ++++ .venv/Lib/site-packages/pygments/lexers/q.py | 187 + .../Lib/site-packages/pygments/lexers/qlik.py | 117 + .../Lib/site-packages/pygments/lexers/qvt.py | 153 + .venv/Lib/site-packages/pygments/lexers/r.py | 196 + .../Lib/site-packages/pygments/lexers/rdf.py | 468 ++ .../site-packages/pygments/lexers/rebol.py | 419 ++ .../Lib/site-packages/pygments/lexers/rego.py | 57 + .../site-packages/pygments/lexers/resource.py | 83 + .../Lib/site-packages/pygments/lexers/ride.py | 138 + .../Lib/site-packages/pygments/lexers/rita.py | 42 + .../Lib/site-packages/pygments/lexers/rnc.py | 66 + .../site-packages/pygments/lexers/roboconf.py | 81 + .../pygments/lexers/robotframework.py | 551 ++ .../Lib/site-packages/pygments/lexers/ruby.py | 518 ++ .../Lib/site-packages/pygments/lexers/rust.py | 222 + .../Lib/site-packages/pygments/lexers/sas.py | 227 + .../Lib/site-packages/pygments/lexers/savi.py | 171 + .../site-packages/pygments/lexers/scdoc.py | 85 + .../pygments/lexers/scripting.py | 1614 +++++ .../Lib/site-packages/pygments/lexers/sgf.py | 59 + .../site-packages/pygments/lexers/shell.py | 902 +++ .../site-packages/pygments/lexers/sieve.py | 78 + .../site-packages/pygments/lexers/slash.py | 183 + .../pygments/lexers/smalltalk.py | 194 + .../site-packages/pygments/lexers/smithy.py | 77 + .../Lib/site-packages/pygments/lexers/smv.py | 78 + .../site-packages/pygments/lexers/snobol.py | 82 + .../site-packages/pygments/lexers/solidity.py | 87 + .../site-packages/pygments/lexers/soong.py | 78 + .../site-packages/pygments/lexers/sophia.py | 102 + .../site-packages/pygments/lexers/special.py | 122 + .../site-packages/pygments/lexers/spice.py | 70 + .../Lib/site-packages/pygments/lexers/sql.py | 1203 ++++ .../site-packages/pygments/lexers/srcinfo.py | 62 + .../site-packages/pygments/lexers/stata.py | 170 + .../pygments/lexers/supercollider.py | 94 + .../site-packages/pygments/lexers/tablegen.py | 177 + .../Lib/site-packages/pygments/lexers/tact.py | 303 + .../Lib/site-packages/pygments/lexers/tal.py | 77 + .../Lib/site-packages/pygments/lexers/tcl.py | 148 + .../Lib/site-packages/pygments/lexers/teal.py | 88 + .../pygments/lexers/templates.py | 2355 ++++++++ .../site-packages/pygments/lexers/teraterm.py | 325 + .../site-packages/pygments/lexers/testing.py | 209 + .../Lib/site-packages/pygments/lexers/text.py | 27 + .../site-packages/pygments/lexers/textedit.py | 205 + .../site-packages/pygments/lexers/textfmts.py | 436 ++ .../site-packages/pygments/lexers/theorem.py | 410 ++ .../site-packages/pygments/lexers/thingsdb.py | 140 + .../Lib/site-packages/pygments/lexers/tlb.py | 59 + .../Lib/site-packages/pygments/lexers/tls.py | 54 + .../Lib/site-packages/pygments/lexers/tnt.py | 270 + .../pygments/lexers/trafficscript.py | 51 + .../pygments/lexers/typoscript.py | 216 + .../site-packages/pygments/lexers/typst.py | 160 + .../Lib/site-packages/pygments/lexers/ul4.py | 309 + .../site-packages/pygments/lexers/unicon.py | 413 ++ .../Lib/site-packages/pygments/lexers/urbi.py | 145 + .../Lib/site-packages/pygments/lexers/usd.py | 85 + .../site-packages/pygments/lexers/varnish.py | 189 + .../pygments/lexers/verification.py | 113 + .../site-packages/pygments/lexers/verifpal.py | 65 + .../Lib/site-packages/pygments/lexers/vip.py | 150 + .../site-packages/pygments/lexers/vyper.py | 140 + .../Lib/site-packages/pygments/lexers/web.py | 24 + .../pygments/lexers/webassembly.py | 119 + .../site-packages/pygments/lexers/webidl.py | 298 + .../site-packages/pygments/lexers/webmisc.py | 1006 ++++ .../Lib/site-packages/pygments/lexers/wgsl.py | 406 ++ .../site-packages/pygments/lexers/whiley.py | 115 + .../site-packages/pygments/lexers/wowtoc.py | 120 + .../Lib/site-packages/pygments/lexers/wren.py | 98 + .../Lib/site-packages/pygments/lexers/x10.py | 66 + .../Lib/site-packages/pygments/lexers/xorg.py | 38 + .../Lib/site-packages/pygments/lexers/yang.py | 103 + .../Lib/site-packages/pygments/lexers/yara.py | 69 + .../Lib/site-packages/pygments/lexers/zig.py | 125 + .venv/Lib/site-packages/pygments/modeline.py | 43 + .venv/Lib/site-packages/pygments/plugin.py | 72 + .venv/Lib/site-packages/pygments/regexopt.py | 91 + .venv/Lib/site-packages/pygments/scanner.py | 104 + .venv/Lib/site-packages/pygments/sphinxext.py | 247 + .venv/Lib/site-packages/pygments/style.py | 203 + .../site-packages/pygments/styles/__init__.py | 61 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2642 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 3662 bytes .../styles/__pycache__/abap.cpython-312.pyc | Bin 0 -> 1097 bytes .../styles/__pycache__/algol.cpython-312.pyc | Bin 0 -> 2617 bytes .../__pycache__/algol_nu.cpython-312.pyc | Bin 0 -> 2632 bytes .../__pycache__/arduino.cpython-312.pyc | Bin 0 -> 4291 bytes .../styles/__pycache__/autumn.cpython-312.pyc | Bin 0 -> 2873 bytes .../__pycache__/borland.cpython-312.pyc | Bin 0 -> 2242 bytes .../styles/__pycache__/bw.cpython-312.pyc | Bin 0 -> 1919 bytes .../styles/__pycache__/coffee.cpython-312.pyc | Bin 0 -> 3463 bytes .../__pycache__/colorful.cpython-312.pyc | Bin 0 -> 3731 bytes .../__pycache__/default.cpython-312.pyc | Bin 0 -> 3233 bytes .../__pycache__/dracula.cpython-312.pyc | Bin 0 -> 3046 bytes .../styles/__pycache__/emacs.cpython-312.pyc | Bin 0 -> 3273 bytes .../__pycache__/friendly.cpython-312.pyc | Bin 0 -> 3369 bytes .../friendly_grayscale.cpython-312.pyc | Bin 0 -> 3579 bytes .../styles/__pycache__/fruity.cpython-312.pyc | Bin 0 -> 1948 bytes .../__pycache__/gh_dark.cpython-312.pyc | Bin 0 -> 4037 bytes .../__pycache__/gruvbox.cpython-312.pyc | Bin 0 -> 4385 bytes .../styles/__pycache__/igor.cpython-312.pyc | Bin 0 -> 1142 bytes .../styles/__pycache__/inkpot.cpython-312.pyc | Bin 0 -> 3004 bytes .../__pycache__/lightbulb.cpython-312.pyc | Bin 0 -> 4375 bytes .../__pycache__/lilypond.cpython-312.pyc | Bin 0 -> 3516 bytes .../__pycache__/lovelace.cpython-312.pyc | Bin 0 -> 4269 bytes .../styles/__pycache__/manni.cpython-312.pyc | Bin 0 -> 3504 bytes .../__pycache__/material.cpython-312.pyc | Bin 0 -> 4817 bytes .../__pycache__/monokai.cpython-312.pyc | Bin 0 -> 4798 bytes .../styles/__pycache__/murphy.cpython-312.pyc | Bin 0 -> 3689 bytes .../styles/__pycache__/native.cpython-312.pyc | Bin 0 -> 2966 bytes .../styles/__pycache__/nord.cpython-312.pyc | Bin 0 -> 5595 bytes .../__pycache__/onedark.cpython-312.pyc | Bin 0 -> 2272 bytes .../__pycache__/paraiso_dark.cpython-312.pyc | Bin 0 -> 5138 bytes .../__pycache__/paraiso_light.cpython-312.pyc | Bin 0 -> 5144 bytes .../styles/__pycache__/pastie.cpython-312.pyc | Bin 0 -> 3478 bytes .../__pycache__/perldoc.cpython-312.pyc | Bin 0 -> 3064 bytes .../__pycache__/rainbow_dash.cpython-312.pyc | Bin 0 -> 3710 bytes .../styles/__pycache__/rrt.cpython-312.pyc | Bin 0 -> 1472 bytes .../styles/__pycache__/sas.cpython-312.pyc | Bin 0 -> 1817 bytes .../__pycache__/solarized.cpython-312.pyc | Bin 0 -> 5769 bytes .../__pycache__/staroffice.cpython-312.pyc | Bin 0 -> 1120 bytes .../__pycache__/stata_dark.cpython-312.pyc | Bin 0 -> 1687 bytes .../__pycache__/stata_light.cpython-312.pyc | Bin 0 -> 1688 bytes .../styles/__pycache__/tango.cpython-312.pyc | Bin 0 -> 6141 bytes .../styles/__pycache__/trac.cpython-312.pyc | Bin 0 -> 2613 bytes .../styles/__pycache__/vim.cpython-312.pyc | Bin 0 -> 2496 bytes .../styles/__pycache__/vs.cpython-312.pyc | Bin 0 -> 1501 bytes .../styles/__pycache__/xcode.cpython-312.pyc | Bin 0 -> 1839 bytes .../__pycache__/zenburn.cpython-312.pyc | Bin 0 -> 3348 bytes .../site-packages/pygments/styles/_mapping.py | 54 + .../Lib/site-packages/pygments/styles/abap.py | 32 + .../site-packages/pygments/styles/algol.py | 65 + .../site-packages/pygments/styles/algol_nu.py | 65 + .../site-packages/pygments/styles/arduino.py | 100 + .../site-packages/pygments/styles/autumn.py | 67 + .../site-packages/pygments/styles/borland.py | 53 + .venv/Lib/site-packages/pygments/styles/bw.py | 52 + .../site-packages/pygments/styles/coffee.py | 80 + .../site-packages/pygments/styles/colorful.py | 83 + .../site-packages/pygments/styles/default.py | 76 + .../site-packages/pygments/styles/dracula.py | 90 + .../site-packages/pygments/styles/emacs.py | 75 + .../site-packages/pygments/styles/friendly.py | 76 + .../pygments/styles/friendly_grayscale.py | 80 + .../site-packages/pygments/styles/fruity.py | 47 + .../site-packages/pygments/styles/gh_dark.py | 113 + .../site-packages/pygments/styles/gruvbox.py | 118 + .../Lib/site-packages/pygments/styles/igor.py | 32 + .../site-packages/pygments/styles/inkpot.py | 72 + .../pygments/styles/lightbulb.py | 110 + .../site-packages/pygments/styles/lilypond.py | 62 + .../site-packages/pygments/styles/lovelace.py | 100 + .../site-packages/pygments/styles/manni.py | 79 + .../site-packages/pygments/styles/material.py | 124 + .../site-packages/pygments/styles/monokai.py | 112 + .../site-packages/pygments/styles/murphy.py | 82 + .../site-packages/pygments/styles/native.py | 70 + .../Lib/site-packages/pygments/styles/nord.py | 156 + .../site-packages/pygments/styles/onedark.py | 63 + .../pygments/styles/paraiso_dark.py | 124 + .../pygments/styles/paraiso_light.py | 124 + .../site-packages/pygments/styles/pastie.py | 78 + .../site-packages/pygments/styles/perldoc.py | 73 + .../pygments/styles/rainbow_dash.py | 95 + .../Lib/site-packages/pygments/styles/rrt.py | 40 + .../Lib/site-packages/pygments/styles/sas.py | 46 + .../pygments/styles/solarized.py | 144 + .../pygments/styles/staroffice.py | 31 + .../pygments/styles/stata_dark.py | 42 + .../pygments/styles/stata_light.py | 42 + .../site-packages/pygments/styles/tango.py | 143 + .../Lib/site-packages/pygments/styles/trac.py | 66 + .../Lib/site-packages/pygments/styles/vim.py | 67 + .venv/Lib/site-packages/pygments/styles/vs.py | 41 + .../site-packages/pygments/styles/xcode.py | 53 + .../site-packages/pygments/styles/zenburn.py | 83 + .venv/Lib/site-packages/pygments/token.py | 214 + .venv/Lib/site-packages/pygments/unistring.py | 153 + .venv/Lib/site-packages/pygments/util.py | 324 + .../rich-14.0.0.dist-info/INSTALLER | 1 + .../rich-14.0.0.dist-info/LICENSE | 19 + .../rich-14.0.0.dist-info/METADATA | 473 ++ .../rich-14.0.0.dist-info/RECORD | 163 + .../rich-14.0.0.dist-info/REQUESTED | 0 .../site-packages/rich-14.0.0.dist-info/WHEEL | 4 + .venv/Lib/site-packages/rich/__init__.py | 177 + .venv/Lib/site-packages/rich/__main__.py | 273 + .../rich/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 7005 bytes .../rich/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 10162 bytes .../__pycache__/_cell_widths.cpython-312.pyc | Bin 0 -> 7886 bytes .../__pycache__/_emoji_codes.cpython-312.pyc | Bin 0 -> 205990 bytes .../_emoji_replace.cpython-312.pyc | Bin 0 -> 1743 bytes .../_export_format.cpython-312.pyc | Bin 0 -> 2363 bytes .../__pycache__/_extension.cpython-312.pyc | Bin 0 -> 527 bytes .../rich/__pycache__/_fileno.cpython-312.pyc | Bin 0 -> 869 bytes .../rich/__pycache__/_inspect.cpython-312.pyc | Bin 0 -> 12036 bytes .../__pycache__/_log_render.cpython-312.pyc | Bin 0 -> 4149 bytes .../rich/__pycache__/_loop.cpython-312.pyc | Bin 0 -> 1884 bytes .../__pycache__/_null_file.cpython-312.pyc | Bin 0 -> 3643 bytes .../__pycache__/_palettes.cpython-312.pyc | Bin 0 -> 5174 bytes .../rich/__pycache__/_pick.cpython-312.pyc | Bin 0 -> 735 bytes .../rich/__pycache__/_ratio.cpython-312.pyc | Bin 0 -> 6572 bytes .../__pycache__/_spinners.cpython-312.pyc | Bin 0 -> 13193 bytes .../rich/__pycache__/_stack.cpython-312.pyc | Bin 0 -> 979 bytes .../rich/__pycache__/_timer.cpython-312.pyc | Bin 0 -> 879 bytes .../_win32_console.cpython-312.pyc | Bin 0 -> 28789 bytes .../rich/__pycache__/_windows.cpython-312.pyc | Bin 0 -> 2480 bytes .../_windows_renderer.cpython-312.pyc | Bin 0 -> 3553 bytes .../rich/__pycache__/_wrap.cpython-312.pyc | Bin 0 -> 3340 bytes .../rich/__pycache__/abc.cpython-312.pyc | Bin 0 -> 1610 bytes .../rich/__pycache__/align.cpython-312.pyc | Bin 0 -> 12357 bytes .../rich/__pycache__/ansi.cpython-312.pyc | Bin 0 -> 9095 bytes .../rich/__pycache__/bar.cpython-312.pyc | Bin 0 -> 4286 bytes .../rich/__pycache__/box.cpython-312.pyc | Bin 0 -> 11804 bytes .../rich/__pycache__/cells.cpython-312.pyc | Bin 0 -> 5574 bytes .../rich/__pycache__/color.cpython-312.pyc | Bin 0 -> 26566 bytes .../__pycache__/color_triplet.cpython-312.pyc | Bin 0 -> 1715 bytes .../rich/__pycache__/columns.cpython-312.pyc | Bin 0 -> 8598 bytes .../rich/__pycache__/console.cpython-312.pyc | Bin 0 -> 114707 bytes .../__pycache__/constrain.cpython-312.pyc | Bin 0 -> 2272 bytes .../__pycache__/containers.cpython-312.pyc | Bin 0 -> 9224 bytes .../rich/__pycache__/control.cpython-312.pyc | Bin 0 -> 10931 bytes .../default_styles.cpython-312.pyc | Bin 0 -> 10499 bytes .../rich/__pycache__/diagnose.cpython-312.pyc | Bin 0 -> 1470 bytes .../rich/__pycache__/emoji.cpython-312.pyc | Bin 0 -> 4190 bytes .../rich/__pycache__/errors.cpython-312.pyc | Bin 0 -> 1859 bytes .../__pycache__/file_proxy.cpython-312.pyc | Bin 0 -> 3585 bytes .../rich/__pycache__/filesize.cpython-312.pyc | Bin 0 -> 3061 bytes .../__pycache__/highlighter.cpython-312.pyc | Bin 0 -> 9902 bytes .../rich/__pycache__/json.cpython-312.pyc | Bin 0 -> 6037 bytes .../rich/__pycache__/jupyter.cpython-312.pyc | Bin 0 -> 5210 bytes .../rich/__pycache__/layout.cpython-312.pyc | Bin 0 -> 20124 bytes .../rich/__pycache__/live.cpython-312.pyc | Bin 0 -> 19022 bytes .../__pycache__/live_render.cpython-312.pyc | Bin 0 -> 4891 bytes .../rich/__pycache__/logging.cpython-312.pyc | Bin 0 -> 14066 bytes .../rich/__pycache__/markdown.cpython-312.pyc | Bin 0 -> 36014 bytes .../rich/__pycache__/markup.cpython-312.pyc | Bin 0 -> 9557 bytes .../rich/__pycache__/measure.cpython-312.pyc | Bin 0 -> 6392 bytes .../rich/__pycache__/padding.cpython-312.pyc | Bin 0 -> 6935 bytes .../rich/__pycache__/pager.cpython-312.pyc | Bin 0 -> 1825 bytes .../rich/__pycache__/palette.cpython-312.pyc | Bin 0 -> 5239 bytes .../rich/__pycache__/panel.cpython-312.pyc | Bin 0 -> 12774 bytes .../rich/__pycache__/pretty.cpython-312.pyc | Bin 0 -> 40601 bytes .../rich/__pycache__/progress.cpython-312.pyc | Bin 0 -> 75736 bytes .../__pycache__/progress_bar.cpython-312.pyc | Bin 0 -> 10391 bytes .../rich/__pycache__/prompt.cpython-312.pyc | Bin 0 -> 16007 bytes .../rich/__pycache__/protocol.cpython-312.pyc | Bin 0 -> 1794 bytes .../rich/__pycache__/region.cpython-312.pyc | Bin 0 -> 581 bytes .../rich/__pycache__/repr.cpython-312.pyc | Bin 0 -> 6615 bytes .../rich/__pycache__/rule.cpython-312.pyc | Bin 0 -> 6570 bytes .../rich/__pycache__/scope.cpython-312.pyc | Bin 0 -> 3827 bytes .../rich/__pycache__/screen.cpython-312.pyc | Bin 0 -> 2481 bytes .../rich/__pycache__/segment.cpython-312.pyc | Bin 0 -> 28515 bytes .../rich/__pycache__/spinner.cpython-312.pyc | Bin 0 -> 6104 bytes .../rich/__pycache__/status.cpython-312.pyc | Bin 0 -> 6075 bytes .../rich/__pycache__/style.cpython-312.pyc | Bin 0 -> 33481 bytes .../rich/__pycache__/styled.cpython-312.pyc | Bin 0 -> 2129 bytes .../rich/__pycache__/syntax.cpython-312.pyc | Bin 0 -> 40090 bytes .../rich/__pycache__/table.cpython-312.pyc | Bin 0 -> 43827 bytes .../terminal_theme.cpython-312.pyc | Bin 0 -> 3362 bytes .../rich/__pycache__/text.cpython-312.pyc | Bin 0 -> 61212 bytes .../rich/__pycache__/theme.cpython-312.pyc | Bin 0 -> 6341 bytes .../rich/__pycache__/themes.cpython-312.pyc | Bin 0 -> 328 bytes .../__pycache__/traceback.cpython-312.pyc | Bin 0 -> 35826 bytes .../rich/__pycache__/tree.cpython-312.pyc | Bin 0 -> 11747 bytes .venv/Lib/site-packages/rich/_cell_widths.py | 454 ++ .venv/Lib/site-packages/rich/_emoji_codes.py | 3610 +++++++++++ .../Lib/site-packages/rich/_emoji_replace.py | 32 + .../Lib/site-packages/rich/_export_format.py | 76 + .venv/Lib/site-packages/rich/_extension.py | 10 + .venv/Lib/site-packages/rich/_fileno.py | 24 + .venv/Lib/site-packages/rich/_inspect.py | 268 + .venv/Lib/site-packages/rich/_log_render.py | 94 + .venv/Lib/site-packages/rich/_loop.py | 43 + .venv/Lib/site-packages/rich/_null_file.py | 69 + .venv/Lib/site-packages/rich/_palettes.py | 309 + .venv/Lib/site-packages/rich/_pick.py | 17 + .venv/Lib/site-packages/rich/_ratio.py | 159 + .venv/Lib/site-packages/rich/_spinners.py | 482 ++ .venv/Lib/site-packages/rich/_stack.py | 16 + .venv/Lib/site-packages/rich/_timer.py | 19 + .../Lib/site-packages/rich/_win32_console.py | 661 ++ .venv/Lib/site-packages/rich/_windows.py | 71 + .../site-packages/rich/_windows_renderer.py | 56 + .venv/Lib/site-packages/rich/_wrap.py | 93 + .venv/Lib/site-packages/rich/abc.py | 33 + .venv/Lib/site-packages/rich/align.py | 312 + .venv/Lib/site-packages/rich/ansi.py | 241 + .venv/Lib/site-packages/rich/bar.py | 93 + .venv/Lib/site-packages/rich/box.py | 480 ++ .venv/Lib/site-packages/rich/cells.py | 174 + .venv/Lib/site-packages/rich/color.py | 621 ++ .venv/Lib/site-packages/rich/color_triplet.py | 38 + .venv/Lib/site-packages/rich/columns.py | 187 + .venv/Lib/site-packages/rich/console.py | 2675 +++++++++ .venv/Lib/site-packages/rich/constrain.py | 37 + .venv/Lib/site-packages/rich/containers.py | 167 + .venv/Lib/site-packages/rich/control.py | 225 + .../Lib/site-packages/rich/default_styles.py | 193 + .venv/Lib/site-packages/rich/diagnose.py | 38 + .venv/Lib/site-packages/rich/emoji.py | 96 + .venv/Lib/site-packages/rich/errors.py | 34 + .venv/Lib/site-packages/rich/file_proxy.py | 57 + .venv/Lib/site-packages/rich/filesize.py | 88 + .venv/Lib/site-packages/rich/highlighter.py | 232 + .venv/Lib/site-packages/rich/json.py | 139 + .venv/Lib/site-packages/rich/jupyter.py | 101 + .venv/Lib/site-packages/rich/layout.py | 442 ++ .venv/Lib/site-packages/rich/live.py | 375 ++ .venv/Lib/site-packages/rich/live_render.py | 112 + .venv/Lib/site-packages/rich/logging.py | 297 + .venv/Lib/site-packages/rich/markdown.py | 784 +++ .venv/Lib/site-packages/rich/markup.py | 251 + .venv/Lib/site-packages/rich/measure.py | 151 + .venv/Lib/site-packages/rich/padding.py | 141 + .venv/Lib/site-packages/rich/pager.py | 34 + .venv/Lib/site-packages/rich/palette.py | 100 + .venv/Lib/site-packages/rich/panel.py | 318 + .venv/Lib/site-packages/rich/pretty.py | 1016 ++++ .venv/Lib/site-packages/rich/progress.py | 1715 ++++++ .venv/Lib/site-packages/rich/progress_bar.py | 223 + .venv/Lib/site-packages/rich/prompt.py | 400 ++ .venv/Lib/site-packages/rich/protocol.py | 42 + .venv/Lib/site-packages/rich/py.typed | 0 .venv/Lib/site-packages/rich/region.py | 10 + .venv/Lib/site-packages/rich/repr.py | 149 + .venv/Lib/site-packages/rich/rule.py | 130 + .venv/Lib/site-packages/rich/scope.py | 86 + .venv/Lib/site-packages/rich/screen.py | 54 + .venv/Lib/site-packages/rich/segment.py | 752 +++ .venv/Lib/site-packages/rich/spinner.py | 138 + .venv/Lib/site-packages/rich/status.py | 131 + .venv/Lib/site-packages/rich/style.py | 796 +++ .venv/Lib/site-packages/rich/styled.py | 42 + .venv/Lib/site-packages/rich/syntax.py | 966 +++ .venv/Lib/site-packages/rich/table.py | 1006 ++++ .../Lib/site-packages/rich/terminal_theme.py | 153 + .venv/Lib/site-packages/rich/text.py | 1361 +++++ .venv/Lib/site-packages/rich/theme.py | 115 + .venv/Lib/site-packages/rich/themes.py | 5 + .venv/Lib/site-packages/rich/traceback.py | 884 +++ .venv/Lib/site-packages/rich/tree.py | 257 + .venv/Scripts/markdown-it.exe | Bin 0 -> 108446 bytes .venv/Scripts/pygmentize.exe | Bin 0 -> 108441 bytes SOP/Handoff-FlaskBenchmarkStall.md | 98 + app_fastapi/__pycache__/app.cpython-312.pyc | Bin 721 -> 727 bytes app_fastapi/app.py | 4 +- app_flask/flask_application.py | 2 +- benchmark/run_benchmark.py | 31 +- o3.txt | 221 + show_benchmark_table.py | 140 + 1012 files changed, 161566 insertions(+), 10 deletions(-) create mode 100644 .venv/Lib/site-packages/markdown_it/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/_compat.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/_punycode.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/main.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/parser_block.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/parser_core.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/parser_inline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/renderer.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/ruler.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/token.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/tree.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/__pycache__/utils.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/_compat.py create mode 100644 .venv/Lib/site-packages/markdown_it/_punycode.py create mode 100644 .venv/Lib/site-packages/markdown_it/cli/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/cli/__pycache__/parse.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/cli/parse.py create mode 100644 .venv/Lib/site-packages/markdown_it/common/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/common/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/common/__pycache__/entities.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/common/__pycache__/html_blocks.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/common/__pycache__/html_re.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/common/__pycache__/normalize_url.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/common/__pycache__/utils.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/common/entities.py create mode 100644 .venv/Lib/site-packages/markdown_it/common/html_blocks.py create mode 100644 .venv/Lib/site-packages/markdown_it/common/html_re.py create mode 100644 .venv/Lib/site-packages/markdown_it/common/normalize_url.py create mode 100644 .venv/Lib/site-packages/markdown_it/common/utils.py create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_destination.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_label.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_title.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/parse_link_destination.py create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/parse_link_label.py create mode 100644 .venv/Lib/site-packages/markdown_it/helpers/parse_link_title.py create mode 100644 .venv/Lib/site-packages/markdown_it/main.py create mode 100644 .venv/Lib/site-packages/markdown_it/parser_block.py create mode 100644 .venv/Lib/site-packages/markdown_it/parser_core.py create mode 100644 .venv/Lib/site-packages/markdown_it/parser_inline.py create mode 100644 .venv/Lib/site-packages/markdown_it/port.yaml create mode 100644 .venv/Lib/site-packages/markdown_it/presets/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/presets/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/presets/__pycache__/commonmark.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/presets/__pycache__/default.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/presets/__pycache__/zero.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/presets/commonmark.py create mode 100644 .venv/Lib/site-packages/markdown_it/presets/default.py create mode 100644 .venv/Lib/site-packages/markdown_it/presets/zero.py create mode 100644 .venv/Lib/site-packages/markdown_it/py.typed create mode 100644 .venv/Lib/site-packages/markdown_it/renderer.py create mode 100644 .venv/Lib/site-packages/markdown_it/ruler.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/blockquote.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/code.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/fence.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/heading.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/hr.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/html_block.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/lheading.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/list.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/paragraph.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/reference.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/state_block.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/__pycache__/table.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/blockquote.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/code.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/fence.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/heading.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/hr.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/html_block.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/lheading.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/list.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/paragraph.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/reference.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/state_block.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_block/table.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/block.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/inline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/linkify.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/normalize.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/replacements.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/smartquotes.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/state_core.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/__pycache__/text_join.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/block.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/inline.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/linkify.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/normalize.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/replacements.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/smartquotes.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/state_core.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_core/text_join.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__init__.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/autolink.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/backticks.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/balance_pairs.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/emphasis.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/entity.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/escape.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/fragments_join.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/html_inline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/image.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/link.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/linkify.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/newline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/state_inline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/strikethrough.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/text.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/autolink.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/backticks.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/balance_pairs.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/emphasis.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/entity.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/escape.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/fragments_join.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/html_inline.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/image.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/link.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/linkify.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/newline.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/state_inline.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/strikethrough.py create mode 100644 .venv/Lib/site-packages/markdown_it/rules_inline/text.py create mode 100644 .venv/Lib/site-packages/markdown_it/token.py create mode 100644 .venv/Lib/site-packages/markdown_it/tree.py create mode 100644 .venv/Lib/site-packages/markdown_it/utils.py create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE.markdown-it create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/mdurl-0.1.2.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/mdurl-0.1.2.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/mdurl-0.1.2.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/mdurl-0.1.2.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/mdurl-0.1.2.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/mdurl/__init__.py create mode 100644 .venv/Lib/site-packages/mdurl/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/mdurl/__pycache__/_decode.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/mdurl/__pycache__/_encode.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/mdurl/__pycache__/_format.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/mdurl/__pycache__/_parse.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/mdurl/__pycache__/_url.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/mdurl/_decode.py create mode 100644 .venv/Lib/site-packages/mdurl/_encode.py create mode 100644 .venv/Lib/site-packages/mdurl/_format.py create mode 100644 .venv/Lib/site-packages/mdurl/_parse.py create mode 100644 .venv/Lib/site-packages/mdurl/_url.py create mode 100644 .venv/Lib/site-packages/mdurl/py.typed create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/entry_points.txt create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS create mode 100644 .venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE create mode 100644 .venv/Lib/site-packages/pygments/__init__.py create mode 100644 .venv/Lib/site-packages/pygments/__main__.py create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/__main__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/cmdline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/console.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/filter.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/formatter.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/lexer.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/modeline.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/plugin.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/regexopt.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/scanner.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/sphinxext.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/style.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/token.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/unistring.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/__pycache__/util.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/cmdline.py create mode 100644 .venv/Lib/site-packages/pygments/console.py create mode 100644 .venv/Lib/site-packages/pygments/filter.py create mode 100644 .venv/Lib/site-packages/pygments/filters/__init__.py create mode 100644 .venv/Lib/site-packages/pygments/filters/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatter.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/__init__.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/_mapping.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/bbcode.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/groff.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/html.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/img.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/irc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/latex.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/other.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/rtf.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/svg.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/terminal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/__pycache__/terminal256.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/formatters/_mapping.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/bbcode.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/groff.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/html.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/img.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/irc.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/latex.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/other.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/pangomarkup.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/rtf.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/svg.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/terminal.py create mode 100644 .venv/Lib/site-packages/pygments/formatters/terminal256.py create mode 100644 .venv/Lib/site-packages/pygments/lexer.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/__init__.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_ada_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_asy_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_cl_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_cocoa_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_csound_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_css_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_googlesql_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_julia_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_lasso_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_lilypond_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_lua_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_luau_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_mapping.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_mql_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_mysql_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_openedge_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_php_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_postgres_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_qlik_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_scheme_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_scilab_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_sourcemod_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_stan_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_stata_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_tsql_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_usd_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_vbscript_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/_vim_builtins.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/actionscript.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ada.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/agile.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/algebra.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ambient.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/amdgpu.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ampl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/apdlexer.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/apl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/archetype.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/arrow.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/arturo.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/asc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/asm.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/asn1.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/automation.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/bare.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/basic.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/bdd.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/berry.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/bibtex.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/blueprint.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/boa.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/bqn.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/business.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/c_cpp.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/c_like.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/capnproto.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/carbon.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/cddl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/chapel.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/clean.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/codeql.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/comal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/compiled.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/configs.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/console.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/cplint.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/crystal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/csound.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/css.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/d.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/dalvik.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/data.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/dax.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/devicetree.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/diff.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/dns.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/dotnet.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/dsls.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/dylan.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ecl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/eiffel.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/elm.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/elpi.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/email.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/erlang.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/esoteric.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ezhil.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/factor.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/fantom.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/felix.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/fift.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/floscript.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/forth.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/fortran.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/foxpro.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/freefem.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/func.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/functional.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/futhark.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/gcodelexer.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/gdscript.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/gleam.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/go.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/grammar_notation.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/graph.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/graphics.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/graphql.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/graphviz.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/gsql.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/hare.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/haskell.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/haxe.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/hdl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/hexdump.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/html.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/idl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/igor.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/inferno.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/installers.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/int_fiction.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/iolang.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/j.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/javascript.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/jmespath.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/jslt.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/json5.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/jsonnet.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/jsx.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/julia.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/jvm.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/kuin.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/kusto.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ldap.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/lean.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/lilypond.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/lisp.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/macaulay2.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/make.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/maple.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/markup.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/math.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/matlab.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/maxima.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/meson.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/mime.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/minecraft.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/mips.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ml.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/modeling.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/modula2.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/mojo.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/monte.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/mosel.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ncl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/nimrod.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/nit.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/nix.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/numbair.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/oberon.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/objective.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ooc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/openscad.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/other.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/parasail.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/parsers.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/pascal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/pawn.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/pddl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/perl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/phix.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/php.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/pointless.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/pony.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/praat.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/procfile.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/prolog.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/promql.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/prql.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ptx.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/python.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/q.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/qlik.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/qvt.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/r.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/rdf.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/rebol.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/rego.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/resource.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ride.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/rita.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/rnc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/roboconf.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/robotframework.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ruby.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/rust.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/sas.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/savi.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/scdoc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/scripting.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/sgf.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/shell.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/sieve.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/slash.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/smalltalk.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/smithy.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/smv.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/snobol.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/solidity.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/soong.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/sophia.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/special.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/spice.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/sql.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/srcinfo.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/stata.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/supercollider.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tablegen.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tact.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tcl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/teal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/templates.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/teraterm.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/testing.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/text.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/textedit.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/textfmts.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/theorem.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/thingsdb.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tlb.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tls.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/tnt.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/trafficscript.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/typoscript.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/typst.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/ul4.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/unicon.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/urbi.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/usd.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/varnish.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/verification.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/verifpal.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/vip.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/vyper.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/web.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/webassembly.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/webidl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/webmisc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/wgsl.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/whiley.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/wowtoc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/wren.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/x10.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/xorg.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/yang.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/yara.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/__pycache__/zig.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/lexers/_ada_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_asy_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_cl_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_cocoa_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_csound_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_css_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_googlesql_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_julia_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_lasso_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_lilypond_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_lua_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_luau_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_mapping.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_mql_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_mysql_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_openedge_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_php_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_postgres_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_qlik_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_scheme_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_scilab_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_sourcemod_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_stan_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_stata_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_tsql_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_usd_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_vbscript_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/_vim_builtins.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/actionscript.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ada.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/agile.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/algebra.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ambient.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/amdgpu.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ampl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/apdlexer.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/apl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/archetype.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/arrow.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/arturo.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/asc.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/asm.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/asn1.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/automation.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/bare.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/basic.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/bdd.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/berry.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/bibtex.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/blueprint.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/boa.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/bqn.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/business.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/c_cpp.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/c_like.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/capnproto.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/carbon.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/cddl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/chapel.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/clean.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/codeql.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/comal.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/compiled.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/configs.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/console.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/cplint.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/crystal.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/csound.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/css.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/d.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/dalvik.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/data.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/dax.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/devicetree.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/diff.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/dns.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/dotnet.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/dsls.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/dylan.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ecl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/eiffel.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/elm.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/elpi.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/email.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/erlang.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/esoteric.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ezhil.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/factor.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/fantom.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/felix.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/fift.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/floscript.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/forth.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/fortran.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/foxpro.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/freefem.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/func.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/functional.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/futhark.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/gcodelexer.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/gdscript.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/gleam.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/go.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/grammar_notation.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/graph.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/graphics.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/graphql.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/graphviz.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/gsql.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/hare.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/haskell.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/haxe.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/hdl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/hexdump.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/html.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/idl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/igor.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/inferno.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/installers.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/int_fiction.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/iolang.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/j.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/javascript.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/jmespath.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/jslt.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/json5.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/jsonnet.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/jsx.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/julia.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/jvm.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/kuin.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/kusto.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ldap.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/lean.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/lilypond.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/lisp.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/macaulay2.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/make.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/maple.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/markup.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/math.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/matlab.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/maxima.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/meson.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/mime.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/minecraft.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/mips.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ml.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/modeling.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/modula2.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/mojo.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/monte.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/mosel.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ncl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/nimrod.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/nit.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/nix.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/numbair.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/oberon.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/objective.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ooc.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/openscad.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/other.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/parasail.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/parsers.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/pascal.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/pawn.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/pddl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/perl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/phix.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/php.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/pointless.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/pony.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/praat.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/procfile.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/prolog.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/promql.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/prql.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ptx.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/python.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/q.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/qlik.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/qvt.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/r.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/rdf.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/rebol.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/rego.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/resource.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ride.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/rita.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/rnc.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/roboconf.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/robotframework.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ruby.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/rust.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/sas.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/savi.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/scdoc.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/scripting.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/sgf.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/shell.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/sieve.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/slash.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/smalltalk.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/smithy.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/smv.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/snobol.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/solidity.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/soong.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/sophia.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/special.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/spice.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/sql.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/srcinfo.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/stata.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/supercollider.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tablegen.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tact.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tal.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tcl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/teal.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/templates.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/teraterm.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/testing.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/text.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/textedit.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/textfmts.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/theorem.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/thingsdb.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tlb.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tls.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/tnt.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/trafficscript.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/typoscript.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/typst.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/ul4.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/unicon.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/urbi.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/usd.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/varnish.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/verification.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/verifpal.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/vip.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/vyper.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/web.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/webassembly.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/webidl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/webmisc.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/wgsl.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/whiley.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/wowtoc.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/wren.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/x10.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/xorg.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/yang.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/yara.py create mode 100644 .venv/Lib/site-packages/pygments/lexers/zig.py create mode 100644 .venv/Lib/site-packages/pygments/modeline.py create mode 100644 .venv/Lib/site-packages/pygments/plugin.py create mode 100644 .venv/Lib/site-packages/pygments/regexopt.py create mode 100644 .venv/Lib/site-packages/pygments/scanner.py create mode 100644 .venv/Lib/site-packages/pygments/sphinxext.py create mode 100644 .venv/Lib/site-packages/pygments/style.py create mode 100644 .venv/Lib/site-packages/pygments/styles/__init__.py create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/_mapping.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/abap.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/algol.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/algol_nu.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/arduino.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/autumn.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/borland.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/bw.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/coffee.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/colorful.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/default.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/dracula.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/emacs.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/friendly.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/friendly_grayscale.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/fruity.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/gh_dark.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/gruvbox.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/igor.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/inkpot.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/lightbulb.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/lilypond.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/lovelace.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/manni.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/material.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/monokai.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/murphy.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/native.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/nord.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/onedark.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/paraiso_dark.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/paraiso_light.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/pastie.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/perldoc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/rainbow_dash.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/rrt.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/sas.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/solarized.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/staroffice.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/stata_dark.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/stata_light.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/tango.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/trac.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/vim.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/vs.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/xcode.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/__pycache__/zenburn.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/pygments/styles/_mapping.py create mode 100644 .venv/Lib/site-packages/pygments/styles/abap.py create mode 100644 .venv/Lib/site-packages/pygments/styles/algol.py create mode 100644 .venv/Lib/site-packages/pygments/styles/algol_nu.py create mode 100644 .venv/Lib/site-packages/pygments/styles/arduino.py create mode 100644 .venv/Lib/site-packages/pygments/styles/autumn.py create mode 100644 .venv/Lib/site-packages/pygments/styles/borland.py create mode 100644 .venv/Lib/site-packages/pygments/styles/bw.py create mode 100644 .venv/Lib/site-packages/pygments/styles/coffee.py create mode 100644 .venv/Lib/site-packages/pygments/styles/colorful.py create mode 100644 .venv/Lib/site-packages/pygments/styles/default.py create mode 100644 .venv/Lib/site-packages/pygments/styles/dracula.py create mode 100644 .venv/Lib/site-packages/pygments/styles/emacs.py create mode 100644 .venv/Lib/site-packages/pygments/styles/friendly.py create mode 100644 .venv/Lib/site-packages/pygments/styles/friendly_grayscale.py create mode 100644 .venv/Lib/site-packages/pygments/styles/fruity.py create mode 100644 .venv/Lib/site-packages/pygments/styles/gh_dark.py create mode 100644 .venv/Lib/site-packages/pygments/styles/gruvbox.py create mode 100644 .venv/Lib/site-packages/pygments/styles/igor.py create mode 100644 .venv/Lib/site-packages/pygments/styles/inkpot.py create mode 100644 .venv/Lib/site-packages/pygments/styles/lightbulb.py create mode 100644 .venv/Lib/site-packages/pygments/styles/lilypond.py create mode 100644 .venv/Lib/site-packages/pygments/styles/lovelace.py create mode 100644 .venv/Lib/site-packages/pygments/styles/manni.py create mode 100644 .venv/Lib/site-packages/pygments/styles/material.py create mode 100644 .venv/Lib/site-packages/pygments/styles/monokai.py create mode 100644 .venv/Lib/site-packages/pygments/styles/murphy.py create mode 100644 .venv/Lib/site-packages/pygments/styles/native.py create mode 100644 .venv/Lib/site-packages/pygments/styles/nord.py create mode 100644 .venv/Lib/site-packages/pygments/styles/onedark.py create mode 100644 .venv/Lib/site-packages/pygments/styles/paraiso_dark.py create mode 100644 .venv/Lib/site-packages/pygments/styles/paraiso_light.py create mode 100644 .venv/Lib/site-packages/pygments/styles/pastie.py create mode 100644 .venv/Lib/site-packages/pygments/styles/perldoc.py create mode 100644 .venv/Lib/site-packages/pygments/styles/rainbow_dash.py create mode 100644 .venv/Lib/site-packages/pygments/styles/rrt.py create mode 100644 .venv/Lib/site-packages/pygments/styles/sas.py create mode 100644 .venv/Lib/site-packages/pygments/styles/solarized.py create mode 100644 .venv/Lib/site-packages/pygments/styles/staroffice.py create mode 100644 .venv/Lib/site-packages/pygments/styles/stata_dark.py create mode 100644 .venv/Lib/site-packages/pygments/styles/stata_light.py create mode 100644 .venv/Lib/site-packages/pygments/styles/tango.py create mode 100644 .venv/Lib/site-packages/pygments/styles/trac.py create mode 100644 .venv/Lib/site-packages/pygments/styles/vim.py create mode 100644 .venv/Lib/site-packages/pygments/styles/vs.py create mode 100644 .venv/Lib/site-packages/pygments/styles/xcode.py create mode 100644 .venv/Lib/site-packages/pygments/styles/zenburn.py create mode 100644 .venv/Lib/site-packages/pygments/token.py create mode 100644 .venv/Lib/site-packages/pygments/unistring.py create mode 100644 .venv/Lib/site-packages/pygments/util.py create mode 100644 .venv/Lib/site-packages/rich-14.0.0.dist-info/INSTALLER create mode 100644 .venv/Lib/site-packages/rich-14.0.0.dist-info/LICENSE create mode 100644 .venv/Lib/site-packages/rich-14.0.0.dist-info/METADATA create mode 100644 .venv/Lib/site-packages/rich-14.0.0.dist-info/RECORD create mode 100644 .venv/Lib/site-packages/rich-14.0.0.dist-info/REQUESTED create mode 100644 .venv/Lib/site-packages/rich-14.0.0.dist-info/WHEEL create mode 100644 .venv/Lib/site-packages/rich/__init__.py create mode 100644 .venv/Lib/site-packages/rich/__main__.py create mode 100644 .venv/Lib/site-packages/rich/__pycache__/__init__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/__main__.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_cell_widths.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_emoji_codes.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_emoji_replace.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_export_format.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_extension.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_fileno.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_inspect.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_log_render.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_loop.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_null_file.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_palettes.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_pick.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_ratio.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_spinners.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_stack.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_timer.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_win32_console.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_windows.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_windows_renderer.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/_wrap.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/abc.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/align.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/ansi.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/bar.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/box.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/cells.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/color.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/color_triplet.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/columns.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/console.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/constrain.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/containers.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/control.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/default_styles.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/diagnose.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/emoji.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/errors.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/file_proxy.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/filesize.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/highlighter.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/json.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/jupyter.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/layout.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/live.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/live_render.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/logging.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/markdown.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/markup.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/measure.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/padding.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/pager.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/palette.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/panel.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/pretty.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/progress.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/progress_bar.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/prompt.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/protocol.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/region.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/repr.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/rule.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/scope.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/screen.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/segment.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/spinner.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/status.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/style.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/styled.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/syntax.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/table.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/terminal_theme.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/text.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/theme.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/themes.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/traceback.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/__pycache__/tree.cpython-312.pyc create mode 100644 .venv/Lib/site-packages/rich/_cell_widths.py create mode 100644 .venv/Lib/site-packages/rich/_emoji_codes.py create mode 100644 .venv/Lib/site-packages/rich/_emoji_replace.py create mode 100644 .venv/Lib/site-packages/rich/_export_format.py create mode 100644 .venv/Lib/site-packages/rich/_extension.py create mode 100644 .venv/Lib/site-packages/rich/_fileno.py create mode 100644 .venv/Lib/site-packages/rich/_inspect.py create mode 100644 .venv/Lib/site-packages/rich/_log_render.py create mode 100644 .venv/Lib/site-packages/rich/_loop.py create mode 100644 .venv/Lib/site-packages/rich/_null_file.py create mode 100644 .venv/Lib/site-packages/rich/_palettes.py create mode 100644 .venv/Lib/site-packages/rich/_pick.py create mode 100644 .venv/Lib/site-packages/rich/_ratio.py create mode 100644 .venv/Lib/site-packages/rich/_spinners.py create mode 100644 .venv/Lib/site-packages/rich/_stack.py create mode 100644 .venv/Lib/site-packages/rich/_timer.py create mode 100644 .venv/Lib/site-packages/rich/_win32_console.py create mode 100644 .venv/Lib/site-packages/rich/_windows.py create mode 100644 .venv/Lib/site-packages/rich/_windows_renderer.py create mode 100644 .venv/Lib/site-packages/rich/_wrap.py create mode 100644 .venv/Lib/site-packages/rich/abc.py create mode 100644 .venv/Lib/site-packages/rich/align.py create mode 100644 .venv/Lib/site-packages/rich/ansi.py create mode 100644 .venv/Lib/site-packages/rich/bar.py create mode 100644 .venv/Lib/site-packages/rich/box.py create mode 100644 .venv/Lib/site-packages/rich/cells.py create mode 100644 .venv/Lib/site-packages/rich/color.py create mode 100644 .venv/Lib/site-packages/rich/color_triplet.py create mode 100644 .venv/Lib/site-packages/rich/columns.py create mode 100644 .venv/Lib/site-packages/rich/console.py create mode 100644 .venv/Lib/site-packages/rich/constrain.py create mode 100644 .venv/Lib/site-packages/rich/containers.py create mode 100644 .venv/Lib/site-packages/rich/control.py create mode 100644 .venv/Lib/site-packages/rich/default_styles.py create mode 100644 .venv/Lib/site-packages/rich/diagnose.py create mode 100644 .venv/Lib/site-packages/rich/emoji.py create mode 100644 .venv/Lib/site-packages/rich/errors.py create mode 100644 .venv/Lib/site-packages/rich/file_proxy.py create mode 100644 .venv/Lib/site-packages/rich/filesize.py create mode 100644 .venv/Lib/site-packages/rich/highlighter.py create mode 100644 .venv/Lib/site-packages/rich/json.py create mode 100644 .venv/Lib/site-packages/rich/jupyter.py create mode 100644 .venv/Lib/site-packages/rich/layout.py create mode 100644 .venv/Lib/site-packages/rich/live.py create mode 100644 .venv/Lib/site-packages/rich/live_render.py create mode 100644 .venv/Lib/site-packages/rich/logging.py create mode 100644 .venv/Lib/site-packages/rich/markdown.py create mode 100644 .venv/Lib/site-packages/rich/markup.py create mode 100644 .venv/Lib/site-packages/rich/measure.py create mode 100644 .venv/Lib/site-packages/rich/padding.py create mode 100644 .venv/Lib/site-packages/rich/pager.py create mode 100644 .venv/Lib/site-packages/rich/palette.py create mode 100644 .venv/Lib/site-packages/rich/panel.py create mode 100644 .venv/Lib/site-packages/rich/pretty.py create mode 100644 .venv/Lib/site-packages/rich/progress.py create mode 100644 .venv/Lib/site-packages/rich/progress_bar.py create mode 100644 .venv/Lib/site-packages/rich/prompt.py create mode 100644 .venv/Lib/site-packages/rich/protocol.py create mode 100644 .venv/Lib/site-packages/rich/py.typed create mode 100644 .venv/Lib/site-packages/rich/region.py create mode 100644 .venv/Lib/site-packages/rich/repr.py create mode 100644 .venv/Lib/site-packages/rich/rule.py create mode 100644 .venv/Lib/site-packages/rich/scope.py create mode 100644 .venv/Lib/site-packages/rich/screen.py create mode 100644 .venv/Lib/site-packages/rich/segment.py create mode 100644 .venv/Lib/site-packages/rich/spinner.py create mode 100644 .venv/Lib/site-packages/rich/status.py create mode 100644 .venv/Lib/site-packages/rich/style.py create mode 100644 .venv/Lib/site-packages/rich/styled.py create mode 100644 .venv/Lib/site-packages/rich/syntax.py create mode 100644 .venv/Lib/site-packages/rich/table.py create mode 100644 .venv/Lib/site-packages/rich/terminal_theme.py create mode 100644 .venv/Lib/site-packages/rich/text.py create mode 100644 .venv/Lib/site-packages/rich/theme.py create mode 100644 .venv/Lib/site-packages/rich/themes.py create mode 100644 .venv/Lib/site-packages/rich/traceback.py create mode 100644 .venv/Lib/site-packages/rich/tree.py create mode 100644 .venv/Scripts/markdown-it.exe create mode 100644 .venv/Scripts/pygmentize.exe create mode 100644 SOP/Handoff-FlaskBenchmarkStall.md create mode 100644 o3.txt create mode 100644 show_benchmark_table.py diff --git a/.venv/Lib/site-packages/markdown_it/__init__.py b/.venv/Lib/site-packages/markdown_it/__init__.py new file mode 100644 index 0000000..6606868 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/__init__.py @@ -0,0 +1,5 @@ +"""A Python port of Markdown-It""" +__all__ = ("MarkdownIt",) +__version__ = "3.0.0" + +from .main import MarkdownIt diff --git a/.venv/Lib/site-packages/markdown_it/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..74feb25f52e6cde75d9d291419061546689b9930 GIT binary patch literal 343 zcmXwz&q@O^5XO`4mTH%J>p|E<@V1Ap1#eP>VkuTs3dPG32yqi_x_`1J=}LR*6L|F* zd=_7z_9_V8gx)-vg?0`z-^Vx1{61Q(Ca`t=+M7Px`Bj;H)pla*Tk!@Mhya5TWVNWq z90pS-b0Zgmg&WkDejkk&W-4=3NM(?GM7LBWOupoukqO|Yxwj*;te=J5u=@k;)w`g+ zX%NC>Oh_eYnp)uzQgWq*%&l=VDsok^yn}5;^d~RR@x8VSctSHg;5sp~z!SkZ8Y?;D zvC())wds#XsMKhfQk~!{8Yf(#ft*PkmOL-x5!l1mgM*(CzctCZkv{;R z9RPTPc2JCBoS__t7&o|;wQ>@Y877$(TEJPEojaieoGse1Gk{59jTXO+N_Oqi6opdqJ-?ZLXL$N7lB^q|w_ww{{uZ8=J8bjH#wxUy5XwiD;(P=ev=z z8kXov*N&+gS!K`q82fK4#_Ed`p)_pBl44IP2YTM2Gw|qFvA#xkG*oH8b2=0{HL|2Z z5({rj$q|TYy1}*aw;p&C?QLXSr}RFLQlY$|97)=rh+;xFlU=G4BUVc&@qM9b&Q%)A zLy$DLStRq4n|@iwMxq9R6%F(N1YvuIHHSlT)CVvB*0+`JJ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/__pycache__/_punycode.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/__pycache__/_punycode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25990e1b8bf11542652de40458405193fb22cb90 GIT binary patch literal 2633 zcmcIl-A@}w5Z}E!pN-Ep!B%MaYMnX>G7%0TkTis#BEV@H6U>V&$jwBm8V48Ob<`CdwR7V34^ex4=*E7;#9! z5mR+xoy+`VT$Uybe>+F0%@JjTVw6S2I3vi$`@)1tHr3y2K>Q=z^J0mYw<+DAC?v84HAziAx#Zhwl~>U`jx zU}#<;&e3=z9`M{%Vs``M;pu=H)|Bo9n1Zv48dwODc{#omn+j`Zrm7x#5-UW4a~XMq zdeIIfjrOIc2bb3`XB}I~J*oGJba7X@n3pc)gi9r`Bi#^GL*ekNL)rrq{#!`>h!|m! zn^^6k@HanaxEF4j^?uk8Zc_Nqsq?kJv!3i>gK-<~lbM3mpWs20N{f zPw*y6p-2sSP*sMEtNFdk$=oWh(Ntk0#Z@gbKR*h-T2q`Xu$;z8n6b)(%u{(4Y4kKU zUUfzaRd-qyWJ84B|1V<=&tO@+Z%PTHsG4B4HHH+QGSCzK$ZhoL_-!3Mr8gn;x;pl} z1kE|nmpnkez}FB4fKq4@0=^7lPrKXD}KM1*7Var)H+9p*90~{yTb} zM!Dwxotdp$8zg&jb7g1d50ysjp8Y6x3%Wr~M8lfSN0pd<gCx4!?K( zre7B#@o>y7k|tQd9MTPmAkm<j%7zSUSAUnP0dtT z6ZfqhPpqz8t82@fx1LUW3$~^QbL(??dPyL8TYvgWL2Ale*_GOILR&dg`S^6?C9GIy z8USCQg<}nPdB|M-AKEQ{Us%NlQWF7+m1Kvc5PakmEF-jA9Xfz2Xz`Tp0QvU{AngZ_ zkU1H(qJL_E)eQARf`J>n?}e}&>+XI^p@lp$s~W{=DXh)0T85;GFDYaPGj9)+yKV%4 z5>Uj+HZ48{eVn$+dP-G{{jjUr1q48oY!8Okhq9;kq~rUJmaHoq%uZ)JzwZ93`{9|q zqbq0WDm2>H%q;FZoX$g!V94)qG+mwPdZg_v^?@|oqKp~*U_1?bk=brXJ83AOV=Gl%2YjqyalGqbPnxz z3Nh}&JjS@>LD=>)YWM}U{p#q*^llDp4CG$Fn0E~1(2;_@J@e*f z*G5-%GH*YfZY+uz4`%ox0+!`Vlod@F_h(#G)t_}yRe#ZB#_bukh=6UGwq4stzvs7G mcb$Dq^Mj*A4aHUwpU8|95wPq?iL#=ds$eUsay_GrUE)u9`XFEc literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/__pycache__/main.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/__pycache__/main.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f7e2435be2b331e22d8d96bc64d50720157a65e GIT binary patch literal 17007 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/__pycache__/parser_core.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/__pycache__/parser_core.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62fc6e3d61d2c2555ecdc3d561cbd33bd768ff75 GIT binary patch literal 1830 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/__pycache__/utils.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d91c53b125f24db615f8b63e119246268f9728e8 GIT binary patch literal 8363 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/_compat.py b/.venv/Lib/site-packages/markdown_it/_compat.py new file mode 100644 index 0000000..974d431 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/_compat.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from collections.abc import Mapping +import sys +from typing import Any + +DATACLASS_KWARGS: Mapping[str, Any] +if sys.version_info >= (3, 10): + DATACLASS_KWARGS = {"slots": True} +else: + DATACLASS_KWARGS = {} diff --git a/.venv/Lib/site-packages/markdown_it/_punycode.py b/.venv/Lib/site-packages/markdown_it/_punycode.py new file mode 100644 index 0000000..f9baad2 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/_punycode.py @@ -0,0 +1,67 @@ +# Copyright 2014 Mathias Bynens +# Copyright 2021 Taneli Hukkinen +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import codecs +import re +from typing import Callable + +REGEX_SEPARATORS = re.compile(r"[\x2E\u3002\uFF0E\uFF61]") +REGEX_NON_ASCII = re.compile(r"[^\0-\x7E]") + + +def encode(uni: str) -> str: + return codecs.encode(uni, encoding="punycode").decode() + + +def decode(ascii: str) -> str: + return codecs.decode(ascii, encoding="punycode") # type: ignore + + +def map_domain(string: str, fn: Callable[[str], str]) -> str: + parts = string.split("@") + result = "" + if len(parts) > 1: + # In email addresses, only the domain name should be punycoded. Leave + # the local part (i.e. everything up to `@`) intact. + result = parts[0] + "@" + string = parts[1] + labels = REGEX_SEPARATORS.split(string) + encoded = ".".join(fn(label) for label in labels) + return result + encoded + + +def to_unicode(obj: str) -> str: + def mapping(obj: str) -> str: + if obj.startswith("xn--"): + return decode(obj[4:].lower()) + return obj + + return map_domain(obj, mapping) + + +def to_ascii(obj: str) -> str: + def mapping(obj: str) -> str: + if REGEX_NON_ASCII.search(obj): + return "xn--" + encode(obj) + return obj + + return map_domain(obj, mapping) diff --git a/.venv/Lib/site-packages/markdown_it/cli/__init__.py b/.venv/Lib/site-packages/markdown_it/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/markdown_it/cli/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/cli/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94bc7819b0dae8d4952e8c0247900e3974975de8 GIT binary patch literal 212 zcmX@j%ge<81YUhM86f&Gh(HIQS%4zb87dhx8U0o=6fpsLpFwJV6+2tSgche36~_c8 z=Ek_B7H5~_7sLc-rlcwa6y;~7CYKb)xFr^sI0kqsloczu7&-6`tiT$>s7_lx+Q2iPx6nn5slY`6*mSRx0bKQew+)q!f`XgIIG{7Aca; z%r0eOQtrs)0A!VbY1=1dRVdJ6g*R+en zHlN|Ad8mbqkabVHvz}>Bb=*7cg>iRA%=)H%Y|N99vi@m5w7uz8=ZJc(`R;OdZ#t+( z)CN_&>Yfg%QPp=ms60Mt?F2cd4%n$*zzF+%7u7tunRH{Ds^ z*=ea^m2V@pQ}zR=Hyw9o>$SGu;o(S;FY>YdC0!akJtn7erbcI#q$ZoXoK@(&s$b4^ zr_AnrQIgIn)X-!-2Y)JOb*j}kMjPmiL<8l&Z<+sGio6rZF?380NsaF?qp| zM>2{rKQpQ%=QS!1>1ll?zM$n6W=^Lr&KN0E>xRAOl}nm2<7hOIGJBGlR1Xt3o-bNL zR!QY(1deZnzwt7VWwI4%TYGgqA}^0^dLtX&wy(TxTVi-yfM=Bl?2=4I2 z*K|F&=?`qfDzfKh1Q=j91Mr5MStLW`LXeOpZr2@gbq!w+3#3TyaN~f4Kvic6RAbCV z(bO%mrc+x}Gz_B@Y~LpB&@h^SER%1Vo?8*O#HQ7EAB)d_$CG`}(*~H>Bb^5Zm~=yc zn48462RZ01RQ{fD7rz0@YbZ4$jTPtq(>3%sGYm&HoYY6170%Z#xlErkyXaEg_dIv2 z_(U&*zk0vu?I69x;4Xvbnj#$hiry>y6uHcG5R>^p-029RuXDr4pPODz0Q3+2K zRa_*ui0b={v5%Bg|c>g=}6n z=fKkx%zR;wD>T@iYKm&PncuR!XD5bnPm4E-hUEbt21i)# z%M{GU60|ERGse?>xSXF&fKe&_hz6YI@CTp8U80N#%lv%{((n?=7X?%pvC*3iN|&eqX!1KQwRAkpGTU6CAEUUWQNhj45MzW z4v0B&i7Y`7UE+LTHj5l}sjeJ^)ER*Ak_((IN!LuJwkz4?YF!S1RG|b6PLCtkj{&67 zFj)aep9C=03`G@8G7jbob&MPr%VsN3BPTMTpuyfAF={+ zg!ahcb#_35EQ&P)@RcSdfJM~+3gE*b@&eAgWE=QSnCy}vY(mV%2uiiQra<6i>x$-_ zo|E4mK6e@dYB8hP!y_?QNr=be@+3C;`}^fdi<2n&JNg`ul1~~2tb&ci$74P#$iSVL z1E4drQSx8~fO#g0B@Uk*VW6iSxE_szB5*Astpmmz-qMN}b%m;9m@?2p9!$Uz!5f=e z&NLuWfK^(aJk_&#bFUeo=b=b2F)@A%WSQ(p#2vkQb~D_tJi6(REDvo;p^D4ri+
#s+*!ZMhSFN({$ z9t9459cTda@I{{(`$4iBM~{=w2l!Ks{DYH?K);M~K%X5REa2arRy-?_z;Iz!Lj^&1 z%74O}u+A>&8ls&MLLjtMZG$nFPjrG2hsnybR`^s&_1_CPJ2Sp# z*hk$GCP*w;YP0<{gNKaSBIG57EM9lK^p-vMe@PBYKav=z>;&k91du;cOEn=Gg}#%a z*r{nf=Tp4kiY~~Ox;`>V`-Ja=EcIDz6oKYWp@U5U?`*^C7C=vOr(NmF^u zt|2VuQyKk|6`s{;Rxx2oA_*y>QF3)JlziRY)x6pARvQpgJ$MCrj-CLt*{K!RS?V(K zS~4|T1g``E73YNutO=L z-#YNNav4%tN9s{nG~&o>1r$}qw3(sK@;grg!=w~p4*4IV7~Br#*R+}^+rby-8Pgy% zjGqHpCVvg?+Xx;h2ai--+`d;UqR?;v{7CzYYuyzRJjPXg4MAb&C}};k(b89L>D%dT z4SAMFDz6f^e?w?43(af7+Wh_4AI?7%njZ;2-4rBycvEa#d*$H^6BVAgTXrBYdoTr# zZur~F{`R%Wb^qaq!eKkn1UYI2lSHs}Zu@7@*zHMF?wN72=11-V=&?98#GvX3#I0Hk zg>;a_`0-NY{iVGIQtJJm?E}&sj0%>=#u7!P-XZLhY;||T07Wtjf8!t!cqjBPOs*ebVGS2hYQGUyv8&ad0-6 zu9*dzvv{z0;KVGq6m*`DjFY|zW0rv2z+fk72pAlur||&SuC{#`9m7fFC`BE(#>erI zhVQRfi{(uuR6UtUSW+S}TL1|(5E<@{&^Lfs;iR6)!21hq!-y*vlN7It;{DPWaNh4Y z0(fEBu#fB-iL+N03%Db=1eMDkUG@`(rI9R%GEAeAQE&J>1cC6exM2CvizOf*)+oNI z=uePfQqOM368o~cTF7Yq6rqM#F+KoN;W>``P7pZZ9}?j@z9r#5llV78`Wxx^6M6A3 zp&x97UM`1TzW@4q=#6Fnj>p3Vx1%oZ;I<@jP1|izF1p<*a~<0woQr#-A`v05Qu>N- u{W{XLI&t&e8}F_uYZq5%)+2}EsVD@N2Y)sCi_w*-$3k<(O@uZk-+ut5HZl(Y literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/cli/parse.py b/.venv/Lib/site-packages/markdown_it/cli/parse.py new file mode 100644 index 0000000..890d5de --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/cli/parse.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +""" +CLI interface to markdown-it-py + +Parse one or more markdown files, convert each to HTML, and print to stdout. +""" +from __future__ import annotations + +import argparse +from collections.abc import Iterable, Sequence +import sys + +from markdown_it import __version__ +from markdown_it.main import MarkdownIt + +version_str = "markdown-it-py [version {}]".format(__version__) + + +def main(args: Sequence[str] | None = None) -> int: + namespace = parse_args(args) + if namespace.filenames: + convert(namespace.filenames) + else: + interactive() + return 0 + + +def convert(filenames: Iterable[str]) -> None: + for filename in filenames: + convert_file(filename) + + +def convert_file(filename: str) -> None: + """ + Parse a Markdown file and dump the output to stdout. + """ + try: + with open(filename, "r", encoding="utf8", errors="ignore") as fin: + rendered = MarkdownIt().render(fin.read()) + print(rendered, end="") + except OSError: + sys.stderr.write(f'Cannot open file "{filename}".\n') + sys.exit(1) + + +def interactive() -> None: + """ + Parse user input, dump to stdout, rinse and repeat. + Python REPL style. + """ + print_heading() + contents = [] + more = False + while True: + try: + prompt, more = ("... ", True) if more else (">>> ", True) + contents.append(input(prompt) + "\n") + except EOFError: + print("\n" + MarkdownIt().render("\n".join(contents)), end="") + more = False + contents = [] + except KeyboardInterrupt: + print("\nExiting.") + break + + +def parse_args(args: Sequence[str] | None) -> argparse.Namespace: + """Parse input CLI arguments.""" + parser = argparse.ArgumentParser( + description="Parse one or more markdown files, " + "convert each to HTML, and print to stdout", + # NOTE: Remember to update README.md w/ the output of `markdown-it -h` + epilog=( + f""" +Interactive: + + $ markdown-it + markdown-it-py [version {__version__}] (interactive) + Type Ctrl-D to complete input, or Ctrl-C to exit. + >>> # Example + ... > markdown *input* + ... +

Example

+
+

markdown input

+
+ +Batch: + + $ markdown-it README.md README.footer.md > index.html +""" + ), + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument("-v", "--version", action="version", version=version_str) + parser.add_argument( + "filenames", nargs="*", help="specify an optional list of files to convert" + ) + return parser.parse_args(args) + + +def print_heading() -> None: + print("{} (interactive)".format(version_str)) + print("Type Ctrl-D to complete input, or Ctrl-C to exit.") + + +if __name__ == "__main__": + exit_code = main(sys.argv[1:]) + sys.exit(exit_code) diff --git a/.venv/Lib/site-packages/markdown_it/common/__init__.py b/.venv/Lib/site-packages/markdown_it/common/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.venv/Lib/site-packages/markdown_it/common/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/common/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4198e9b2cea26537a4ba290a9dbc4854ddc03a78 GIT binary patch literal 215 zcmX@j%ge<81YUhM86f&Gh(HIQS%4zb87dhx8U0o=6fpsLpFwJVl{s6*gche36~_c8 z=Ek_B7H5~_7sLc-rlcwa6y;~7CYKb)xFr^sI0kqsloczu&1Hiwbt*s zDWWokUvD+M0uOrNA^aXByg{$A3wGY|*?80eHoYsZYo;dAur*m$1Cr;;$ rePW&Pr_J&1v)yC!Y;NJ0Pv)+Fayp;w?vv{8GrKEFy4$;j%`4@<@THs^ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/common/__pycache__/html_blocks.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/common/__pycache__/html_blocks.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb49476d4f04bb69b4cfb16fae7ca9c0e8aa0b0a GIT binary patch literal 799 zcmX|9&2H2%5Kg?i*=VZ@cmqqED$!l>d#I{bsHFl_P^F4X6)E!CPU5a(2isY++;{=5 z+z}U^g*TWhF97t$iSY)o^nLka&x~ir^KEx`mf(8%@v!+aN|NvK=iefK#m#LLpAwN= zC3Paw&*@dVA$z0u;avGZZAI5iD?yvkYP!^xuRJxZmHr-OoLeW9scEp3+qSi)Wo|`% zC;6-ip*vVCuIqMQtI+hzxw4CstQDL{r z;v3QnXRk3KUz{-?o?g75YfsNK^Q+=HMwgDB+G|_P*V3$ubG0ly*1X^05v!#y;&ci7 z&Xg)FhIw1W9+t!K%)1TbhpiR8mPhUxW|AWO9i$(lG);dJl8%4n$G6Cb9e0Aee*juG BC;R{a literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/common/__pycache__/html_re.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/common/__pycache__/html_re.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..220a5f841b1c7c491b7423dce82a82780992d5c6 GIT binary patch literal 1361 zcmZ`%OKjs*6t&|xj(_=e`U?ysEmfOT>1SZU6gQztJ2M@1+Nv!Qa-M5kzo#~B5(nEU z9cva|!UotetSGxdY`SDQOC&a9v5CBj#Axu5fXzlkD8V0-+v zbn+ub5Pt;0jYWsx`U8?6z9S$Z6Oe?F1}T$}k|QuGQ;?RUFecNGL6n2bVLb3C`Y%j} zm<_xfgB*&4F&}so3$YO97$_npj1yrThe?@*DVc+5nTHu!fFrUPArN``Hg5fo!8<5a z9_oi`L(GLU-|Q}>8FvxsPpa~Iz|_5 zD`y+Ire^CWxf8qD$e{*mqLyuOuLG@ZCtK4>&RR)USCk=ID&1dMP)kbD8L1sk&8|x2 z&%njfQVCq#TT+pRaSiRnNJp+7>2-_cerpZt^%v*P=!jt z8JB8U1WPHy6{~PN`Zyh&~dJ{sUbM#Nhg)Qe=qcd!;A9ZZpZnRNL zwY6iP)ft}Q?u(v%cpgy*_s~|w(AY#^N$XmY^eup z57oU5e>@C!b~m=w>ekNwM#%3U?D=E2CH6LcBCdm{|FctF0iRgN#8;&?!8)?eY@-eK z>k#F3P2&{lwgnz&mc6#SnLD>~4;q?v1|Dhp88UP0#;E}o&Qa?eY}Jo|Rku;8jZ@k& zvOrTa&!F)|ORd|B!O@J?V(|4;6D_o#`f;ggz)k~|%`DzU@aHWF`#wdI56%m>n5gLz8jx&>0V;u z%cE~jzdG$kxo#{mph!B|i?IVbLUa8X!K4NZMW_04g5d^i6muNGBnCW9C;CFbi80J2 z2qry9GIYA13b=F}a~Xok3`STw)4vmNqa5bO2u2u;^R&>P2)Ids=B}wkGUD?6cZj$0 wmmhlB`4_sEUB24%va2sCFI#;@jCUuepJ#r^exH5y-bcSrN**z0PT*Vo3)nApa{vGU literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/common/__pycache__/normalize_url.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/common/__pycache__/normalize_url.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03a1d593290abd5c00215cfddb4f1dd77d90cd22 GIT binary patch literal 3324 zcmeHJ&2JmW6`$qz$5Nt9OLgox-qa3kHWnSHZi}#rZHc0y6t1XM_2Ab=g9XmT~|L;rvt?DUWTxk#V`x!VRUkmit^0i`gIQ{U`zMcHwC zYHuBa^WMDo=FP{x-+S|EA`wH-e)8+FdIY#H*uZOkm*I9k0_GZ$k<6(`-6(x-C#Cg+aIsefz3@7nB_2j!%kcq>>QUJay&zG73;oE?{R z-JlXx4BdiZBqyn=R8=wKt)^)bY*{nufF1l<)1cT6H+7eZG>K|T#KLwAxTfy#U-?|8 zQPFJbt2IN$X@5Idr_{{0LyTD2c36`Xl^WSvZ}ZL(LeRq%b31L2UPE+O*I*tWX&t!y zTfUn;&1J5`H3E;Az>r{&Grx~CvhVS78u1KUh`dDO-iY!Z=UwFw5Qo6WpeOHBI^^+< zeID1RkKd=~^_Jh`E^~5#{k#)$d+%d^-=D|rxvddT)~6lL^Xt(fI*Lvsi(B?_=yf;? zhpwJp@xP9ixpc7InlXqbsY)9QGPbCqJE0+5oV#ENiY};%zGTH>0<>(_rHr44n8E6$ zEU?;hLFT!-LNQ#BaG^jhG){e9n@q9 zH#_Kr8%e@3?TASXYSawXPR-?Wg~_})T_~1j#($a@rwVf<$ZVqdl^Ql#klPWFU{jT9 zn6OW5N2no6R!vdt5Y}15+Mxw@1N4T^_Oqoz&Qh|)!c7pq`FSo|xoBZxRf>{UnZ(u- zHOxv;k+CpKj0Ubzt1=~7bbR(@p=AkEaHOTmv{YNdM3^)hMkUk2daH6lsa7n7;!zV+ z(jvAhnnadlV_6p!da7n#Yyg-e0@>e17Xl{vV0q_ms~P!oA@` z*Tmn7x0LP7`K`?P+an(zxpSnOdF3}^cX;ldsRw>E@buRq#1CzZT^ajb@B{vR{=-+h z2Tpe5qnm-z2VqceCWLP+29rBO&rO{6e{?!Hkqti{-@pGqzR~{*-xR)p+ZqQvu21D) z8wOrZc}xz-^>RR{UF_!osYwlnd7)!0a__KYSzu9jtz)1p@CoEiNZ0?zK zg0NgkSekTTOj3+v+08*L8D< zmZ+4@f(c`?iU!G~a_YpQvd}U0#ZJS-i=Aa$HPb(??JcD&D>?=DkHB1ma`uae5Bd(e z*(<$8)Ip8iG7Lt&cC$wty%&)uXVlYOMs&9zH^O@@T)w{wd5T6oJ#}7RZ1kV!^miz8 zMU?hQJZ$q-C|Pg;m=!9gNC}E1z*ELp#xkp0Mw6ONnsLLoR0n0tona86Cg}pykh)S; zsGu1H3$zX*f?@uupkpk94{Cr7hTKhs*NVlA6Vor##A@wJs|_h8L{5(NtvtYqSKR( zKfI!_%DgDRZWO9u3p}zlWp`VpbjS``6hg!fvI`(KKQTTj&dwD|1#vEKhb%0STHOv* z4JexYONGLuI5}P#2VL4n4#5Yoqr12B5Q_Mo7(3->6fCFUZ_Prtj##l7+6+JW=fMNl zQ}4dH8996}me@#NNx%E-cI?nr>`*s$cs=*m(HFKy&u@*Mzn!`}n!kGHJ$^fRbSruE z!(2Ccq8m>G5I#8r-46If>43W(Kb*!65lovzC#RT#n@NWpoiijSLDqiKd%MohgZ-tG z0z2O&p(D%~IwsG73HctIJ7UK~aiIy$uqYB1$MzsRA5^H_>=m4msx`vm*N!ow@^`#FyL9DVmobnJ6<{<>8$)OuBP(- literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/common/__pycache__/utils.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/common/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..425530bf72b8ea9703bd1a8fae15b5c499eaa9c2 GIT binary patch literal 10095 zcmcIqT~J%emA+RJe-b}3_}>^`evB<6KtD)An6WK%bz^31#$y;KV}u!5_hMuViRpW> zjSRD7HnqV!*&RHSU6W+1LUtZv*Q6@*xLfu8%;sS)rLX@^pFZ7v`t<2;{P&p9O@a>fv{3-Q!5cxp`P`2{ia}Bp<0FfhOP8w>@!GA z-*xAnHLHtK?Aw#3=4-gus&3T@`Rdembsxh0YVGv{dvdGO4&)${x}UJv`a#q^fVzj& z4)q|y!+X|0RIGCZbq<5}sM@I>L3m8{s7Ddjj|=LtPsQuURj*o)bi0=wEO7%thqS)Eqm5&`P#ZC)h_iU+HXbJityC5)fLD! zy=|n@DI=xn(pZ*BlL@A$GPfi>JH?WkWN7yd`#Md$OUyeGnM~G57^!SVA8=XnC6^OM zay(x)G(D+ZOR#lPLXeef8G|!S7IcQH3#9v2K@d02A@UenY7}%<5N3oK@d$D^M{rPR z7K~!u7J*qs;T>UGyeHhZz9ZZdpIQ=jRJKd_u4={<%jl9Zu1RlaQpv2UNp}i-Is>IF{iO?`^|(7 zVl%VARMqqpLuQeA2j|ewn`D}l(xpsxt8{16oSR!3NDL4ytt5fX)q<} zD?Qp1e_Pj>9v@6h#AQvtV`L}egDH&J6_&lNB@I2UBy=NkrC++MOG-MS--%yLB=2DK zVpT(mN)n^L84f zDCQ+%Fel`2;HRGg%n2`QttI=P*VHcf7xYKnAI>h9*Z#X^*(SAdl7`m2(`WL_Aa%e%;V@R!v zGvZNU#zLly`k?Zdiag306kOKay@JM1WbbN{mewY)(4;YzosbfYC8niBMwKR~41`%M z2PnLmOKP9hH3^D1M)r=D(M|PYr4ZpML||2j zuxdcwk@acKiny(q zTe2;;GzVU4>7CP%p&V3Zx{T6=dgaA>72E3Bw^2BX6qVa3s*1VQ+j48}$R_7$r)%Fp zN>~$w)E|B&2uf=CzY+aUf1hx@{m%h&!k1;`^U4Pg7T#M_K7O!Pv;WofT7`Z7 z+QXxZrN1a|SbFQp!Jl0JT=_*yPk~bYV0z)L#g>oXL3$0Gklu>DT2f3?8{Hqw5T&Dr z9flk)O(&@fpH3=y{L)VFSz+3t@M7-YqS?${jTsVbTPl-COGZ|jGL3w}R1Rbf%?;bk zEqj)wZgH~L6L%AOlBFi0`uDPuZZO)?ipCnoRfCac+Iv%E#ob)VO)INvli5_p(4};O z-NF(w#uFLoUC(_5-@E3*>B9=U!fmhQmy#%E+9cC-T8oLy^rn2U*acoBT{fd_HE*)P zMrlosGbUjOwohmkEohp@DXQ7=8D_%^9Z4*Jv{Qj>-KwR zU1xJu&8LS88Qrt4+`i`fL^-yV^^(mkfhc_XS}|EzjiP}J^SdjsimjBntq;Ps&04lL z^xIVbm2XDeocR0Vtd-RpWt#*u*4t#MU-?waCcSFibdF{%8K1$OZzBFbv~uiEXvMbG z%8cdP2MwAI{>>C6VGe`#j#qLAVa=h;CAk}$%6xI?@+FD;NYik)47es4-PA!{)1-03 znACeZJIPJyF!xg0T|2VuR;Q=K@9AtdtF|+33|gE?YTJ$UI`w~@wpmv>qcO}Mmixca zKNPt%8XFkuA9`oBFESYOdPc9t@)fZE=?U(_S)pqAl3Of0HMx6*AS!Uf!WGhG%a@oH zZJES`mba0z!_!C@x(#h&Cn#8_{a72c3z*jFirHD_1Io2 znnR1Whwm?!AOG^uu{rs9b?dWg&q}rD^Zl#U!R4~xoDSgr!sGCx@Zwva^e)w|*0emd zJ$Igd=Jc&NeV=!&I=h!Ey65WvJ1OUFUzRzR%MN`}-~L4XqTc_!rhai~wWevgyy;7a zbMDekQ$_vZy8b#MII`JP@jJFz?9Ma7U6GZl*mV#hH7IQ9{cSREuY5D&jIgOgqz?lx zSww24j=bX!5TOn3cEJvA=b{!D$t;`&G%AvE?MhixN-VshFuT)!R%il>Oj{8?ayAC| zp1)2xE(@dWn@<~DfDXj-WtyH$OloSr)YQh8J%Fmhw6oE%sZ280G?g*QBk6QUFL~W* z{anXOG z=^HbgEO%EF$vBBUg*StLt8;nM- z#6}~RF40o3>Qgt7Uuy0Yted2vu5aqGV_Of{1r$sXg$FPvY*Bj`XNh|;1dhVM zL@!3JGCHa~71?>pDz)K_6%L(sHZ1WtR7%!QIK%@+nixx6?rXD{>dFnx;$Q=SBD)+uVny)+V>q z)Jt%#iM!pWnof~(LZ-c4PmF1j4(Ea!=ML6`Zstl_6BCnX^I~t#)|xgDIfuwCiZta) zTi=_?8fW1Vlob{QIR`9pZ~LIz%{jYhOr+Tx;P@eadOrXLv{Z0Zf7JG{Z6UcBTD3RN zMc3?Ag>-P$-t@=P-K+K%lsl^DUN=>@cKoEJ{7w=Hix{Jx4J)LO-NZx-FO!o>v`zR@Jyt z)wtC9q;<8*JEyEU_7xnXmqaE#;%kO>NAvh_my41+9Ua$_ccj$V*7S1EjZWnW>E1X_ zxjIg{T8GQBPHxD$1SojojMo2lLCaG5AQ7`c6#P9Enoir7j+%wuWygtS+lig4VQ<-* zcad$USb4D`FG`z-150vzyF_+KWH3{xcOcMDw+mIZaBSI8zig}LLY;G@A8d0d^m39Ipz4T|6aiJF9IOE^?Lt3^;d^8d_;XDmDwl|+_ zkDqb3lS3Upe<42H9v>NvKZwu9??=4&h4AZ(-|q|Jhj<^wmH3p$ABqunhk$`Vq@4#; z5a;wISfeUH3y?I5r;A!pygrUZs`$B3ik~%!{QCb`iL|bLrdO}A1whPxi=(}R0zyOx0#>@yZP`S zphUO}@&c)1#7o>GG_2l8go_Y~Q1wWJSC2%fkv=}J-o7A-)u%*>ai2nUqJAz*)Xx*7 z3f^dl$D^ECGzz`&MrBO1&*P;mpT~zRpNCJ2&(p2w1z4pnZG`<)gRA0j}rL2TeNyh3eP(WB&4k{+OkI16|474m$t1|Di91BpN5ui76jFx~LQ_L&{>L)9H z(j^3(b=XXVqlFgy#8e4TR}q8@xm~=eE;43vvR2_D|9Z%dHac7%uiE-TEs6FCfkUBYQ@65kFkia zP%C6g#9N7y1(Tz+7J)PhFt~WxtF*2(_bE1fm;^zYm^`S)9 zCUqaD4)Zd|X7ZrLBS*ugO89wKV%;W5cb`e(=gr8p;mC48dD*dqhh}*q3bg{SIN1Y_W`@RZ}jd#zVa)MnwSVXuHqrPFT7<(AI4r8c+Zc1!JUslzRGx}_es zbk;5Px~13L(mA(u-Ys2lOT%s{?v_T}(havX>XzPhOAp-Aj9Z#@ zJ(@Sr*^DdVRH}WO=RV8j*fRz zyrmEyo$h^k6B0{gZfS+VfZtjTzm*T0sdYP4tvaP&RwE=F*Esfoitwg=)VteE40gn>}Lha&uCTR<7aUA#IJsvbh};B zZkEw~Qm*-;mc|oP;R=6jS{g21U}ETQYH59>0|!IBja@?`I2-N z*Y^36sY$TeaY(GqWZ48BLUP*G&3jR{07m$?3PJBe1b64S$cHHS#5#E5Fg37(N%*M=*CKW9h^# zow7O;asAA>mzGZPUYr)>_M!ipyYHeY+car|xOEwDS@X7=*=#yrd8vQkjnOx+#0KaR zb_~3C^d9HDOR3DAHz&0WqgxePq6Oph94DK~XU^soXY-P>>TFwexR-5i-n0KN;n^n; z0XK!;N06`L(nl}7IT+hhd>B^}KbpofCHnztz4o&FRnMF)E6$dsYpYK8s-u0`*3RX3 zm74F7WC{7BBx|D>S;w#JxY3qoqyfCV{82LK)+Sjw=k`@qI;9)Kg*V%gZG3SS7TDiy zw!mY!Yiy*9V!OQ0J99}wh(TtYacRkxn=z7>$54xG_|Dwdcg>|ulF?-d@9$>2-=d5k zy_(BucgV!T8x;0=Py1ax7J_TqI1Jj zCf35_*BxJIdVJ>5nKj$BHCyR-FMs>;Mv1k~GFOAwlls<0-;aBK(6ihcTs;JTU%!a*8tU=@Z8y0+zdmi;HH*~Gm1(pRTmDX-JEuyqxw}{7oXRq96 znXB4pu!)T?YK!DAEJDfc;~Q4Xehby9w21!S*&AyubJZIc#Y)s|@Q6(>#zet+be?^b zdzf2ndvf*XBTq-Zs5v`Vx#m2&V0mnRWM4e{>_r=;qS*fXa#8HyGxER3 Ckx)zk literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/common/entities.py b/.venv/Lib/site-packages/markdown_it/common/entities.py new file mode 100644 index 0000000..6bb2d34 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/common/entities.py @@ -0,0 +1,4 @@ +"""HTML5 entities map: { name -> characters }.""" +import html.entities + +entities = {name.rstrip(";"): chars for name, chars in html.entities.html5.items()} diff --git a/.venv/Lib/site-packages/markdown_it/common/html_blocks.py b/.venv/Lib/site-packages/markdown_it/common/html_blocks.py new file mode 100644 index 0000000..8b199af --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/common/html_blocks.py @@ -0,0 +1,68 @@ +"""List of valid html blocks names, according to commonmark spec +http://jgm.github.io/CommonMark/spec.html#html-blocks +""" + +block_names = [ + "address", + "article", + "aside", + "base", + "basefont", + "blockquote", + "body", + "caption", + "center", + "col", + "colgroup", + "dd", + "details", + "dialog", + "dir", + "div", + "dl", + "dt", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hr", + "html", + "iframe", + "legend", + "li", + "link", + "main", + "menu", + "menuitem", + "nav", + "noframes", + "ol", + "optgroup", + "option", + "p", + "param", + "section", + "source", + "summary", + "table", + "tbody", + "td", + "tfoot", + "th", + "thead", + "title", + "tr", + "track", + "ul", +] diff --git a/.venv/Lib/site-packages/markdown_it/common/html_re.py b/.venv/Lib/site-packages/markdown_it/common/html_re.py new file mode 100644 index 0000000..f0c336d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/common/html_re.py @@ -0,0 +1,40 @@ +"""Regexps to match html elements +""" + +import re + +attr_name = "[a-zA-Z_:][a-zA-Z0-9:._-]*" + +unquoted = "[^\"'=<>`\\x00-\\x20]+" +single_quoted = "'[^']*'" +double_quoted = '"[^"]*"' + +attr_value = "(?:" + unquoted + "|" + single_quoted + "|" + double_quoted + ")" + +attribute = "(?:\\s+" + attr_name + "(?:\\s*=\\s*" + attr_value + ")?)" + +open_tag = "<[A-Za-z][A-Za-z0-9\\-]*" + attribute + "*\\s*\\/?>" + +close_tag = "<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>" +comment = "|" +processing = "<[?][\\s\\S]*?[?]>" +declaration = "]*>" +cdata = "" + +HTML_TAG_RE = re.compile( + "^(?:" + + open_tag + + "|" + + close_tag + + "|" + + comment + + "|" + + processing + + "|" + + declaration + + "|" + + cdata + + ")" +) +HTML_OPEN_CLOSE_TAG_STR = "^(?:" + open_tag + "|" + close_tag + ")" +HTML_OPEN_CLOSE_TAG_RE = re.compile(HTML_OPEN_CLOSE_TAG_STR) diff --git a/.venv/Lib/site-packages/markdown_it/common/normalize_url.py b/.venv/Lib/site-packages/markdown_it/common/normalize_url.py new file mode 100644 index 0000000..92720b3 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/common/normalize_url.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +from collections.abc import Callable +from contextlib import suppress +import re +from urllib.parse import quote, unquote, urlparse, urlunparse # noqa: F401 + +import mdurl + +from .. import _punycode + +RECODE_HOSTNAME_FOR = ("http:", "https:", "mailto:") + + +def normalizeLink(url: str) -> str: + """Normalize destination URLs in links + + :: + + [label]: destination 'title' + ^^^^^^^^^^^ + """ + parsed = mdurl.parse(url, slashes_denote_host=True) + + # Encode hostnames in urls like: + # `http://host/`, `https://host/`, `mailto:user@host`, `//host/` + # + # We don't encode unknown schemas, because it's likely that we encode + # something we shouldn't (e.g. `skype:name` treated as `skype:host`) + # + if parsed.hostname and ( + not parsed.protocol or parsed.protocol in RECODE_HOSTNAME_FOR + ): + with suppress(Exception): + parsed = parsed._replace(hostname=_punycode.to_ascii(parsed.hostname)) + + return mdurl.encode(mdurl.format(parsed)) + + +def normalizeLinkText(url: str) -> str: + """Normalize autolink content + + :: + + + ~~~~~~~~~~~ + """ + parsed = mdurl.parse(url, slashes_denote_host=True) + + # Encode hostnames in urls like: + # `http://host/`, `https://host/`, `mailto:user@host`, `//host/` + # + # We don't encode unknown schemas, because it's likely that we encode + # something we shouldn't (e.g. `skype:name` treated as `skype:host`) + # + if parsed.hostname and ( + not parsed.protocol or parsed.protocol in RECODE_HOSTNAME_FOR + ): + with suppress(Exception): + parsed = parsed._replace(hostname=_punycode.to_unicode(parsed.hostname)) + + # add '%' to exclude list because of https://github.com/markdown-it/markdown-it/issues/720 + return mdurl.decode(mdurl.format(parsed), mdurl.DECODE_DEFAULT_CHARS + "%") + + +BAD_PROTO_RE = re.compile(r"^(vbscript|javascript|file|data):") +GOOD_DATA_RE = re.compile(r"^data:image\/(gif|png|jpeg|webp);") + + +def validateLink(url: str, validator: Callable[[str], bool] | None = None) -> bool: + """Validate URL link is allowed in output. + + This validator can prohibit more than really needed to prevent XSS. + It's a tradeoff to keep code simple and to be secure by default. + + Note: url should be normalized at this point, and existing entities decoded. + """ + if validator is not None: + return validator(url) + url = url.strip().lower() + return bool(GOOD_DATA_RE.search(url)) if BAD_PROTO_RE.search(url) else True diff --git a/.venv/Lib/site-packages/markdown_it/common/utils.py b/.venv/Lib/site-packages/markdown_it/common/utils.py new file mode 100644 index 0000000..0d11e3e --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/common/utils.py @@ -0,0 +1,318 @@ +"""Utilities for parsing source text +""" +from __future__ import annotations + +import re +from typing import Match, TypeVar + +from .entities import entities + + +def charCodeAt(src: str, pos: int) -> int | None: + """ + Returns the Unicode value of the character at the specified location. + + @param - index The zero-based index of the desired character. + If there is no character at the specified index, NaN is returned. + + This was added for compatibility with python + """ + try: + return ord(src[pos]) + except IndexError: + return None + + +def charStrAt(src: str, pos: int) -> str | None: + """ + Returns the Unicode value of the character at the specified location. + + @param - index The zero-based index of the desired character. + If there is no character at the specified index, NaN is returned. + + This was added for compatibility with python + """ + try: + return src[pos] + except IndexError: + return None + + +_ItemTV = TypeVar("_ItemTV") + + +def arrayReplaceAt( + src: list[_ItemTV], pos: int, newElements: list[_ItemTV] +) -> list[_ItemTV]: + """ + Remove element from array and put another array at those position. + Useful for some operations with tokens + """ + return src[:pos] + newElements + src[pos + 1 :] + + +def isValidEntityCode(c: int) -> bool: + # broken sequence + if c >= 0xD800 and c <= 0xDFFF: + return False + # never used + if c >= 0xFDD0 and c <= 0xFDEF: + return False + if ((c & 0xFFFF) == 0xFFFF) or ((c & 0xFFFF) == 0xFFFE): + return False + # control codes + if c >= 0x00 and c <= 0x08: + return False + if c == 0x0B: + return False + if c >= 0x0E and c <= 0x1F: + return False + if c >= 0x7F and c <= 0x9F: + return False + # out of range + if c > 0x10FFFF: + return False + return True + + +def fromCodePoint(c: int) -> str: + """Convert ordinal to unicode. + + Note, in the original Javascript two string characters were required, + for codepoints larger than `0xFFFF`. + But Python 3 can represent any unicode codepoint in one character. + """ + return chr(c) + + +# UNESCAPE_MD_RE = re.compile(r'\\([!"#$%&\'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])') +# ENTITY_RE_g = re.compile(r'&([a-z#][a-z0-9]{1,31})', re.IGNORECASE) +UNESCAPE_ALL_RE = re.compile( + r'\\([!"#$%&\'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])' + "|" + r"&([a-z#][a-z0-9]{1,31});", + re.IGNORECASE, +) +DIGITAL_ENTITY_BASE10_RE = re.compile(r"#([0-9]{1,8})") +DIGITAL_ENTITY_BASE16_RE = re.compile(r"#x([a-f0-9]{1,8})", re.IGNORECASE) + + +def replaceEntityPattern(match: str, name: str) -> str: + """Convert HTML entity patterns, + see https://spec.commonmark.org/0.30/#entity-references + """ + if name in entities: + return entities[name] + + code: None | int = None + if pat := DIGITAL_ENTITY_BASE10_RE.fullmatch(name): + code = int(pat.group(1), 10) + elif pat := DIGITAL_ENTITY_BASE16_RE.fullmatch(name): + code = int(pat.group(1), 16) + + if code is not None and isValidEntityCode(code): + return fromCodePoint(code) + + return match + + +def unescapeAll(string: str) -> str: + def replacer_func(match: Match[str]) -> str: + escaped = match.group(1) + if escaped: + return escaped + entity = match.group(2) + return replaceEntityPattern(match.group(), entity) + + if "\\" not in string and "&" not in string: + return string + return UNESCAPE_ALL_RE.sub(replacer_func, string) + + +ESCAPABLE = r"""\\!"#$%&'()*+,./:;<=>?@\[\]^`{}|_~-""" +ESCAPE_CHAR = re.compile(r"\\([" + ESCAPABLE + r"])") + + +def stripEscape(string: str) -> str: + """Strip escape \\ characters""" + return ESCAPE_CHAR.sub(r"\1", string) + + +def escapeHtml(raw: str) -> str: + """Replace special characters "&", "<", ">" and '"' to HTML-safe sequences.""" + # like html.escape, but without escaping single quotes + raw = raw.replace("&", "&") # Must be done first! + raw = raw.replace("<", "<") + raw = raw.replace(">", ">") + raw = raw.replace('"', """) + return raw + + +# ////////////////////////////////////////////////////////////////////////////// + +REGEXP_ESCAPE_RE = re.compile(r"[.?*+^$[\]\\(){}|-]") + + +def escapeRE(string: str) -> str: + string = REGEXP_ESCAPE_RE.sub("\\$&", string) + return string + + +# ////////////////////////////////////////////////////////////////////////////// + + +def isSpace(code: int | None) -> bool: + """Check if character code is a whitespace.""" + return code in (0x09, 0x20) + + +def isStrSpace(ch: str | None) -> bool: + """Check if character is a whitespace.""" + return ch in ("\t", " ") + + +MD_WHITESPACE = { + 0x09, # \t + 0x0A, # \n + 0x0B, # \v + 0x0C, # \f + 0x0D, # \r + 0x20, # space + 0xA0, + 0x1680, + 0x202F, + 0x205F, + 0x3000, +} + + +def isWhiteSpace(code: int) -> bool: + r"""Zs (unicode class) || [\t\f\v\r\n]""" + if code >= 0x2000 and code <= 0x200A: + return True + return code in MD_WHITESPACE + + +# ////////////////////////////////////////////////////////////////////////////// + +UNICODE_PUNCT_RE = re.compile( + r"[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166D\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4E\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDF3C-\uDF3E]|\uD806[\uDC3B\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8]|\uD809[\uDC70-\uDC74]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]" # noqa: E501 +) + + +# Currently without astral characters support. +def isPunctChar(ch: str) -> bool: + """Check if character is a punctuation character.""" + return UNICODE_PUNCT_RE.search(ch) is not None + + +MD_ASCII_PUNCT = { + 0x21, # /* ! */ + 0x22, # /* " */ + 0x23, # /* # */ + 0x24, # /* $ */ + 0x25, # /* % */ + 0x26, # /* & */ + 0x27, # /* ' */ + 0x28, # /* ( */ + 0x29, # /* ) */ + 0x2A, # /* * */ + 0x2B, # /* + */ + 0x2C, # /* , */ + 0x2D, # /* - */ + 0x2E, # /* . */ + 0x2F, # /* / */ + 0x3A, # /* : */ + 0x3B, # /* ; */ + 0x3C, # /* < */ + 0x3D, # /* = */ + 0x3E, # /* > */ + 0x3F, # /* ? */ + 0x40, # /* @ */ + 0x5B, # /* [ */ + 0x5C, # /* \ */ + 0x5D, # /* ] */ + 0x5E, # /* ^ */ + 0x5F, # /* _ */ + 0x60, # /* ` */ + 0x7B, # /* { */ + 0x7C, # /* | */ + 0x7D, # /* } */ + 0x7E, # /* ~ */ +} + + +def isMdAsciiPunct(ch: int) -> bool: + """Markdown ASCII punctuation characters. + + :: + + !, ", #, $, %, &, ', (, ), *, +, ,, -, ., /, :, ;, <, =, >, ?, @, [, \\, ], ^, _, `, {, |, }, or ~ + + See http://spec.commonmark.org/0.15/#ascii-punctuation-character + + Don't confuse with unicode punctuation !!! It lacks some chars in ascii range. + + """ # noqa: E501 + return ch in MD_ASCII_PUNCT + + +def normalizeReference(string: str) -> str: + """Helper to unify [reference labels].""" + # Trim and collapse whitespace + # + string = re.sub(r"\s+", " ", string.strip()) + + # In node v10 'ẞ'.toLowerCase() === 'Ṿ', which is presumed to be a bug + # fixed in v12 (couldn't find any details). + # + # So treat this one as a special case + # (remove this when node v10 is no longer supported). + # + # if ('ẞ'.toLowerCase() === 'Ṿ') { + # str = str.replace(/ẞ/g, 'ß') + # } + + # .toLowerCase().toUpperCase() should get rid of all differences + # between letter variants. + # + # Simple .toLowerCase() doesn't normalize 125 code points correctly, + # and .toUpperCase doesn't normalize 6 of them (list of exceptions: + # İ, ϴ, ẞ, Ω, K, Å - those are already uppercased, but have differently + # uppercased versions). + # + # Here's an example showing how it happens. Lets take greek letter omega: + # uppercase U+0398 (Θ), U+03f4 (ϴ) and lowercase U+03b8 (θ), U+03d1 (ϑ) + # + # Unicode entries: + # 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8 + # 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398 + # 03D1;GREEK THETA SYMBOL;Ll;0;L; 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398 + # 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L; 0398;;;;N;;;;03B8 + # + # Case-insensitive comparison should treat all of them as equivalent. + # + # But .toLowerCase() doesn't change ϑ (it's already lowercase), + # and .toUpperCase() doesn't change ϴ (already uppercase). + # + # Applying first lower then upper case normalizes any character: + # '\u0398\u03f4\u03b8\u03d1'.toLowerCase().toUpperCase() === '\u0398\u0398\u0398\u0398' + # + # Note: this is equivalent to unicode case folding; unicode normalization + # is a different step that is not required here. + # + # Final result should be uppercased, because it's later stored in an object + # (this avoid a conflict with Object.prototype members, + # most notably, `__proto__`) + # + return string.lower().upper() + + +LINK_OPEN_RE = re.compile(r"^\s]", flags=re.IGNORECASE) +LINK_CLOSE_RE = re.compile(r"^", flags=re.IGNORECASE) + + +def isLinkOpen(string: str) -> bool: + return bool(LINK_OPEN_RE.search(string)) + + +def isLinkClose(string: str) -> bool: + return bool(LINK_CLOSE_RE.search(string)) diff --git a/.venv/Lib/site-packages/markdown_it/helpers/__init__.py b/.venv/Lib/site-packages/markdown_it/helpers/__init__.py new file mode 100644 index 0000000..3dbbdd1 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/helpers/__init__.py @@ -0,0 +1,6 @@ +"""Functions for parsing Links +""" +__all__ = ("parseLinkLabel", "parseLinkDestination", "parseLinkTitle") +from .parse_link_destination import parseLinkDestination +from .parse_link_label import parseLinkLabel +from .parse_link_title import parseLinkTitle diff --git a/.venv/Lib/site-packages/markdown_it/helpers/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/helpers/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed2a8cebd4bd92c087334f36c81ab73a4add8a7d GIT binary patch literal 481 zcmY*V%Sr<=6iqs9rxYtLL|nL-?SQYPND;&`s1zwwH$xz#lc;erlOai4>dG&0>o@o< z{=q;+aOF;MCkQ6>oki|B_vD^?$X%<|1oj+Wx6j{geRSmeRKCFLrUf^Ef*4R3Lt3Gp zsAOL3L11xJRI^%Ko8g+MXMXHMFsXMWthiSue;%5K6I_5^OCuqZjP$eoxAERKI?+sN)F&CTQBxxe)aR51JtZ$#Vl;|~ zHoLupV5Eac5S^lZlB7%p9eE+q`iSKt)a3)DxnXOCmB<;>C?hJRa-3ssHqMzS?1~MH ydCm>S>&2vOv@=PEg6*hzo5THsUbfe>2O)f^Kv;cfMpyn6Y)!%HJy=z9R{Q{qwUE95 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_destination.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_destination.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25dcd43182914fd3f3a735e3fd4979246e5e148b GIT binary patch literal 2204 zcmZ`4OKcNY@V(u&cm0d)I6n|UMnnOlCWuefs*Px){2-zcg??1a)pqOMfblnP*J%@N zR2QX^32C*JDq%R8TM(D_Mo;a%7nEF9s~jSgi*H6jLh7mW-mcwH;7L1gX5P%a`Mue{ zB9S11HUHDZjo(Ft{-#7{NglF44ai-jqBK&m$`x>tOLIj&&11x&Ii&LINEIG&u5?;Z zeVR}8YkpOPPtt@%Ne!$EX>lc(3at(WuP8*siZ)p&WIbot=G}$%hk(3`G?d2R9jD?nuL|IgkQP?Bl+O|6tD0Ud z7!L)9E9V`)Qq~3O4E$z02+TJj1h-_){( zo|#p2WAe(S!t~97&dQrJNzlt1&N2;~h>2{M3&Es3E&|ur6$h zcA^h9$?hM3EodkD>%x!HK1k4#`H5y!NofHR4n|8#QIlmSD9gpNS}jmKEXzw(rQn?e zWLYni4PBN=91J`}q!%_4qrl$*wDFkN$`u9SmjqE zAcswCa(S>u7GJNi<~RMSz_d8icMSpM+UQU|c9vom;bzk(cRR_T?ZOuL0FAr~xQP#= zN1neRD|iA(^#euYW6QfqWVU;{wp~yCKufOon_s;q61=%c^&vZAH@c-aNB6xCVhXUE zaOq2iLj*eI20iXoz+GRC{m+*}FWYrv>}I=T_3QzU=fPHp*$tbbR|OHUKpy52>0~v` zBtpQ)o)0l5JqR^}s9vca-dr*T)0K5?P|bHb7GJK!n`&V4Py^bJZVm9kTE1GJRAhlb z3!xSrFfCfr79GB=3jjW8WdIV|39Tdr-%$XqhgvBBDbalzv`1Ob6WRxaK2$=V3ZaHl z5;;V1`XT`yQk${E(b~*zr0>obwb`d)+!}2h-w}^CN4CXLTME^eZcBCE?ulD-8^ztk zaAUEV-ASCPPutOiWo(%C;II{W9X_0Fp1JqA<^LtPJA86$;8)*c{9EAh)RWYQJHwNd zZ68U(7GMVUTw_hXsXP$3PHZR7*s+AQ^s{8~c5G-b9JS8ezF41XA4AbzYwk|5J&Ixj z^+;PnksgR37_r2SvEAsQ#%S~SPIR;`?1iHBiN^Wn`TG-gINtW7aLgLnc)u~y9J&7% zaNyiJzcJC6Y96~c*Sx-cq@%rsADq~Up4w8kqi5|{KP1P!+79=5I-qTRe0#n=V@LZe zva#w0;MxOL0|SdHdQy9x9Jb#^p&m=TGuD0=NfC>`W!lmHdc+pP7QVI0@Tc)3jnA4h zTgRUakMG1!*Jjt}?Zgmlm+g2TqhfTsWQXFlkJuDlNJ;Q_l+|*U&gX2oSS**ut46M% z6V_v_z1TFSJ?8MalEIpQ&_C{f1KW`%+$n#7jKKlzY5fBLZ60I%jN`EILPGf53%`g5 eo*@A3zG;kmn~64}`_?&kf9%nJ4nAjmcEP_kbrfX) literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_label.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/helpers/__pycache__/parse_link_label.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e79cbbe201842bdac0801f80cc0a002936eccea9 GIT binary patch literal 1448 zcmZ`(&2Jk;6rb^W*XvDO$Nk6$RA^%wkrisH9ykOQBt&C1RR}>Ym6{q^8_yVTyxz5D z)`moD;X@B`g-9$R**R405yU^ioeM3MSoRdrQ*Ma@7cTH-orE@+C+)oVesA8#ym_-f zrBWIKy8X?K%4i&+7eYCq(YG|8GTQM1@x@|dC-8R>#t!ZAx;(EE^lswCIbd&Q&jdI&PJ4X)rU4UaPg+gb@fLE_a}@J;y&R51aV0+JkI5>Z;R!-o5} zRKS(9xe!`chhQWB#eDPwbVm?IP(>ojnDs@}0sP7ewZWK0dqjQGW=d4*Xnu^Te*ERm zZQ$V%0R6wd;jbV0G8-N42Y2^Md|%2VLtWng8z{Fgju7I{mIvY0Fu(a2DZrf|W5-L6emAdFmg8=%TIZBjc_ zY9^~v7AES9Ho?rr`_fP7udhCQx9};aj2H4|t#Fg_s^``Vd5cheg}Ljr zi+YpmIossb!Y#7|A@!T?x?7lQQm0v1vepXR^61q%n9R>9FNn0n{lY0)-n9y~>yYAF zT|CXAc$&qi>bd$xcrF5$09z8TmAwY#iJRxY!_r1UI@7)tq|R^O>)dPSg3(NSVQ=hG zA9s`Og$IklXbN;Ky=`=i9onf zv9W7BF?X*%OTTrXpv-tb)7852Z<#lO%h?_I+hi~?b?_z{8T+@OU$pGu6{Mzu3zNP1 z?);W2{3b;4dm|UxA0NRf(XxSaFa(KWk+`K|F`RsDj1OZ9j{kWM;p>NrjxYA#K0v^}D@E+b PD-ruSfAYxNbY{Qf*l|7_NCKs9L7^^6BKk#JA*3iD1r#FM&`PzeuD0GyFkXAj%$kyD zLtVsS!$)gQ7*0M_p@TeY?9Bu40GTL@Ol%4^E(uwoBxXg71oR0q#aqafo(K_lRx)Kv zHWf=TRoI#(t!if9Eh($6$1?pJLl+G~t+ZVz7t?ORwXIl-31);amcML}ImfhS-LSt} zwrJj{ShKdB?|8wljuEtX4A2M2LRk!M2`0{preaE9MluCUUKLCkU}as*sG+KVX3?tc zK9)kkDTZRjp`i>8STq!=OG1TMZk3dm^Y|4@%#a9s?=&}LVh`zEvMB)8<>uJFV~`D? zF-gAGQAS!`Y%w@QM1|`y4kc>YtCY#7|N3_BEgICFy?8EtjiwiEgBEjVjeOA}>3QdhlbgO~m9OQN3SZ}F!L_C;Kr+@WnkyNk zXgc4N^@2Nd*|IBOVy41!ue03iJonR;^-$CGLb>4T`o>@^9Ij>fa0sbvlq_8jW4c~)%&N`c zxUOHV8g_@$2L^1%rMgZ=KrHg&06>osSI6BT3L~+DZ8`?WEffq+)z0lnl6;^Y$MRTX zXIc=8HzyIMTt;r+hbR6NBLil=}p4v@$p6(EU2T++j)ypaHnn7_ZpG@1%X zGW}4&txH*TrT16VGy}Z9m!Q2bvB^qK z01GQ_dK4Uleu*b)3qd?tTX>#G-TAV%xU0tewVOABPkwi{HrHhdhDLp5HU)ay-oCpGCW1mlMrS05hq7w?`A4yEB*3dWCcZ0s;x z=Yo-O|3Z)$s$aUDYpiZdkIJvU1o5Hzr(5T@7WO&v&Dn=*+v>9;GZ10@Xzn%hnF)Nn?9zKXEP)3luAx{ zy6P5eN_t<(DwY3YC>F{tPc%8i-q<9HK0`YlO`bDk2HseO&=28gix}e<0>;uG=$${6 h7#@3p;Al@|@NnbZHq6A~<_f=_M%d4%Ub087`EToc&bI&n literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/helpers/parse_link_destination.py b/.venv/Lib/site-packages/markdown_it/helpers/parse_link_destination.py new file mode 100644 index 0000000..f42b224 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/helpers/parse_link_destination.py @@ -0,0 +1,86 @@ +""" +Parse link destination +""" + +from ..common.utils import charCodeAt, unescapeAll + + +class _Result: + __slots__ = ("ok", "pos", "lines", "str") + + def __init__(self) -> None: + self.ok = False + self.pos = 0 + self.lines = 0 + self.str = "" + + +def parseLinkDestination(string: str, pos: int, maximum: int) -> _Result: + lines = 0 + start = pos + result = _Result() + + if charCodeAt(string, pos) == 0x3C: # /* < */ + pos += 1 + while pos < maximum: + code = charCodeAt(string, pos) + if code == 0x0A: # /* \n */) + return result + if code == 0x3C: # / * < * / + return result + if code == 0x3E: # /* > */) { + result.pos = pos + 1 + result.str = unescapeAll(string[start + 1 : pos]) + result.ok = True + return result + + if code == 0x5C and pos + 1 < maximum: # \ + pos += 2 + continue + + pos += 1 + + # no closing '>' + return result + + # this should be ... } else { ... branch + + level = 0 + while pos < maximum: + code = charCodeAt(string, pos) + + if code is None or code == 0x20: + break + + # ascii control characters + if code < 0x20 or code == 0x7F: + break + + if code == 0x5C and pos + 1 < maximum: + if charCodeAt(string, pos + 1) == 0x20: + break + pos += 2 + continue + + if code == 0x28: # /* ( */) + level += 1 + if level > 32: + return result + + if code == 0x29: # /* ) */) + if level == 0: + break + level -= 1 + + pos += 1 + + if start == pos: + return result + if level != 0: + return result + + result.str = unescapeAll(string[start:pos]) + result.lines = lines + result.pos = pos + result.ok = True + return result diff --git a/.venv/Lib/site-packages/markdown_it/helpers/parse_link_label.py b/.venv/Lib/site-packages/markdown_it/helpers/parse_link_label.py new file mode 100644 index 0000000..01c653c --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/helpers/parse_link_label.py @@ -0,0 +1,43 @@ +""" +Parse link label + +this function assumes that first character ("[") already matches +returns the end of the label + +""" +from markdown_it.rules_inline import StateInline + + +def parseLinkLabel(state: StateInline, start: int, disableNested: bool = False) -> int: + labelEnd = -1 + oldPos = state.pos + found = False + + state.pos = start + 1 + level = 1 + + while state.pos < state.posMax: + marker = state.src[state.pos] + if marker == "]": + level -= 1 + if level == 0: + found = True + break + + prevPos = state.pos + state.md.inline.skipToken(state) + if marker == "[": + if prevPos == state.pos - 1: + # increase level if we find text `[`, + # which is not a part of any token + level += 1 + elif disableNested: + state.pos = oldPos + return -1 + if found: + labelEnd = state.pos + + # restore old state + state.pos = oldPos + + return labelEnd diff --git a/.venv/Lib/site-packages/markdown_it/helpers/parse_link_title.py b/.venv/Lib/site-packages/markdown_it/helpers/parse_link_title.py new file mode 100644 index 0000000..8f58933 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/helpers/parse_link_title.py @@ -0,0 +1,60 @@ +"""Parse link title +""" +from ..common.utils import charCodeAt, unescapeAll + + +class _Result: + __slots__ = ("ok", "pos", "lines", "str") + + def __init__(self) -> None: + self.ok = False + self.pos = 0 + self.lines = 0 + self.str = "" + + def __str__(self) -> str: + return self.str + + +def parseLinkTitle(string: str, pos: int, maximum: int) -> _Result: + lines = 0 + start = pos + result = _Result() + + if pos >= maximum: + return result + + marker = charCodeAt(string, pos) + + # /* " */ /* ' */ /* ( */ + if marker != 0x22 and marker != 0x27 and marker != 0x28: + return result + + pos += 1 + + # if opening marker is "(", switch it to closing marker ")" + if marker == 0x28: + marker = 0x29 + + while pos < maximum: + code = charCodeAt(string, pos) + if code == marker: + title = string[start + 1 : pos] + title = unescapeAll(title) + result.pos = pos + 1 + result.lines = lines + result.str = title + result.ok = True + return result + elif code == 0x28 and marker == 0x29: # /* ( */ /* ) */ + return result + elif code == 0x0A: + lines += 1 + elif code == 0x5C and pos + 1 < maximum: # /* \ */ + pos += 1 + if charCodeAt(string, pos) == 0x0A: + lines += 1 + + pos += 1 + + return result diff --git a/.venv/Lib/site-packages/markdown_it/main.py b/.venv/Lib/site-packages/markdown_it/main.py new file mode 100644 index 0000000..bb294a9 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/main.py @@ -0,0 +1,355 @@ +from __future__ import annotations + +from collections.abc import Callable, Generator, Iterable, Mapping, MutableMapping +from contextlib import contextmanager +from typing import Any, Literal, overload + +from . import helpers, presets +from .common import normalize_url, utils +from .parser_block import ParserBlock +from .parser_core import ParserCore +from .parser_inline import ParserInline +from .renderer import RendererHTML, RendererProtocol +from .rules_core.state_core import StateCore +from .token import Token +from .utils import EnvType, OptionsDict, OptionsType, PresetType + +try: + import linkify_it +except ModuleNotFoundError: + linkify_it = None + + +_PRESETS: dict[str, PresetType] = { + "default": presets.default.make(), + "js-default": presets.js_default.make(), + "zero": presets.zero.make(), + "commonmark": presets.commonmark.make(), + "gfm-like": presets.gfm_like.make(), +} + + +class MarkdownIt: + def __init__( + self, + config: str | PresetType = "commonmark", + options_update: Mapping[str, Any] | None = None, + *, + renderer_cls: Callable[[MarkdownIt], RendererProtocol] = RendererHTML, + ): + """Main parser class + + :param config: name of configuration to load or a pre-defined dictionary + :param options_update: dictionary that will be merged into ``config["options"]`` + :param renderer_cls: the class to load as the renderer: + ``self.renderer = renderer_cls(self) + """ + # add modules + self.utils = utils + self.helpers = helpers + + # initialise classes + self.inline = ParserInline() + self.block = ParserBlock() + self.core = ParserCore() + self.renderer = renderer_cls(self) + self.linkify = linkify_it.LinkifyIt() if linkify_it else None + + # set the configuration + if options_update and not isinstance(options_update, Mapping): + # catch signature change where renderer_cls was not used as a key-word + raise TypeError( + f"options_update should be a mapping: {options_update}" + "\n(Perhaps you intended this to be the renderer_cls?)" + ) + self.configure(config, options_update=options_update) + + def __repr__(self) -> str: + return f"{self.__class__.__module__}.{self.__class__.__name__}()" + + @overload + def __getitem__(self, name: Literal["inline"]) -> ParserInline: + ... + + @overload + def __getitem__(self, name: Literal["block"]) -> ParserBlock: + ... + + @overload + def __getitem__(self, name: Literal["core"]) -> ParserCore: + ... + + @overload + def __getitem__(self, name: Literal["renderer"]) -> RendererProtocol: + ... + + @overload + def __getitem__(self, name: str) -> Any: + ... + + def __getitem__(self, name: str) -> Any: + return { + "inline": self.inline, + "block": self.block, + "core": self.core, + "renderer": self.renderer, + }[name] + + def set(self, options: OptionsType) -> None: + """Set parser options (in the same format as in constructor). + Probably, you will never need it, but you can change options after constructor call. + + __Note:__ To achieve the best possible performance, don't modify a + `markdown-it` instance options on the fly. If you need multiple configurations + it's best to create multiple instances and initialize each with separate config. + """ + self.options = OptionsDict(options) + + def configure( + self, presets: str | PresetType, options_update: Mapping[str, Any] | None = None + ) -> MarkdownIt: + """Batch load of all options and component settings. + This is an internal method, and you probably will not need it. + But if you will - see available presets and data structure + [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets) + + We strongly recommend to use presets instead of direct config loads. + That will give better compatibility with next versions. + """ + if isinstance(presets, str): + if presets not in _PRESETS: + raise KeyError(f"Wrong `markdown-it` preset '{presets}', check name") + config = _PRESETS[presets] + else: + config = presets + + if not config: + raise ValueError("Wrong `markdown-it` config, can't be empty") + + options = config.get("options", {}) or {} + if options_update: + options = {**options, **options_update} # type: ignore + + self.set(options) # type: ignore + + if "components" in config: + for name, component in config["components"].items(): + rules = component.get("rules", None) + if rules: + self[name].ruler.enableOnly(rules) + rules2 = component.get("rules2", None) + if rules2: + self[name].ruler2.enableOnly(rules2) + + return self + + def get_all_rules(self) -> dict[str, list[str]]: + """Return the names of all active rules.""" + rules = { + chain: self[chain].ruler.get_all_rules() + for chain in ["core", "block", "inline"] + } + rules["inline2"] = self.inline.ruler2.get_all_rules() + return rules + + def get_active_rules(self) -> dict[str, list[str]]: + """Return the names of all active rules.""" + rules = { + chain: self[chain].ruler.get_active_rules() + for chain in ["core", "block", "inline"] + } + rules["inline2"] = self.inline.ruler2.get_active_rules() + return rules + + def enable( + self, names: str | Iterable[str], ignoreInvalid: bool = False + ) -> MarkdownIt: + """Enable list or rules. (chainable) + + :param names: rule name or list of rule names to enable. + :param ignoreInvalid: set `true` to ignore errors when rule not found. + + It will automatically find appropriate components, + containing rules with given names. If rule not found, and `ignoreInvalid` + not set - throws exception. + + Example:: + + md = MarkdownIt().enable(['sub', 'sup']).disable('smartquotes') + + """ + result = [] + + if isinstance(names, str): + names = [names] + + for chain in ["core", "block", "inline"]: + result.extend(self[chain].ruler.enable(names, True)) + result.extend(self.inline.ruler2.enable(names, True)) + + missed = [name for name in names if name not in result] + if missed and not ignoreInvalid: + raise ValueError(f"MarkdownIt. Failed to enable unknown rule(s): {missed}") + + return self + + def disable( + self, names: str | Iterable[str], ignoreInvalid: bool = False + ) -> MarkdownIt: + """The same as [[MarkdownIt.enable]], but turn specified rules off. (chainable) + + :param names: rule name or list of rule names to disable. + :param ignoreInvalid: set `true` to ignore errors when rule not found. + + """ + result = [] + + if isinstance(names, str): + names = [names] + + for chain in ["core", "block", "inline"]: + result.extend(self[chain].ruler.disable(names, True)) + result.extend(self.inline.ruler2.disable(names, True)) + + missed = [name for name in names if name not in result] + if missed and not ignoreInvalid: + raise ValueError(f"MarkdownIt. Failed to disable unknown rule(s): {missed}") + return self + + @contextmanager + def reset_rules(self) -> Generator[None, None, None]: + """A context manager, that will reset the current enabled rules on exit.""" + chain_rules = self.get_active_rules() + yield + for chain, rules in chain_rules.items(): + if chain != "inline2": + self[chain].ruler.enableOnly(rules) + self.inline.ruler2.enableOnly(chain_rules["inline2"]) + + def add_render_rule( + self, name: str, function: Callable[..., Any], fmt: str = "html" + ) -> None: + """Add a rule for rendering a particular Token type. + + Only applied when ``renderer.__output__ == fmt`` + """ + if self.renderer.__output__ == fmt: + self.renderer.rules[name] = function.__get__(self.renderer) # type: ignore + + def use( + self, plugin: Callable[..., None], *params: Any, **options: Any + ) -> MarkdownIt: + """Load specified plugin with given params into current parser instance. (chainable) + + It's just a sugar to call `plugin(md, params)` with curring. + + Example:: + + def func(tokens, idx): + tokens[idx].content = tokens[idx].content.replace('foo', 'bar') + md = MarkdownIt().use(plugin, 'foo_replace', 'text', func) + + """ + plugin(self, *params, **options) + return self + + def parse(self, src: str, env: EnvType | None = None) -> list[Token]: + """Parse the source string to a token stream + + :param src: source string + :param env: environment sandbox + + Parse input string and return list of block tokens (special token type + "inline" will contain list of inline tokens). + + `env` is used to pass data between "distributed" rules and return additional + metadata like reference info, needed for the renderer. It also can be used to + inject data in specific cases. Usually, you will be ok to pass `{}`, + and then pass updated object to renderer. + """ + env = {} if env is None else env + if not isinstance(env, MutableMapping): + raise TypeError(f"Input data should be a MutableMapping, not {type(env)}") + if not isinstance(src, str): + raise TypeError(f"Input data should be a string, not {type(src)}") + state = StateCore(src, self, env) + self.core.process(state) + return state.tokens + + def render(self, src: str, env: EnvType | None = None) -> Any: + """Render markdown string into html. It does all magic for you :). + + :param src: source string + :param env: environment sandbox + :returns: The output of the loaded renderer + + `env` can be used to inject additional metadata (`{}` by default). + But you will not need it with high probability. See also comment + in [[MarkdownIt.parse]]. + """ + env = {} if env is None else env + return self.renderer.render(self.parse(src, env), self.options, env) + + def parseInline(self, src: str, env: EnvType | None = None) -> list[Token]: + """The same as [[MarkdownIt.parse]] but skip all block rules. + + :param src: source string + :param env: environment sandbox + + It returns the + block tokens list with the single `inline` element, containing parsed inline + tokens in `children` property. Also updates `env` object. + """ + env = {} if env is None else env + if not isinstance(env, MutableMapping): + raise TypeError(f"Input data should be an MutableMapping, not {type(env)}") + if not isinstance(src, str): + raise TypeError(f"Input data should be a string, not {type(src)}") + state = StateCore(src, self, env) + state.inlineMode = True + self.core.process(state) + return state.tokens + + def renderInline(self, src: str, env: EnvType | None = None) -> Any: + """Similar to [[MarkdownIt.render]] but for single paragraph content. + + :param src: source string + :param env: environment sandbox + + Similar to [[MarkdownIt.render]] but for single paragraph content. Result + will NOT be wrapped into `

` tags. + """ + env = {} if env is None else env + return self.renderer.render(self.parseInline(src, env), self.options, env) + + # link methods + + def validateLink(self, url: str) -> bool: + """Validate if the URL link is allowed in output. + + This validator can prohibit more than really needed to prevent XSS. + It's a tradeoff to keep code simple and to be secure by default. + + Note: the url should be normalized at this point, and existing entities decoded. + """ + return normalize_url.validateLink(url) + + def normalizeLink(self, url: str) -> str: + """Normalize destination URLs in links + + :: + + [label]: destination 'title' + ^^^^^^^^^^^ + """ + return normalize_url.normalizeLink(url) + + def normalizeLinkText(self, link: str) -> str: + """Normalize autolink content + + :: + + + ~~~~~~~~~~~ + """ + return normalize_url.normalizeLinkText(link) diff --git a/.venv/Lib/site-packages/markdown_it/parser_block.py b/.venv/Lib/site-packages/markdown_it/parser_block.py new file mode 100644 index 0000000..72360f9 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/parser_block.py @@ -0,0 +1,111 @@ +"""Block-level tokenizer.""" +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING, Callable + +from . import rules_block +from .ruler import Ruler +from .rules_block.state_block import StateBlock +from .token import Token +from .utils import EnvType + +if TYPE_CHECKING: + from markdown_it import MarkdownIt + +LOGGER = logging.getLogger(__name__) + + +RuleFuncBlockType = Callable[[StateBlock, int, int, bool], bool] +"""(state: StateBlock, startLine: int, endLine: int, silent: bool) -> matched: bool) + +`silent` disables token generation, useful for lookahead. +""" + +_rules: list[tuple[str, RuleFuncBlockType, list[str]]] = [ + # First 2 params - rule name & source. Secondary array - list of rules, + # which can be terminated by this one. + ("table", rules_block.table, ["paragraph", "reference"]), + ("code", rules_block.code, []), + ("fence", rules_block.fence, ["paragraph", "reference", "blockquote", "list"]), + ( + "blockquote", + rules_block.blockquote, + ["paragraph", "reference", "blockquote", "list"], + ), + ("hr", rules_block.hr, ["paragraph", "reference", "blockquote", "list"]), + ("list", rules_block.list_block, ["paragraph", "reference", "blockquote"]), + ("reference", rules_block.reference, []), + ("html_block", rules_block.html_block, ["paragraph", "reference", "blockquote"]), + ("heading", rules_block.heading, ["paragraph", "reference", "blockquote"]), + ("lheading", rules_block.lheading, []), + ("paragraph", rules_block.paragraph, []), +] + + +class ParserBlock: + """ + ParserBlock#ruler -> Ruler + + [[Ruler]] instance. Keep configuration of block rules. + """ + + def __init__(self) -> None: + self.ruler = Ruler[RuleFuncBlockType]() + for name, rule, alt in _rules: + self.ruler.push(name, rule, {"alt": alt}) + + def tokenize(self, state: StateBlock, startLine: int, endLine: int) -> None: + """Generate tokens for input range.""" + rules = self.ruler.getRules("") + line = startLine + maxNesting = state.md.options.maxNesting + hasEmptyLines = False + + while line < endLine: + state.line = line = state.skipEmptyLines(line) + if line >= endLine: + break + if state.sCount[line] < state.blkIndent: + # Termination condition for nested calls. + # Nested calls currently used for blockquotes & lists + break + if state.level >= maxNesting: + # If nesting level exceeded - skip tail to the end. + # That's not ordinary situation and we should not care about content. + state.line = endLine + break + + # Try all possible rules. + # On success, rule should: + # - update `state.line` + # - update `state.tokens` + # - return True + for rule in rules: + if rule(state, line, endLine, False): + break + + # set state.tight if we had an empty line before current tag + # i.e. latest empty line should not count + state.tight = not hasEmptyLines + + line = state.line + + # paragraph might "eat" one newline after it in nested lists + if (line - 1) < endLine and state.isEmpty(line - 1): + hasEmptyLines = True + + if line < endLine and state.isEmpty(line): + hasEmptyLines = True + line += 1 + state.line = line + + def parse( + self, src: str, md: MarkdownIt, env: EnvType, outTokens: list[Token] + ) -> list[Token] | None: + """Process input string and push block tokens into `outTokens`.""" + if not src: + return None + state = StateBlock(src, md, env, outTokens) + self.tokenize(state, state.line, state.lineMax) + return state.tokens diff --git a/.venv/Lib/site-packages/markdown_it/parser_core.py b/.venv/Lib/site-packages/markdown_it/parser_core.py new file mode 100644 index 0000000..ca5ab25 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/parser_core.py @@ -0,0 +1,45 @@ +""" + * class Core + * + * Top-level rules executor. Glues block/inline parsers and does intermediate + * transformations. +""" +from __future__ import annotations + +from typing import Callable + +from .ruler import Ruler +from .rules_core import ( + block, + inline, + linkify, + normalize, + replace, + smartquotes, + text_join, +) +from .rules_core.state_core import StateCore + +RuleFuncCoreType = Callable[[StateCore], None] + +_rules: list[tuple[str, RuleFuncCoreType]] = [ + ("normalize", normalize), + ("block", block), + ("inline", inline), + ("linkify", linkify), + ("replacements", replace), + ("smartquotes", smartquotes), + ("text_join", text_join), +] + + +class ParserCore: + def __init__(self) -> None: + self.ruler = Ruler[RuleFuncCoreType]() + for name, rule in _rules: + self.ruler.push(name, rule) + + def process(self, state: StateCore) -> None: + """Executes core chain rules.""" + for rule in self.ruler.getRules(""): + rule(state) diff --git a/.venv/Lib/site-packages/markdown_it/parser_inline.py b/.venv/Lib/site-packages/markdown_it/parser_inline.py new file mode 100644 index 0000000..0026c38 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/parser_inline.py @@ -0,0 +1,147 @@ +"""Tokenizes paragraph content. +""" +from __future__ import annotations + +from typing import TYPE_CHECKING, Callable + +from . import rules_inline +from .ruler import Ruler +from .rules_inline.state_inline import StateInline +from .token import Token +from .utils import EnvType + +if TYPE_CHECKING: + from markdown_it import MarkdownIt + + +# Parser rules +RuleFuncInlineType = Callable[[StateInline, bool], bool] +"""(state: StateInline, silent: bool) -> matched: bool) + +`silent` disables token generation, useful for lookahead. +""" +_rules: list[tuple[str, RuleFuncInlineType]] = [ + ("text", rules_inline.text), + ("linkify", rules_inline.linkify), + ("newline", rules_inline.newline), + ("escape", rules_inline.escape), + ("backticks", rules_inline.backtick), + ("strikethrough", rules_inline.strikethrough.tokenize), + ("emphasis", rules_inline.emphasis.tokenize), + ("link", rules_inline.link), + ("image", rules_inline.image), + ("autolink", rules_inline.autolink), + ("html_inline", rules_inline.html_inline), + ("entity", rules_inline.entity), +] + +# Note `rule2` ruleset was created specifically for emphasis/strikethrough +# post-processing and may be changed in the future. +# +# Don't use this for anything except pairs (plugins working with `balance_pairs`). +# +RuleFuncInline2Type = Callable[[StateInline], None] +_rules2: list[tuple[str, RuleFuncInline2Type]] = [ + ("balance_pairs", rules_inline.link_pairs), + ("strikethrough", rules_inline.strikethrough.postProcess), + ("emphasis", rules_inline.emphasis.postProcess), + # rules for pairs separate '**' into its own text tokens, which may be left unused, + # rule below merges unused segments back with the rest of the text + ("fragments_join", rules_inline.fragments_join), +] + + +class ParserInline: + def __init__(self) -> None: + self.ruler = Ruler[RuleFuncInlineType]() + for name, rule in _rules: + self.ruler.push(name, rule) + # Second ruler used for post-processing (e.g. in emphasis-like rules) + self.ruler2 = Ruler[RuleFuncInline2Type]() + for name, rule2 in _rules2: + self.ruler2.push(name, rule2) + + def skipToken(self, state: StateInline) -> None: + """Skip single token by running all rules in validation mode; + returns `True` if any rule reported success + """ + ok = False + pos = state.pos + rules = self.ruler.getRules("") + maxNesting = state.md.options["maxNesting"] + cache = state.cache + + if pos in cache: + state.pos = cache[pos] + return + + if state.level < maxNesting: + for rule in rules: + # Increment state.level and decrement it later to limit recursion. + # It's harmless to do here, because no tokens are created. + # But ideally, we'd need a separate private state variable for this purpose. + state.level += 1 + ok = rule(state, True) + state.level -= 1 + if ok: + break + else: + # Too much nesting, just skip until the end of the paragraph. + # + # NOTE: this will cause links to behave incorrectly in the following case, + # when an amount of `[` is exactly equal to `maxNesting + 1`: + # + # [[[[[[[[[[[[[[[[[[[[[foo]() + # + # TODO: remove this workaround when CM standard will allow nested links + # (we can replace it by preventing links from being parsed in + # validation mode) + # + state.pos = state.posMax + + if not ok: + state.pos += 1 + cache[pos] = state.pos + + def tokenize(self, state: StateInline) -> None: + """Generate tokens for input range.""" + ok = False + rules = self.ruler.getRules("") + end = state.posMax + maxNesting = state.md.options["maxNesting"] + + while state.pos < end: + # Try all possible rules. + # On success, rule should: + # + # - update `state.pos` + # - update `state.tokens` + # - return true + + if state.level < maxNesting: + for rule in rules: + ok = rule(state, False) + if ok: + break + + if ok: + if state.pos >= end: + break + continue + + state.pending += state.src[state.pos] + state.pos += 1 + + if state.pending: + state.pushPending() + + def parse( + self, src: str, md: MarkdownIt, env: EnvType, tokens: list[Token] + ) -> list[Token]: + """Process input string and push inline tokens into `tokens`""" + state = StateInline(src, md, env, tokens) + self.tokenize(state) + rules2 = self.ruler2.getRules("") + for rule in rules2: + rule(state) + return state.tokens diff --git a/.venv/Lib/site-packages/markdown_it/port.yaml b/.venv/Lib/site-packages/markdown_it/port.yaml new file mode 100644 index 0000000..3e289e9 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/port.yaml @@ -0,0 +1,48 @@ +- package: markdown-it/markdown-it + version: 13.0.1 + commit: e843acc9edad115cbf8cf85e676443f01658be08 + date: May 3, 2022 + notes: + - Rename variables that use python built-in names, e.g. + - `max` -> `maximum` + - `len` -> `length` + - `str` -> `string` + - | + Convert JS `for` loops to `while` loops + this is generally the main difference between the codes, + because in python you can't do e.g. `for {i=1;i PresetType: + config = commonmark.make() + config["components"]["core"]["rules"].append("linkify") + config["components"]["block"]["rules"].append("table") + config["components"]["inline"]["rules"].extend(["strikethrough", "linkify"]) + config["components"]["inline"]["rules2"].append("strikethrough") + config["options"]["linkify"] = True + config["options"]["html"] = True + return config diff --git a/.venv/Lib/site-packages/markdown_it/presets/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/presets/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d89e5a567ff4044f175f3d861fe0c24e666d7dbe GIT binary patch literal 1631 zcmah}&2Jk;6rWx1t|z7@Y6}$+g$!v)vXIyawT)Co1=NzHsEHyad|8%O8_(F@ct6a{ zIBBXN<&Z;82u|rSSIDKu{s{;!tca9oBqSt|P;Y5-K;p!kjhzrg#XG#6_x+nU@9mGp zVgUht^wnhZha5t`X`x3}_i*$+9JUcf6+{hchDKyo%qUmMMOMW!5Y165v?HhD7>MO6 zc@s?|YHuRy?3%|JDtImLV%JuMS`tM`9QnMZ@|4y6PAHZ2fbm2XmW9{T;6^?2!l1>T z7?8ltah-<)Jj6AoCt7q3RhZ{YFuAzaW;M{9kapB`Gz@GTF;p=CyGe~oj#<=XcHN}8 zO=~xELa5@bS+30;5dA?YI338D&Jvjl{gtG{86~p-mnN$*8J(V*b%_R6DijFNVlxoL zr&JKxWMGI}L49qENPj70#E&Tvl7qKw@}$#f61aUkiCHYcKOwiF7tjoyy_;?>k!*|v zl7xP(1wOuLjfa7dpkfgef`r^(B{Pe&_eebmCF4Qd7|W1AzKAiI;m}y>oiHQ-mk4N1 zP!DRp43ao=9Tkj`rj%`Qvs`Wjve{WGbw2>G481R3@jEin*Ae6FzGSh0*m1X%g)4_M z+2Qe-mg{HHZ9f`<25uv%-z}r%?g;c`{p~gWOSBFHH2@lFW<00)vaNm2618@_8I98z z`+s7b|A@)|BPM^ghL$L%R>OR5T;Fr?;nNsefLpzg)v+dZ&QtlEmeE_A0s zS+#^SW%EwRgvxj4NZCtaQfnzY8z1Gx+oQp)KbCzqqxY;>!;| zN%7U4Pg6X;kFTZp+N00+@Ovjl(7(CUNO5T&Ur+J%M~yvv>%{n3iidYrQ(WH1H&T4# zasT%NKTRy`;l;Ba_f!1NKAuSN#N+-wJaaJe_Lj4?mg0ejE|fmFI@%M5Q~bt3|I1s& zBS4Gh+`Ph`7yA+OJXP?#D53B)a6adGUv&JiYsq^aO=?;#BrIhug5N_zc^{<6+VL&o zuj%t;&Gb(xW7;f+fNi3uX5Pk!7m#z|(8Ttouitux;B%A%#Z#>~4%d-$Zl8j3ei%YI z^sm3DvO6*e#c^T1bH~N5=+g-Rg(r`%af^?DK~GDD;xK0z#zEo3jr<>IBt;{?px1vb SzO+&J)46C|dWL{yIsOK^aiOsQ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/presets/__pycache__/commonmark.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/presets/__pycache__/commonmark.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca42b76f8dd7c5877cf0fcfd22cca6575f6f0ddb GIT binary patch literal 1176 zcmYLIF>m8G6sBZZw&d6iu0aySmmD*6Fwi8uLvL~K4k+#rT(4;wAn6haFldps7)zo` zQc0Z2Lx)aX+XCs5rRZNeVBGD(1pI+Jt-$Y;vPuzkFFjftB3i$)xK(Oi zp}~%SRm_bmi!NN+w0T*ftxNk5bw1dCw*=9ScJl=gHgq-g)rFl9uPNb9A)PTx}55}gU$C(&Pl0{4!_uE`(rcC|3IP`U{joX)ujFj<< zaKLcD&y5%HVHCsArYiH8sg7g3RLF$H{DPTkSvKR|m&N%1#{a*|enWBxtamWbzvGwP z;2Q<~92}A)c*WF6i!3IlPBL@(ixuTotb_2dFPq;`{H5^!Fcw5dw8vk(4TyB zIrRDB!iL2MgwX-Q8rDNC(hqbEVT0&>9h+~>17lortdrHq;{j%G;teWoO!{6LN}DB; zvRG`MM(sH8pT~ zs_!GG(mBJBzn3lm&nDB^ZEX7yEujdW{=-=q^efO0hT)6vQtKrG2_|17f2Ew0bjJK+Cs(H(IClmDA>}>?&%u z&+jysYS~?6uYKA1w)Ug`;QU@|!OBppWbr!4bR1Kadp*qjUQd-$NkhT&juyoV=S3P{ phBH;!ju=iu@{q5}4qHS68cUj(7}@jrff&8+|c literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/presets/__pycache__/zero.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/presets/__pycache__/zero.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ba89e614510ab104047e01e8486f7e37a7348fe GIT binary patch literal 953 zcmXw1&2J+$6!&~&l1x8#1*I)5>6)%M1huI^yBAatAFB%3RjE|CR3k;s*qOMQu?O4J zO)9OF0|!oADN>LSH~tnb6{pCjRXOb~QI`uR-pnqx-h1}@^zZroxv~->SYQ8iIQX=I z(BI|d|K+|u++sNVj3_!o)S+(bWbT>kAnGx?dQM% z6(Fj%S8<;rTAMa$kRV$B-Qf-mXd@|QGjV80mlBsQPhGk)_2}x_D^`(wLg#<@%s$p=i? z;QK-vrfp+XI(<_Z8}t+-Lv6z{9f0fek!=omGDv}pt*Ihqy6xMhkSc?QTrykhr7|Ac zfD5R>Y}2rj>7Gk2Y!li?s#?}BwRWXPAaBgNIpIp%)jpUrCXBB9+pf9`u%MA;kq_IR z^<$}+dIOZ|O<--;)@5$E6!5@UX1Nq)@E=IEz#e_b9$&9LnXR{eTe^C7{nq~TEqt{(+kXFg@9=u-<3-Ke zSY6cX8{y*N?s70kyR|^=K%HawjC!|AW!&xBT48vqRXK6hYpT9fZt5QBY~v8-9Gd%y kx(` PresetType: + return { + "options": { + "maxNesting": 20, # Internal protection, recursion limit + "html": True, # Enable HTML tags in source, + # this is just a shorthand for .enable(["html_inline", "html_block"]) + # used by the linkify rule: + "linkify": False, # autoconvert URL-like texts to links + # used by the replacements and smartquotes rules + # Enable some language-neutral replacements + quotes beautification + "typographer": False, + # used by the smartquotes rule: + # Double + single quotes replacement pairs, when typographer enabled, + # and smartquotes on. Could be either a String or an Array. + # + # For example, you can use '«»„“' for Russian, '„“‚‘' for German, + # and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp). + "quotes": "\u201c\u201d\u2018\u2019", # /* “”‘’ */ + # Renderer specific; these options are used directly in the HTML renderer + "xhtmlOut": True, # Use '/' to close single tags (
) + "breaks": False, # Convert '\n' in paragraphs into
+ "langPrefix": "language-", # CSS language prefix for fenced blocks + # Highlighter function. Should return escaped HTML, + # or '' if the source string is not changed and should be escaped externally. + # If result starts with PresetType: + return { + "options": { + "maxNesting": 100, # Internal protection, recursion limit + "html": False, # Enable HTML tags in source + # this is just a shorthand for .disable(["html_inline", "html_block"]) + # used by the linkify rule: + "linkify": False, # autoconvert URL-like texts to links + # used by the replacements and smartquotes rules: + # Enable some language-neutral replacements + quotes beautification + "typographer": False, + # used by the smartquotes rule: + # Double + single quotes replacement pairs, when typographer enabled, + # and smartquotes on. Could be either a String or an Array. + # For example, you can use '«»„“' for Russian, '„“‚‘' for German, + # and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp). + "quotes": "\u201c\u201d\u2018\u2019", # /* “”‘’ */ + # Renderer specific; these options are used directly in the HTML renderer + "xhtmlOut": False, # Use '/' to close single tags (
) + "breaks": False, # Convert '\n' in paragraphs into
+ "langPrefix": "language-", # CSS language prefix for fenced blocks + # Highlighter function. Should return escaped HTML, + # or '' if the source string is not changed and should be escaped externally. + # If result starts with PresetType: + return { + "options": { + "maxNesting": 20, # Internal protection, recursion limit + "html": False, # Enable HTML tags in source + # this is just a shorthand for .disable(["html_inline", "html_block"]) + # used by the linkify rule: + "linkify": False, # autoconvert URL-like texts to links + # used by the replacements and smartquotes rules: + # Enable some language-neutral replacements + quotes beautification + "typographer": False, + # used by the smartquotes rule: + # Double + single quotes replacement pairs, when typographer enabled, + # and smartquotes on. Could be either a String or an Array. + # For example, you can use '«»„“' for Russian, '„“‚‘' for German, + # and ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'] for French (including nbsp). + "quotes": "\u201c\u201d\u2018\u2019", # /* “”‘’ */ + # Renderer specific; these options are used directly in the HTML renderer + "xhtmlOut": False, # Use '/' to close single tags (
) + "breaks": False, # Convert '\n' in paragraphs into
+ "langPrefix": "language-", # CSS language prefix for fenced blocks + # Highlighter function. Should return escaped HTML, + # or '' if the source string is not changed and should be escaped externally. + # If result starts with Any: + ... + + +class RendererHTML(RendererProtocol): + """Contains render rules for tokens. Can be updated and extended. + + Example: + + Each rule is called as independent static function with fixed signature: + + :: + + class Renderer: + def token_type_name(self, tokens, idx, options, env) { + # ... + return renderedHTML + + :: + + class CustomRenderer(RendererHTML): + def strong_open(self, tokens, idx, options, env): + return '' + def strong_close(self, tokens, idx, options, env): + return '' + + md = MarkdownIt(renderer_cls=CustomRenderer) + + result = md.render(...) + + See https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js + for more details and examples. + """ + + __output__ = "html" + + def __init__(self, parser: Any = None): + self.rules = { + k: v + for k, v in inspect.getmembers(self, predicate=inspect.ismethod) + if not (k.startswith("render") or k.startswith("_")) + } + + def render( + self, tokens: Sequence[Token], options: OptionsDict, env: EnvType + ) -> str: + """Takes token stream and generates HTML. + + :param tokens: list on block tokens to render + :param options: params of parser instance + :param env: additional data from parsed input + + """ + result = "" + + for i, token in enumerate(tokens): + if token.type == "inline": + if token.children: + result += self.renderInline(token.children, options, env) + elif token.type in self.rules: + result += self.rules[token.type](tokens, i, options, env) + else: + result += self.renderToken(tokens, i, options, env) + + return result + + def renderInline( + self, tokens: Sequence[Token], options: OptionsDict, env: EnvType + ) -> str: + """The same as ``render``, but for single token of `inline` type. + + :param tokens: list on block tokens to render + :param options: params of parser instance + :param env: additional data from parsed input (references, for example) + """ + result = "" + + for i, token in enumerate(tokens): + if token.type in self.rules: + result += self.rules[token.type](tokens, i, options, env) + else: + result += self.renderToken(tokens, i, options, env) + + return result + + def renderToken( + self, + tokens: Sequence[Token], + idx: int, + options: OptionsDict, + env: EnvType, + ) -> str: + """Default token renderer. + + Can be overridden by custom function + + :param idx: token index to render + :param options: params of parser instance + """ + result = "" + needLf = False + token = tokens[idx] + + # Tight list paragraphs + if token.hidden: + return "" + + # Insert a newline between hidden paragraph and subsequent opening + # block-level tag. + # + # For example, here we should insert a newline before blockquote: + # - a + # > + # + if token.block and token.nesting != -1 and idx and tokens[idx - 1].hidden: + result += "\n" + + # Add token name, e.g. ``. + # + needLf = False + + result += ">\n" if needLf else ">" + + return result + + @staticmethod + def renderAttrs(token: Token) -> str: + """Render token attributes to string.""" + result = "" + + for key, value in token.attrItems(): + result += " " + escapeHtml(key) + '="' + escapeHtml(str(value)) + '"' + + return result + + def renderInlineAsText( + self, + tokens: Sequence[Token] | None, + options: OptionsDict, + env: EnvType, + ) -> str: + """Special kludge for image `alt` attributes to conform CommonMark spec. + + Don't try to use it! Spec requires to show `alt` content with stripped markup, + instead of simple escaping. + + :param tokens: list on block tokens to render + :param options: params of parser instance + :param env: additional data from parsed input + """ + result = "" + + for token in tokens or []: + if token.type == "text": + result += token.content + elif token.type == "image": + if token.children: + result += self.renderInlineAsText(token.children, options, env) + elif token.type == "softbreak": + result += "\n" + + return result + + ################################################### + + def code_inline( + self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType + ) -> str: + token = tokens[idx] + return ( + "" + + escapeHtml(tokens[idx].content) + + "" + ) + + def code_block( + self, + tokens: Sequence[Token], + idx: int, + options: OptionsDict, + env: EnvType, + ) -> str: + token = tokens[idx] + + return ( + "" + + escapeHtml(tokens[idx].content) + + "\n" + ) + + def fence( + self, + tokens: Sequence[Token], + idx: int, + options: OptionsDict, + env: EnvType, + ) -> str: + token = tokens[idx] + info = unescapeAll(token.info).strip() if token.info else "" + langName = "" + langAttrs = "" + + if info: + arr = info.split(maxsplit=1) + langName = arr[0] + if len(arr) == 2: + langAttrs = arr[1] + + if options.highlight: + highlighted = options.highlight( + token.content, langName, langAttrs + ) or escapeHtml(token.content) + else: + highlighted = escapeHtml(token.content) + + if highlighted.startswith("" + + highlighted + + "\n" + ) + + return ( + "

"
+            + highlighted
+            + "
\n" + ) + + def image( + self, + tokens: Sequence[Token], + idx: int, + options: OptionsDict, + env: EnvType, + ) -> str: + token = tokens[idx] + + # "alt" attr MUST be set, even if empty. Because it's mandatory and + # should be placed on proper position for tests. + if token.children: + token.attrSet("alt", self.renderInlineAsText(token.children, options, env)) + else: + token.attrSet("alt", "") + + return self.renderToken(tokens, idx, options, env) + + def hardbreak( + self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType + ) -> str: + return "
\n" if options.xhtmlOut else "
\n" + + def softbreak( + self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType + ) -> str: + return ( + ("
\n" if options.xhtmlOut else "
\n") if options.breaks else "\n" + ) + + def text( + self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType + ) -> str: + return escapeHtml(tokens[idx].content) + + def html_block( + self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType + ) -> str: + return tokens[idx].content + + def html_inline( + self, tokens: Sequence[Token], idx: int, options: OptionsDict, env: EnvType + ) -> str: + return tokens[idx].content diff --git a/.venv/Lib/site-packages/markdown_it/ruler.py b/.venv/Lib/site-packages/markdown_it/ruler.py new file mode 100644 index 0000000..bd8baba --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/ruler.py @@ -0,0 +1,276 @@ +""" +class Ruler + +Helper class, used by [[MarkdownIt#core]], [[MarkdownIt#block]] and +[[MarkdownIt#inline]] to manage sequences of functions (rules): + +- keep rules in defined order +- assign the name to each rule +- enable/disable rules +- add/replace rules +- allow assign rules to additional named chains (in the same) +- caching lists of active rules + +You will not need use this class directly until write plugins. For simple +rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and +[[MarkdownIt.use]]. +""" +from __future__ import annotations + +from collections.abc import Iterable +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Generic, TypedDict, TypeVar +import warnings + +from markdown_it._compat import DATACLASS_KWARGS + +from .utils import EnvType + +if TYPE_CHECKING: + from markdown_it import MarkdownIt + + +class StateBase: + def __init__(self, src: str, md: MarkdownIt, env: EnvType): + self.src = src + self.env = env + self.md = md + + @property + def src(self) -> str: + return self._src + + @src.setter + def src(self, value: str) -> None: + self._src = value + self._srcCharCode: tuple[int, ...] | None = None + + @property + def srcCharCode(self) -> tuple[int, ...]: + warnings.warn( + "StateBase.srcCharCode is deprecated. Use StateBase.src instead.", + DeprecationWarning, + stacklevel=2, + ) + if self._srcCharCode is None: + self._srcCharCode = tuple(ord(c) for c in self._src) + return self._srcCharCode + + +class RuleOptionsType(TypedDict, total=False): + alt: list[str] + + +RuleFuncTv = TypeVar("RuleFuncTv") +"""A rule function, whose signature is dependent on the state type.""" + + +@dataclass(**DATACLASS_KWARGS) +class Rule(Generic[RuleFuncTv]): + name: str + enabled: bool + fn: RuleFuncTv = field(repr=False) + alt: list[str] + + +class Ruler(Generic[RuleFuncTv]): + def __init__(self) -> None: + # List of added rules. + self.__rules__: list[Rule[RuleFuncTv]] = [] + # Cached rule chains. + # First level - chain name, '' for default. + # Second level - diginal anchor for fast filtering by charcodes. + self.__cache__: dict[str, list[RuleFuncTv]] | None = None + + def __find__(self, name: str) -> int: + """Find rule index by name""" + for i, rule in enumerate(self.__rules__): + if rule.name == name: + return i + return -1 + + def __compile__(self) -> None: + """Build rules lookup cache""" + chains = {""} + # collect unique names + for rule in self.__rules__: + if not rule.enabled: + continue + for name in rule.alt: + chains.add(name) + self.__cache__ = {} + for chain in chains: + self.__cache__[chain] = [] + for rule in self.__rules__: + if not rule.enabled: + continue + if chain and (chain not in rule.alt): + continue + self.__cache__[chain].append(rule.fn) + + def at( + self, ruleName: str, fn: RuleFuncTv, options: RuleOptionsType | None = None + ) -> None: + """Replace rule by name with new function & options. + + :param ruleName: rule name to replace. + :param fn: new rule function. + :param options: new rule options (not mandatory). + :raises: KeyError if name not found + """ + index = self.__find__(ruleName) + options = options or {} + if index == -1: + raise KeyError(f"Parser rule not found: {ruleName}") + self.__rules__[index].fn = fn + self.__rules__[index].alt = options.get("alt", []) + self.__cache__ = None + + def before( + self, + beforeName: str, + ruleName: str, + fn: RuleFuncTv, + options: RuleOptionsType | None = None, + ) -> None: + """Add new rule to chain before one with given name. + + :param beforeName: new rule will be added before this one. + :param ruleName: new rule will be added before this one. + :param fn: new rule function. + :param options: new rule options (not mandatory). + :raises: KeyError if name not found + """ + index = self.__find__(beforeName) + options = options or {} + if index == -1: + raise KeyError(f"Parser rule not found: {beforeName}") + self.__rules__.insert( + index, Rule[RuleFuncTv](ruleName, True, fn, options.get("alt", [])) + ) + self.__cache__ = None + + def after( + self, + afterName: str, + ruleName: str, + fn: RuleFuncTv, + options: RuleOptionsType | None = None, + ) -> None: + """Add new rule to chain after one with given name. + + :param afterName: new rule will be added after this one. + :param ruleName: new rule will be added after this one. + :param fn: new rule function. + :param options: new rule options (not mandatory). + :raises: KeyError if name not found + """ + index = self.__find__(afterName) + options = options or {} + if index == -1: + raise KeyError(f"Parser rule not found: {afterName}") + self.__rules__.insert( + index + 1, Rule[RuleFuncTv](ruleName, True, fn, options.get("alt", [])) + ) + self.__cache__ = None + + def push( + self, ruleName: str, fn: RuleFuncTv, options: RuleOptionsType | None = None + ) -> None: + """Push new rule to the end of chain. + + :param ruleName: new rule will be added to the end of chain. + :param fn: new rule function. + :param options: new rule options (not mandatory). + + """ + self.__rules__.append( + Rule[RuleFuncTv](ruleName, True, fn, (options or {}).get("alt", [])) + ) + self.__cache__ = None + + def enable( + self, names: str | Iterable[str], ignoreInvalid: bool = False + ) -> list[str]: + """Enable rules with given names. + + :param names: name or list of rule names to enable. + :param ignoreInvalid: ignore errors when rule not found + :raises: KeyError if name not found and not ignoreInvalid + :return: list of found rule names + """ + if isinstance(names, str): + names = [names] + result: list[str] = [] + for name in names: + idx = self.__find__(name) + if (idx < 0) and ignoreInvalid: + continue + if (idx < 0) and not ignoreInvalid: + raise KeyError(f"Rules manager: invalid rule name {name}") + self.__rules__[idx].enabled = True + result.append(name) + self.__cache__ = None + return result + + def enableOnly( + self, names: str | Iterable[str], ignoreInvalid: bool = False + ) -> list[str]: + """Enable rules with given names, and disable everything else. + + :param names: name or list of rule names to enable. + :param ignoreInvalid: ignore errors when rule not found + :raises: KeyError if name not found and not ignoreInvalid + :return: list of found rule names + """ + if isinstance(names, str): + names = [names] + for rule in self.__rules__: + rule.enabled = False + return self.enable(names, ignoreInvalid) + + def disable( + self, names: str | Iterable[str], ignoreInvalid: bool = False + ) -> list[str]: + """Disable rules with given names. + + :param names: name or list of rule names to enable. + :param ignoreInvalid: ignore errors when rule not found + :raises: KeyError if name not found and not ignoreInvalid + :return: list of found rule names + """ + if isinstance(names, str): + names = [names] + result = [] + for name in names: + idx = self.__find__(name) + if (idx < 0) and ignoreInvalid: + continue + if (idx < 0) and not ignoreInvalid: + raise KeyError(f"Rules manager: invalid rule name {name}") + self.__rules__[idx].enabled = False + result.append(name) + self.__cache__ = None + return result + + def getRules(self, chainName: str = "") -> list[RuleFuncTv]: + """Return array of active functions (rules) for given chain name. + It analyzes rules configuration, compiles caches if not exists and returns result. + + Default chain name is `''` (empty string). It can't be skipped. + That's done intentionally, to keep signature monomorphic for high speed. + + """ + if self.__cache__ is None: + self.__compile__() + assert self.__cache__ is not None + # Chain can be empty, if rules disabled. But we still have to return Array. + return self.__cache__.get(chainName, []) or [] + + def get_all_rules(self) -> list[str]: + """Return all available rule names.""" + return [r.name for r in self.__rules__] + + def get_active_rules(self) -> list[str]: + """Return the active rule names.""" + return [r.name for r in self.__rules__ if r.enabled] diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__init__.py b/.venv/Lib/site-packages/markdown_it/rules_block/__init__.py new file mode 100644 index 0000000..bcf138d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/__init__.py @@ -0,0 +1,27 @@ +__all__ = ( + "StateBlock", + "paragraph", + "heading", + "lheading", + "code", + "fence", + "hr", + "list_block", + "reference", + "blockquote", + "html_block", + "table", +) + +from .blockquote import blockquote +from .code import code +from .fence import fence +from .heading import heading +from .hr import hr +from .html_block import html_block +from .lheading import lheading +from .list import list_block +from .paragraph import paragraph +from .reference import reference +from .state_block import StateBlock +from .table import table diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4193919ad5a13df3a0be83440d119d1914ed5734 GIT binary patch literal 702 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/code.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/code.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a48cde9548c0f36b2c8334e8833ea516f66a3ad GIT binary patch literal 1401 zcmZ`(O>7%Q6rQzr*ZULK38X+xQe4tPEkOcOkV@4emB#t8(zG-sNM@zg+B3M0?OkhT zlg80nGEyZHsiNsA;Y5x_x#ZZM=rM>((nP9RI9Ng)a*GsBoOrWN;>dz0?VI=Zdq4Aj zc7KgVH3XFY{@VSo!wCJ!m17DJP!0`Xs|ceE!U7JJgp7d0SS*Fg;Y?USAw+~(<=Clx z5@|zdX&D(yB#dPe!4Y^AqF|LM-)LBSC}z}ZD5)>@-*hlZWJ^x2n7BNgU==GzSfXNK zOmK2=pU0Wn=i!oquT8s_OFrkezQnlft8h?vvS1TGLTnreGAopb?fNn$?i{sqV(T&i zj{t{q(P158t|IpYn&odh2n!za1TW-;H>4IMAP>zR$)}Ay;kaZbR6`!LX%XNBp(fTO zPx3;=5JL20@a6eC$UA8ll|2bOqX^ZcM}7a3sco&atv#tGKKevOp6DU-q+W=icO(N9 zi&(<)#!@id9cEDPc~0h0esPaEk-^BR_bxQs+!cM z7W-jRgcj_4A_t3bHF1f3aOxSQ{F=VTF*8^aU*s}{exiMT0bkJWB{g53ygfFSy6a1r zWasjJw7|?$K9K@Tl`C%57fXCo#L67I?<;u{EDrP4Y^gY5W4<$yoCEg(AzZd9$q41M zrZQ)Ia+H?{K`iF_icJ<;izm5Gk=TqIBwF;(gPT{4FBzfCn6}Es2w_FnsTk7*SoJ&9 znI$=w8KV&8#+`}8JWGs1#G)~7<%)zRMx0s47@Q~eyfInG8m!=w58PrTRE zyI<+&cl7gX)jd7gi1jw#cxU~>lk&DWP#;;k($rpC`Rb+C*U-BkUthky_ST;MZlkMr zO<2CQG!8=BePK_(+(ur1dufEjO0?N?ww`*JZg%xNPA{idy!Dxo}#LO+O*p z53gw-$CPVj2SZaoqwj&re>!X&*g;qjgx}D>@94~5XrQUam)?A(#&^{C+Lc}PVqHFv d<3jg}c7WhmXTh;K9ULz%2FKR$-y91v{R^XoT44YH literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/fence.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/fence.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf2b907b79ff48efa641506618a0f16ac51066c0 GIT binary patch literal 2547 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/hr.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/hr.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a59ca1a2214d1c83e4ebab2e8489901e1684829a GIT binary patch literal 1776 zcmaJ>%WoS+7@vJVY{yO07Lp3IsEJCVJQS)@`Vdgkv}t7eauG^ovD$d2_S$Q&nO!G! zw2@p?3A-TTp6Z?&q)LE#$)8XJhYBvWTB&9QQV`;hTOd84p7_R&ld3ArYUcZ9zUR*O z`{w6JL`5*BzdDiriAU%Uy6KFT1U8##SZ*N`%_5UAS(}+&fn8}1Y4t6M(?lJA%tZYhHFlDTm3QQHNW(ccSR5N^?pAD7R!N}tKQx35foxEq* z8Y$XXRZn`FjSbh+4r$I6%}Zk!Yss`hjHHK&t2uei&}=J@wIOXp)75nv>fAaD>mU=T zmK*m-ykI2pI!%He#XZBrAJ|SZ8wf7t0|f~2V&Ei@aNcY&qHEbW?*$^kUXkRJa6#Kc z0*-^Z8HO;okhd+!(9;)&$@s`;eAegg32hOBe3W_K-7XFzW{$G3f zIeXa`vq!)p>~(jt^5sr0F8KAS#+#ra_|jI?ojA;whvBpxlj?GiiRc3a=}q`ZSGIkk z%-#;aLrn=j`QBDlmK3N1%Iw~eceoVmEBf}W`C=;*5H3Q+K(c*PCGi0Ax;j? zpc1=)u5vSIff-cJE$#=@U}EJ{TACcw2HfH2=4nD9FvtbWP{51?jJ{4&yBx4-LRyH8 z1Y+#`nKP4@0>Q*{#Z(~9eQ1!Z8;D*!ZCwF4;`Tmbxq8wuu|C%VGUt+Hpq|Z}`06Af z4j~j?0Z;oP;0r}J9dJ3L5QsT&RxAvvghH556cKubgtmLY6&yE^a>i9FSIo6_F$uUN zbOD=82ZHBhao(k>+V*%>oH&;F$c0W!#Eo3y6n3+oQ%J-u6KfZUlfg;PO`L}IJ$d1* zHt%YuZNtqbri^436YZ3faT25RI6t3=S#t^3^6&_>YSu_$H$hW1orSz^d1Le?aNEB+ zmL{Wx5}{yfEr3$wjzMpi(XYJvdF)#3VfW~&uv)r*@WI=U`AchRba}WsTq`xyH&!OU ziG3Yg?QQfQZ>Y!16V0xkWxHzEk2bmn%4gQ3@Dr)8A@$XdK9&ZW(LEbHC+ux@@4MA| zv$uZe=Ia%4LqvjH8NW7Fo&Z+vs_6}>pK8h|6b654q$b@MX-0N0&s1k>ZuOH2+mu6< zPpfi;Ylb4VeK$_rRlj}fZdbGC)vbLq9IcI4rz#U05ftjGNnea?>_T93@v{YR{JRus zMtjz}`|1~OzE+;RKD`$1UY@Q_*Sz}WmGMX6f%0S%gp+rsZ%;qmbr3YpHhX&O@s;u0 zA2)hHdOfxlivIKTJrv&eH)4dnzd*7a&}S}fgYWl8Cyt;Wjwq)%?njn^bub)Ax^6m2 zT@NJNNu>bDK{)B;a!!7<=vlVghE}Nca<)rC=zA3?DeT3-03ajldfv!kT_-e1z*&GG ze$H|1R>i(Un{bLqKb6TRa*hereV2^EmOjz$c~~GvhWU%-7=BYmO!QAQ@Eba?ru0=_ sd7|_+l)m~qkCgs0)MJR*Rmp51AS>|}Sv}Mu_xToiu;(e2kx}sZFW&gFA^-pY literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/html_block.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/html_block.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1819fe3641176aaa80b4290e42484be68c92a784 GIT binary patch literal 3630 zcma)8T}&I<6~1H7c*Z|4#`ebGK;y8GU;?4ZCJjjl$V(gu0+Pn0iHwP5m=`}Tfe96wqJW{STxV~<*C!O_T;J8H1_3THLX2) zteVEYJPn%Go;)^9V_zOS=ZGGv#(!teQ<`-KiMbDOzyB@l>Bj+$X+J-BnseekG~M@L zYrL(Wr2|&3iErRseb~!p?%*e6z?Rl|T3(|y@DR`(7KDTxmLmy48h?!+8Wv8+5;OB5 zAspu=v~&(njE#n_T=k8I21l>>eW3~OP{==V?KOVU2sil=0sk?!$#`z{bx1Q}Bq=LN zkyj)+9pe?5zbl7DKJ4ijxX=-llzyenFo|oL83onL5twz;6?9*H#nK0f>Xh%er(t?&;bc0!)kl>3{-d3-D=B_ zL8-ItQs$#rM3N`vR5Hd-iv01bVOi!yVN#OCsV?_Bg6TveHZ=w7)nNF2KfUf7AN2WW zNF2zmMx#*=0P$uK^{YVE(DHUYy$GgU=%kFoa1>^VI(OkWXeW}0Pa73x0aa*$Ab~=w zKIuhDp*aJ#_M_-=v>H1jlF{$M_#4Hj=;l$Hh@YWYHSV&z5wjo+`T2HJ?Fb=>(A{oX zv)t{LRczl|RyEXH-Y1&xcS_MAw`jgA+tK7G^~Na0h+1)2+N%FriE^&gv9XX!~8ED7Dx0wHemiJ-VFf=~h$`i(S)Cn>^<6 z%!j;yQad8dy65D0ETopVbMAJjYsc>rBrynyJ`tBe5tE5HqoJv01i^&I0S%*9hK79C zAjR?1saa^49t(@}5;VyExyWr98u;qEE+U0y5*%OM59;C^q!UTC)I$9%FGIZ~&WJcE zp+Vxq;>;Wx2NNklhQ{gG{AGbdZbN;H7a$pn2s|W{DQOPsL`A>s()L2StcGKq)pM&hYBWH9Xns?Ly6&nWRfhjsr~;2)r90iq2{6YvtG?D&}1AM}E-jD8r@!n61lQ zOI<7JlId{X_xb4K(Y2;h+xe2|e0H!>Z(oir#d2p$_3hcA4cf9!yGpbxclH(CUSS;@ z$h3EoMh)vgC!xw|D>N8$7reNXzHF{NYPlFhp~SUGTTHTEEu?=2nZS{$l4 zn^)5h(s_ISM$y^5h`d%ESZ5EH*u(jbSM0HG?FUxw{`NxN`_kTCaWvTH6tNx#DPA z9e*&MKUrdRb9s=h!Y&O*e;i;xMa|Ci7Q6lF>v& zs3trc3hnskg{<&9egecFqe1M!3`}1`aP)s8!-M8 zbbSX-eFr|=FuE3<>qb|}=*sn$jcr-OrUe-7i@IgglBsAPcy9ZB%Qr1$=1PUJX~NTM z;#Uh_E|eKxg|TeXB+3vIFj%wK?g#D#R+uu?lslI@`RLrkbNSolgWUzWNS>-t>=sU! zsm5GquJuvp!_NHA%C4>gS0q2G;pQ^coQvkBA4MNV3y$)Sj<1nL@^lSn%al9cnQ#5P z^Kob4X1Vnz&k%lLLvwHCOwRx4=EIx$`Etw2lKo`y^iat@^uqS%mOr3l+}J+G%IPxG zw2S{m>(Ro|lJ!KHI=MEo_VHIEUyeLWl~4Jer;6m*<{|44q0816t%GlXmC*fgq?fR& GvHu@7EiZro literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/lheading.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/lheading.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1ea31414e6573c45eff7ee07d373dcfb9c409d1 GIT binary patch literal 2952 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 XLt4IiOw0d3Y5Cgq8*ecI=KsF{I5_t# literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/paragraph.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/paragraph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d062eea5a2719b738840da72224f3d36a7b32a9 GIT binary patch literal 2192 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 Vj}BDoZ^=r%bm8((27|HYe*j#k9S;Bi literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/state_block.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/state_block.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ec0d65925fc6768c01441fa119d8dc2efba2868 GIT binary patch literal 9217 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/table.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_block/__pycache__/table.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3372142f511553af686f7ac2dd13e9e26570fce6 GIT binary patch literal 7221 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/blockquote.py b/.venv/Lib/site-packages/markdown_it/rules_block/blockquote.py new file mode 100644 index 0000000..0c9081b --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/blockquote.py @@ -0,0 +1,299 @@ +# Block quotes +from __future__ import annotations + +import logging + +from ..common.utils import isStrSpace +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def blockquote(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug( + "entering blockquote: %s, %s, %s, %s", state, startLine, endLine, silent + ) + + oldLineMax = state.lineMax + pos = state.bMarks[startLine] + state.tShift[startLine] + max = state.eMarks[startLine] + + if state.is_code_block(startLine): + return False + + # check the block quote marker + try: + if state.src[pos] != ">": + return False + except IndexError: + return False + pos += 1 + + # we know that it's going to be a valid blockquote, + # so no point trying to find the end of it in silent mode + if silent: + return True + + # set offset past spaces and ">" + initial = offset = state.sCount[startLine] + 1 + + try: + second_char: str | None = state.src[pos] + except IndexError: + second_char = None + + # skip one optional space after '>' + if second_char == " ": + # ' > test ' + # ^ -- position start of line here: + pos += 1 + initial += 1 + offset += 1 + adjustTab = False + spaceAfterMarker = True + elif second_char == "\t": + spaceAfterMarker = True + + if (state.bsCount[startLine] + offset) % 4 == 3: + # ' >\t test ' + # ^ -- position start of line here (tab has width==1) + pos += 1 + initial += 1 + offset += 1 + adjustTab = False + else: + # ' >\t test ' + # ^ -- position start of line here + shift bsCount slightly + # to make extra space appear + adjustTab = True + + else: + spaceAfterMarker = False + + oldBMarks = [state.bMarks[startLine]] + state.bMarks[startLine] = pos + + while pos < max: + ch = state.src[pos] + + if isStrSpace(ch): + if ch == "\t": + offset += ( + 4 + - (offset + state.bsCount[startLine] + (1 if adjustTab else 0)) % 4 + ) + else: + offset += 1 + + else: + break + + pos += 1 + + oldBSCount = [state.bsCount[startLine]] + state.bsCount[startLine] = ( + state.sCount[startLine] + 1 + (1 if spaceAfterMarker else 0) + ) + + lastLineEmpty = pos >= max + + oldSCount = [state.sCount[startLine]] + state.sCount[startLine] = offset - initial + + oldTShift = [state.tShift[startLine]] + state.tShift[startLine] = pos - state.bMarks[startLine] + + terminatorRules = state.md.block.ruler.getRules("blockquote") + + oldParentType = state.parentType + state.parentType = "blockquote" + + # Search the end of the block + # + # Block ends with either: + # 1. an empty line outside: + # ``` + # > test + # + # ``` + # 2. an empty line inside: + # ``` + # > + # test + # ``` + # 3. another tag: + # ``` + # > test + # - - - + # ``` + + # for (nextLine = startLine + 1; nextLine < endLine; nextLine++) { + nextLine = startLine + 1 + while nextLine < endLine: + # check if it's outdented, i.e. it's inside list item and indented + # less than said list item: + # + # ``` + # 1. anything + # > current blockquote + # 2. checking this line + # ``` + isOutdented = state.sCount[nextLine] < state.blkIndent + + pos = state.bMarks[nextLine] + state.tShift[nextLine] + max = state.eMarks[nextLine] + + if pos >= max: + # Case 1: line is not inside the blockquote, and this line is empty. + break + + evaluatesTrue = state.src[pos] == ">" and not isOutdented + pos += 1 + if evaluatesTrue: + # This line is inside the blockquote. + + # set offset past spaces and ">" + initial = offset = state.sCount[nextLine] + 1 + + try: + next_char: str | None = state.src[pos] + except IndexError: + next_char = None + + # skip one optional space after '>' + if next_char == " ": + # ' > test ' + # ^ -- position start of line here: + pos += 1 + initial += 1 + offset += 1 + adjustTab = False + spaceAfterMarker = True + elif next_char == "\t": + spaceAfterMarker = True + + if (state.bsCount[nextLine] + offset) % 4 == 3: + # ' >\t test ' + # ^ -- position start of line here (tab has width==1) + pos += 1 + initial += 1 + offset += 1 + adjustTab = False + else: + # ' >\t test ' + # ^ -- position start of line here + shift bsCount slightly + # to make extra space appear + adjustTab = True + + else: + spaceAfterMarker = False + + oldBMarks.append(state.bMarks[nextLine]) + state.bMarks[nextLine] = pos + + while pos < max: + ch = state.src[pos] + + if isStrSpace(ch): + if ch == "\t": + offset += ( + 4 + - ( + offset + + state.bsCount[nextLine] + + (1 if adjustTab else 0) + ) + % 4 + ) + else: + offset += 1 + else: + break + + pos += 1 + + lastLineEmpty = pos >= max + + oldBSCount.append(state.bsCount[nextLine]) + state.bsCount[nextLine] = ( + state.sCount[nextLine] + 1 + (1 if spaceAfterMarker else 0) + ) + + oldSCount.append(state.sCount[nextLine]) + state.sCount[nextLine] = offset - initial + + oldTShift.append(state.tShift[nextLine]) + state.tShift[nextLine] = pos - state.bMarks[nextLine] + + nextLine += 1 + continue + + # Case 2: line is not inside the blockquote, and the last line was empty. + if lastLineEmpty: + break + + # Case 3: another tag found. + terminate = False + + for terminatorRule in terminatorRules: + if terminatorRule(state, nextLine, endLine, True): + terminate = True + break + + if terminate: + # Quirk to enforce "hard termination mode" for paragraphs; + # normally if you call `tokenize(state, startLine, nextLine)`, + # paragraphs will look below nextLine for paragraph continuation, + # but if blockquote is terminated by another tag, they shouldn't + state.lineMax = nextLine + + if state.blkIndent != 0: + # state.blkIndent was non-zero, we now set it to zero, + # so we need to re-calculate all offsets to appear as + # if indent wasn't changed + oldBMarks.append(state.bMarks[nextLine]) + oldBSCount.append(state.bsCount[nextLine]) + oldTShift.append(state.tShift[nextLine]) + oldSCount.append(state.sCount[nextLine]) + state.sCount[nextLine] -= state.blkIndent + + break + + oldBMarks.append(state.bMarks[nextLine]) + oldBSCount.append(state.bsCount[nextLine]) + oldTShift.append(state.tShift[nextLine]) + oldSCount.append(state.sCount[nextLine]) + + # A negative indentation means that this is a paragraph continuation + # + state.sCount[nextLine] = -1 + + nextLine += 1 + + oldIndent = state.blkIndent + state.blkIndent = 0 + + token = state.push("blockquote_open", "blockquote", 1) + token.markup = ">" + token.map = lines = [startLine, 0] + + state.md.block.tokenize(state, startLine, nextLine) + + token = state.push("blockquote_close", "blockquote", -1) + token.markup = ">" + + state.lineMax = oldLineMax + state.parentType = oldParentType + lines[1] = state.line + + # Restore original tShift; this might not be necessary since the parser + # has already been here, but just to make sure we can do that. + for i, item in enumerate(oldTShift): + state.bMarks[i + startLine] = oldBMarks[i] + state.tShift[i + startLine] = item + state.sCount[i + startLine] = oldSCount[i] + state.bsCount[i + startLine] = oldBSCount[i] + + state.blkIndent = oldIndent + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/code.py b/.venv/Lib/site-packages/markdown_it/rules_block/code.py new file mode 100644 index 0000000..89db9ce --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/code.py @@ -0,0 +1,35 @@ +"""Code block (4 spaces padded).""" +import logging + +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def code(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug("entering code: %s, %s, %s, %s", state, startLine, endLine, silent) + + if not state.is_code_block(startLine): + return False + + last = nextLine = startLine + 1 + + while nextLine < endLine: + if state.isEmpty(nextLine): + nextLine += 1 + continue + + if state.is_code_block(nextLine): + nextLine += 1 + last = nextLine + continue + + break + + state.line = last + + token = state.push("code_block", "code", 0) + token.content = state.getLines(startLine, last, 4 + state.blkIndent, False) + "\n" + token.map = [startLine, state.line] + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/fence.py b/.venv/Lib/site-packages/markdown_it/rules_block/fence.py new file mode 100644 index 0000000..263f1b8 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/fence.py @@ -0,0 +1,101 @@ +# fences (``` lang, ~~~ lang) +import logging + +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def fence(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug("entering fence: %s, %s, %s, %s", state, startLine, endLine, silent) + + haveEndMarker = False + pos = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + + if state.is_code_block(startLine): + return False + + if pos + 3 > maximum: + return False + + marker = state.src[pos] + + if marker not in ("~", "`"): + return False + + # scan marker length + mem = pos + pos = state.skipCharsStr(pos, marker) + + length = pos - mem + + if length < 3: + return False + + markup = state.src[mem:pos] + params = state.src[pos:maximum] + + if marker == "`" and marker in params: + return False + + # Since start is found, we can report success here in validation mode + if silent: + return True + + # search end of block + nextLine = startLine + + while True: + nextLine += 1 + if nextLine >= endLine: + # unclosed block should be autoclosed by end of document. + # also block seems to be autoclosed by end of parent + break + + pos = mem = state.bMarks[nextLine] + state.tShift[nextLine] + maximum = state.eMarks[nextLine] + + if pos < maximum and state.sCount[nextLine] < state.blkIndent: + # non-empty line with negative indent should stop the list: + # - ``` + # test + break + + try: + if state.src[pos] != marker: + continue + except IndexError: + break + + if state.is_code_block(nextLine): + continue + + pos = state.skipCharsStr(pos, marker) + + # closing code fence must be at least as long as the opening one + if pos - mem < length: + continue + + # make sure tail has spaces only + pos = state.skipSpaces(pos) + + if pos < maximum: + continue + + haveEndMarker = True + # found! + break + + # If a fence has heading spaces, they should be removed from its inner block + length = state.sCount[startLine] + + state.line = nextLine + (1 if haveEndMarker else 0) + + token = state.push("fence", "code", 0) + token.info = params + token.content = state.getLines(startLine + 1, nextLine, length, True) + token.markup = markup + token.map = [startLine, state.line] + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/heading.py b/.venv/Lib/site-packages/markdown_it/rules_block/heading.py new file mode 100644 index 0000000..850ffb5 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/heading.py @@ -0,0 +1,68 @@ +""" Atex heading (#, ##, ...) """ +from __future__ import annotations + +import logging + +from ..common.utils import isStrSpace +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def heading(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug("entering heading: %s, %s, %s, %s", state, startLine, endLine, silent) + + pos = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + + if state.is_code_block(startLine): + return False + + ch: str | None = state.src[pos] + + if ch != "#" or pos >= maximum: + return False + + # count heading level + level = 1 + pos += 1 + try: + ch = state.src[pos] + except IndexError: + ch = None + while ch == "#" and pos < maximum and level <= 6: + level += 1 + pos += 1 + try: + ch = state.src[pos] + except IndexError: + ch = None + + if level > 6 or (pos < maximum and not isStrSpace(ch)): + return False + + if silent: + return True + + # Let's cut tails like ' ### ' from the end of string + + maximum = state.skipSpacesBack(maximum, pos) + tmp = state.skipCharsStrBack(maximum, "#", pos) + if tmp > pos and isStrSpace(state.src[tmp - 1]): + maximum = tmp + + state.line = startLine + 1 + + token = state.push("heading_open", "h" + str(level), 1) + token.markup = "########"[:level] + token.map = [startLine, state.line] + + token = state.push("inline", "", 0) + token.content = state.src[pos:maximum].strip() + token.map = [startLine, state.line] + token.children = [] + + token = state.push("heading_close", "h" + str(level), -1) + token.markup = "########"[:level] + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/hr.py b/.venv/Lib/site-packages/markdown_it/rules_block/hr.py new file mode 100644 index 0000000..16df05f --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/hr.py @@ -0,0 +1,55 @@ +"""Horizontal rule + +At least 3 of these characters on a line * - _ +""" +import logging + +from ..common.utils import isStrSpace +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def hr(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug("entering hr: %s, %s, %s, %s", state, startLine, endLine, silent) + + pos = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + + if state.is_code_block(startLine): + return False + + try: + marker = state.src[pos] + except IndexError: + return False + pos += 1 + + # Check hr marker + if marker not in ("*", "-", "_"): + return False + + # markers can be mixed with spaces, but there should be at least 3 of them + + cnt = 1 + while pos < maximum: + ch = state.src[pos] + pos += 1 + if ch != marker and not isStrSpace(ch): + return False + if ch == marker: + cnt += 1 + + if cnt < 3: + return False + + if silent: + return True + + state.line = startLine + 1 + + token = state.push("hr", "hr", 0) + token.map = [startLine, state.line] + token.markup = marker * (cnt + 1) + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/html_block.py b/.venv/Lib/site-packages/markdown_it/rules_block/html_block.py new file mode 100644 index 0000000..3d43f6e --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/html_block.py @@ -0,0 +1,90 @@ +# HTML block +from __future__ import annotations + +import logging +import re + +from ..common.html_blocks import block_names +from ..common.html_re import HTML_OPEN_CLOSE_TAG_STR +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + +# An array of opening and corresponding closing sequences for html tags, +# last argument defines whether it can terminate a paragraph or not +HTML_SEQUENCES: list[tuple[re.Pattern[str], re.Pattern[str], bool]] = [ + ( + re.compile(r"^<(script|pre|style|textarea)(?=(\s|>|$))", re.IGNORECASE), + re.compile(r"<\/(script|pre|style|textarea)>", re.IGNORECASE), + True, + ), + (re.compile(r"^"), True), + (re.compile(r"^<\?"), re.compile(r"\?>"), True), + (re.compile(r"^"), True), + (re.compile(r"^"), True), + ( + re.compile("^|$))", re.IGNORECASE), + re.compile(r"^$"), + True, + ), + (re.compile(HTML_OPEN_CLOSE_TAG_STR + "\\s*$"), re.compile(r"^$"), False), +] + + +def html_block(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug( + "entering html_block: %s, %s, %s, %s", state, startLine, endLine, silent + ) + pos = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + + if state.is_code_block(startLine): + return False + + if not state.md.options.get("html", None): + return False + + if state.src[pos] != "<": + return False + + lineText = state.src[pos:maximum] + + html_seq = None + for HTML_SEQUENCE in HTML_SEQUENCES: + if HTML_SEQUENCE[0].search(lineText): + html_seq = HTML_SEQUENCE + break + + if not html_seq: + return False + + if silent: + # true if this sequence can be a terminator, false otherwise + return html_seq[2] + + nextLine = startLine + 1 + + # If we are here - we detected HTML block. + # Let's roll down till block end. + if not html_seq[1].search(lineText): + while nextLine < endLine: + if state.sCount[nextLine] < state.blkIndent: + break + + pos = state.bMarks[nextLine] + state.tShift[nextLine] + maximum = state.eMarks[nextLine] + lineText = state.src[pos:maximum] + + if html_seq[1].search(lineText): + if len(lineText) != 0: + nextLine += 1 + break + nextLine += 1 + + state.line = nextLine + + token = state.push("html_block", "", 0) + token.map = [startLine, nextLine] + token.content = state.getLines(startLine, nextLine, state.blkIndent, True) + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/lheading.py b/.venv/Lib/site-packages/markdown_it/rules_block/lheading.py new file mode 100644 index 0000000..3522207 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/lheading.py @@ -0,0 +1,86 @@ +# lheading (---, ==) +import logging + +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def lheading(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug("entering lheading: %s, %s, %s, %s", state, startLine, endLine, silent) + + level = None + nextLine = startLine + 1 + ruler = state.md.block.ruler + terminatorRules = ruler.getRules("paragraph") + + if state.is_code_block(startLine): + return False + + oldParentType = state.parentType + state.parentType = "paragraph" # use paragraph to match terminatorRules + + # jump line-by-line until empty one or EOF + while nextLine < endLine and not state.isEmpty(nextLine): + # this would be a code block normally, but after paragraph + # it's considered a lazy continuation regardless of what's there + if state.sCount[nextLine] - state.blkIndent > 3: + nextLine += 1 + continue + + # Check for underline in setext header + if state.sCount[nextLine] >= state.blkIndent: + pos = state.bMarks[nextLine] + state.tShift[nextLine] + maximum = state.eMarks[nextLine] + + if pos < maximum: + marker = state.src[pos] + + if marker in ("-", "="): + pos = state.skipCharsStr(pos, marker) + pos = state.skipSpaces(pos) + + # /* = */ + if pos >= maximum: + level = 1 if marker == "=" else 2 + break + + # quirk for blockquotes, this line should already be checked by that rule + if state.sCount[nextLine] < 0: + nextLine += 1 + continue + + # Some tags can terminate paragraph without empty line. + terminate = False + for terminatorRule in terminatorRules: + if terminatorRule(state, nextLine, endLine, True): + terminate = True + break + if terminate: + break + + nextLine += 1 + + if not level: + # Didn't find valid underline + return False + + content = state.getLines(startLine, nextLine, state.blkIndent, False).strip() + + state.line = nextLine + 1 + + token = state.push("heading_open", "h" + str(level), 1) + token.markup = marker + token.map = [startLine, state.line] + + token = state.push("inline", "", 0) + token.content = content + token.map = [startLine, state.line - 1] + token.children = [] + + token = state.push("heading_close", "h" + str(level), -1) + token.markup = marker + + state.parentType = oldParentType + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/list.py b/.venv/Lib/site-packages/markdown_it/rules_block/list.py new file mode 100644 index 0000000..d8070d7 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/list.py @@ -0,0 +1,345 @@ +# Lists +import logging + +from ..common.utils import isStrSpace +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +# Search `[-+*][\n ]`, returns next pos after marker on success +# or -1 on fail. +def skipBulletListMarker(state: StateBlock, startLine: int) -> int: + pos = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + + try: + marker = state.src[pos] + except IndexError: + return -1 + pos += 1 + + if marker not in ("*", "-", "+"): + return -1 + + if pos < maximum: + ch = state.src[pos] + + if not isStrSpace(ch): + # " -test " - is not a list item + return -1 + + return pos + + +# Search `\d+[.)][\n ]`, returns next pos after marker on success +# or -1 on fail. +def skipOrderedListMarker(state: StateBlock, startLine: int) -> int: + start = state.bMarks[startLine] + state.tShift[startLine] + pos = start + maximum = state.eMarks[startLine] + + # List marker should have at least 2 chars (digit + dot) + if pos + 1 >= maximum: + return -1 + + ch = state.src[pos] + pos += 1 + + ch_ord = ord(ch) + # /* 0 */ /* 9 */ + if ch_ord < 0x30 or ch_ord > 0x39: + return -1 + + while True: + # EOL -> fail + if pos >= maximum: + return -1 + + ch = state.src[pos] + pos += 1 + + # /* 0 */ /* 9 */ + ch_ord = ord(ch) + if ch_ord >= 0x30 and ch_ord <= 0x39: + # List marker should have no more than 9 digits + # (prevents integer overflow in browsers) + if pos - start >= 10: + return -1 + + continue + + # found valid marker + if ch in (")", "."): + break + + return -1 + + if pos < maximum: + ch = state.src[pos] + + if not isStrSpace(ch): + # " 1.test " - is not a list item + return -1 + + return pos + + +def markTightParagraphs(state: StateBlock, idx: int) -> None: + level = state.level + 2 + + i = idx + 2 + length = len(state.tokens) - 2 + while i < length: + if state.tokens[i].level == level and state.tokens[i].type == "paragraph_open": + state.tokens[i + 2].hidden = True + state.tokens[i].hidden = True + i += 2 + i += 1 + + +def list_block(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug("entering list: %s, %s, %s, %s", state, startLine, endLine, silent) + + isTerminatingParagraph = False + tight = True + + if state.is_code_block(startLine): + return False + + # Special case: + # - item 1 + # - item 2 + # - item 3 + # - item 4 + # - this one is a paragraph continuation + if ( + state.listIndent >= 0 + and state.sCount[startLine] - state.listIndent >= 4 + and state.sCount[startLine] < state.blkIndent + ): + return False + + # limit conditions when list can interrupt + # a paragraph (validation mode only) + # Next list item should still terminate previous list item + # + # This code can fail if plugins use blkIndent as well as lists, + # but I hope the spec gets fixed long before that happens. + # + if ( + silent + and state.parentType == "paragraph" + and state.sCount[startLine] >= state.blkIndent + ): + isTerminatingParagraph = True + + # Detect list type and position after marker + posAfterMarker = skipOrderedListMarker(state, startLine) + if posAfterMarker >= 0: + isOrdered = True + start = state.bMarks[startLine] + state.tShift[startLine] + markerValue = int(state.src[start : posAfterMarker - 1]) + + # If we're starting a new ordered list right after + # a paragraph, it should start with 1. + if isTerminatingParagraph and markerValue != 1: + return False + else: + posAfterMarker = skipBulletListMarker(state, startLine) + if posAfterMarker >= 0: + isOrdered = False + else: + return False + + # If we're starting a new unordered list right after + # a paragraph, first line should not be empty. + if ( + isTerminatingParagraph + and state.skipSpaces(posAfterMarker) >= state.eMarks[startLine] + ): + return False + + # We should terminate list on style change. Remember first one to compare. + markerChar = state.src[posAfterMarker - 1] + + # For validation mode we can terminate immediately + if silent: + return True + + # Start list + listTokIdx = len(state.tokens) + + if isOrdered: + token = state.push("ordered_list_open", "ol", 1) + if markerValue != 1: + token.attrs = {"start": markerValue} + + else: + token = state.push("bullet_list_open", "ul", 1) + + token.map = listLines = [startLine, 0] + token.markup = markerChar + + # + # Iterate list items + # + + nextLine = startLine + prevEmptyEnd = False + terminatorRules = state.md.block.ruler.getRules("list") + + oldParentType = state.parentType + state.parentType = "list" + + while nextLine < endLine: + pos = posAfterMarker + maximum = state.eMarks[nextLine] + + initial = offset = ( + state.sCount[nextLine] + + posAfterMarker + - (state.bMarks[startLine] + state.tShift[startLine]) + ) + + while pos < maximum: + ch = state.src[pos] + + if ch == "\t": + offset += 4 - (offset + state.bsCount[nextLine]) % 4 + elif ch == " ": + offset += 1 + else: + break + + pos += 1 + + contentStart = pos + + # trimming space in "- \n 3" case, indent is 1 here + indentAfterMarker = 1 if contentStart >= maximum else offset - initial + + # If we have more than 4 spaces, the indent is 1 + # (the rest is just indented code block) + if indentAfterMarker > 4: + indentAfterMarker = 1 + + # " - test" + # ^^^^^ - calculating total length of this thing + indent = initial + indentAfterMarker + + # Run subparser & write tokens + token = state.push("list_item_open", "li", 1) + token.markup = markerChar + token.map = itemLines = [startLine, 0] + if isOrdered: + token.info = state.src[start : posAfterMarker - 1] + + # change current state, then restore it after parser subcall + oldTight = state.tight + oldTShift = state.tShift[startLine] + oldSCount = state.sCount[startLine] + + # - example list + # ^ listIndent position will be here + # ^ blkIndent position will be here + # + oldListIndent = state.listIndent + state.listIndent = state.blkIndent + state.blkIndent = indent + + state.tight = True + state.tShift[startLine] = contentStart - state.bMarks[startLine] + state.sCount[startLine] = offset + + if contentStart >= maximum and state.isEmpty(startLine + 1): + # workaround for this case + # (list item is empty, list terminates before "foo"): + # ~~~~~~~~ + # - + # + # foo + # ~~~~~~~~ + state.line = min(state.line + 2, endLine) + else: + # NOTE in list.js this was: + # state.md.block.tokenize(state, startLine, endLine, True) + # but tokeniz does not take the final parameter + state.md.block.tokenize(state, startLine, endLine) + + # If any of list item is tight, mark list as tight + if (not state.tight) or prevEmptyEnd: + tight = False + + # Item become loose if finish with empty line, + # but we should filter last element, because it means list finish + prevEmptyEnd = (state.line - startLine) > 1 and state.isEmpty(state.line - 1) + + state.blkIndent = state.listIndent + state.listIndent = oldListIndent + state.tShift[startLine] = oldTShift + state.sCount[startLine] = oldSCount + state.tight = oldTight + + token = state.push("list_item_close", "li", -1) + token.markup = markerChar + + nextLine = startLine = state.line + itemLines[1] = nextLine + + if nextLine >= endLine: + break + + contentStart = state.bMarks[startLine] + + # + # Try to check if list is terminated or continued. + # + if state.sCount[nextLine] < state.blkIndent: + break + + if state.is_code_block(startLine): + break + + # fail if terminating block found + terminate = False + for terminatorRule in terminatorRules: + if terminatorRule(state, nextLine, endLine, True): + terminate = True + break + + if terminate: + break + + # fail if list has another type + if isOrdered: + posAfterMarker = skipOrderedListMarker(state, nextLine) + if posAfterMarker < 0: + break + start = state.bMarks[nextLine] + state.tShift[nextLine] + else: + posAfterMarker = skipBulletListMarker(state, nextLine) + if posAfterMarker < 0: + break + + if markerChar != state.src[posAfterMarker - 1]: + break + + # Finalize list + if isOrdered: + token = state.push("ordered_list_close", "ol", -1) + else: + token = state.push("bullet_list_close", "ul", -1) + + token.markup = markerChar + + listLines[1] = nextLine + state.line = nextLine + + state.parentType = oldParentType + + # mark paragraphs tight if needed + if tight: + markTightParagraphs(state, listTokIdx) + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/paragraph.py b/.venv/Lib/site-packages/markdown_it/rules_block/paragraph.py new file mode 100644 index 0000000..5388a4b --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/paragraph.py @@ -0,0 +1,65 @@ +"""Paragraph.""" +import logging + +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def paragraph(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + LOGGER.debug( + "entering paragraph: %s, %s, %s, %s", state, startLine, endLine, silent + ) + + nextLine = startLine + 1 + ruler = state.md.block.ruler + terminatorRules = ruler.getRules("paragraph") + endLine = state.lineMax + + oldParentType = state.parentType + state.parentType = "paragraph" + + # jump line-by-line until empty one or EOF + while nextLine < endLine: + if state.isEmpty(nextLine): + break + # this would be a code block normally, but after paragraph + # it's considered a lazy continuation regardless of what's there + if state.sCount[nextLine] - state.blkIndent > 3: + nextLine += 1 + continue + + # quirk for blockquotes, this line should already be checked by that rule + if state.sCount[nextLine] < 0: + nextLine += 1 + continue + + # Some tags can terminate paragraph without empty line. + terminate = False + for terminatorRule in terminatorRules: + if terminatorRule(state, nextLine, endLine, True): + terminate = True + break + + if terminate: + break + + nextLine += 1 + + content = state.getLines(startLine, nextLine, state.blkIndent, False).strip() + + state.line = nextLine + + token = state.push("paragraph_open", "p", 1) + token.map = [startLine, state.line] + + token = state.push("inline", "", 0) + token.content = content + token.map = [startLine, state.line] + token.children = [] + + token = state.push("paragraph_close", "p", -1) + + state.parentType = oldParentType + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/reference.py b/.venv/Lib/site-packages/markdown_it/rules_block/reference.py new file mode 100644 index 0000000..b77944b --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/reference.py @@ -0,0 +1,215 @@ +import logging + +from ..common.utils import charCodeAt, isSpace, normalizeReference +from .state_block import StateBlock + +LOGGER = logging.getLogger(__name__) + + +def reference(state: StateBlock, startLine: int, _endLine: int, silent: bool) -> bool: + LOGGER.debug( + "entering reference: %s, %s, %s, %s", state, startLine, _endLine, silent + ) + + lines = 0 + pos = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + nextLine = startLine + 1 + + if state.is_code_block(startLine): + return False + + if state.src[pos] != "[": + return False + + # Simple check to quickly interrupt scan on [link](url) at the start of line. + # Can be useful on practice: https:#github.com/markdown-it/markdown-it/issues/54 + while pos < maximum: + # /* ] */ /* \ */ /* : */ + if state.src[pos] == "]" and state.src[pos - 1] != "\\": + if pos + 1 == maximum: + return False + if state.src[pos + 1] != ":": + return False + break + pos += 1 + + endLine = state.lineMax + + # jump line-by-line until empty one or EOF + terminatorRules = state.md.block.ruler.getRules("reference") + + oldParentType = state.parentType + state.parentType = "reference" + + while nextLine < endLine and not state.isEmpty(nextLine): + # this would be a code block normally, but after paragraph + # it's considered a lazy continuation regardless of what's there + if state.sCount[nextLine] - state.blkIndent > 3: + nextLine += 1 + continue + + # quirk for blockquotes, this line should already be checked by that rule + if state.sCount[nextLine] < 0: + nextLine += 1 + continue + + # Some tags can terminate paragraph without empty line. + terminate = False + for terminatorRule in terminatorRules: + if terminatorRule(state, nextLine, endLine, True): + terminate = True + break + + if terminate: + break + + nextLine += 1 + + string = state.getLines(startLine, nextLine, state.blkIndent, False).strip() + maximum = len(string) + + labelEnd = None + pos = 1 + while pos < maximum: + ch = charCodeAt(string, pos) + if ch == 0x5B: # /* [ */ + return False + elif ch == 0x5D: # /* ] */ + labelEnd = pos + break + elif ch == 0x0A: # /* \n */ + lines += 1 + elif ch == 0x5C: # /* \ */ + pos += 1 + if pos < maximum and charCodeAt(string, pos) == 0x0A: + lines += 1 + pos += 1 + + if ( + labelEnd is None or labelEnd < 0 or charCodeAt(string, labelEnd + 1) != 0x3A + ): # /* : */ + return False + + # [label]: destination 'title' + # ^^^ skip optional whitespace here + pos = labelEnd + 2 + while pos < maximum: + ch = charCodeAt(string, pos) + if ch == 0x0A: + lines += 1 + elif isSpace(ch): + pass + else: + break + pos += 1 + + # [label]: destination 'title' + # ^^^^^^^^^^^ parse this + res = state.md.helpers.parseLinkDestination(string, pos, maximum) + if not res.ok: + return False + + href = state.md.normalizeLink(res.str) + if not state.md.validateLink(href): + return False + + pos = res.pos + lines += res.lines + + # save cursor state, we could require to rollback later + destEndPos = pos + destEndLineNo = lines + + # [label]: destination 'title' + # ^^^ skipping those spaces + start = pos + while pos < maximum: + ch = charCodeAt(string, pos) + if ch == 0x0A: + lines += 1 + elif isSpace(ch): + pass + else: + break + pos += 1 + + # [label]: destination 'title' + # ^^^^^^^ parse this + res = state.md.helpers.parseLinkTitle(string, pos, maximum) + if pos < maximum and start != pos and res.ok: + title = res.str + pos = res.pos + lines += res.lines + else: + title = "" + pos = destEndPos + lines = destEndLineNo + + # skip trailing spaces until the rest of the line + while pos < maximum: + ch = charCodeAt(string, pos) + if not isSpace(ch): + break + pos += 1 + + if pos < maximum and charCodeAt(string, pos) != 0x0A and title: + # garbage at the end of the line after title, + # but it could still be a valid reference if we roll back + title = "" + pos = destEndPos + lines = destEndLineNo + while pos < maximum: + ch = charCodeAt(string, pos) + if not isSpace(ch): + break + pos += 1 + + if pos < maximum and charCodeAt(string, pos) != 0x0A: + # garbage at the end of the line + return False + + label = normalizeReference(string[1:labelEnd]) + if not label: + # CommonMark 0.20 disallows empty labels + return False + + # Reference can not terminate anything. This check is for safety only. + if silent: + return True + + if "references" not in state.env: + state.env["references"] = {} + + state.line = startLine + lines + 1 + + # note, this is not part of markdown-it JS, but is useful for renderers + if state.md.options.get("inline_definitions", False): + token = state.push("definition", "", 0) + token.meta = { + "id": label, + "title": title, + "url": href, + "label": string[1:labelEnd], + } + token.map = [startLine, state.line] + + if label not in state.env["references"]: + state.env["references"][label] = { + "title": title, + "href": href, + "map": [startLine, state.line], + } + else: + state.env.setdefault("duplicate_refs", []).append( + { + "title": title, + "href": href, + "label": label, + "map": [startLine, state.line], + } + ) + + state.parentType = oldParentType + + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/state_block.py b/.venv/Lib/site-packages/markdown_it/rules_block/state_block.py new file mode 100644 index 0000000..445ad26 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/state_block.py @@ -0,0 +1,261 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Literal + +from ..common.utils import isStrSpace +from ..ruler import StateBase +from ..token import Token +from ..utils import EnvType + +if TYPE_CHECKING: + from markdown_it.main import MarkdownIt + + +class StateBlock(StateBase): + def __init__( + self, src: str, md: MarkdownIt, env: EnvType, tokens: list[Token] + ) -> None: + self.src = src + + # link to parser instance + self.md = md + + self.env = env + + # + # Internal state variables + # + + self.tokens = tokens + + self.bMarks: list[int] = [] # line begin offsets for fast jumps + self.eMarks: list[int] = [] # line end offsets for fast jumps + # offsets of the first non-space characters (tabs not expanded) + self.tShift: list[int] = [] + self.sCount: list[int] = [] # indents for each line (tabs expanded) + + # An amount of virtual spaces (tabs expanded) between beginning + # of each line (bMarks) and real beginning of that line. + # + # It exists only as a hack because blockquotes override bMarks + # losing information in the process. + # + # It's used only when expanding tabs, you can think about it as + # an initial tab length, e.g. bsCount=21 applied to string `\t123` + # means first tab should be expanded to 4-21%4 === 3 spaces. + # + self.bsCount: list[int] = [] + + # block parser variables + self.blkIndent = 0 # required block content indent (for example, if we are + # inside a list, it would be positioned after list marker) + self.line = 0 # line index in src + self.lineMax = 0 # lines count + self.tight = False # loose/tight mode for lists + self.ddIndent = -1 # indent of the current dd block (-1 if there isn't any) + self.listIndent = -1 # indent of the current list block (-1 if there isn't any) + + # can be 'blockquote', 'list', 'root', 'paragraph' or 'reference' + # used in lists to determine if they interrupt a paragraph + self.parentType = "root" + + self.level = 0 + + # renderer + self.result = "" + + # Create caches + # Generate markers. + indent_found = False + + start = pos = indent = offset = 0 + length = len(self.src) + + for pos, character in enumerate(self.src): + if not indent_found: + if isStrSpace(character): + indent += 1 + + if character == "\t": + offset += 4 - offset % 4 + else: + offset += 1 + continue + else: + indent_found = True + + if character == "\n" or pos == length - 1: + if character != "\n": + pos += 1 + self.bMarks.append(start) + self.eMarks.append(pos) + self.tShift.append(indent) + self.sCount.append(offset) + self.bsCount.append(0) + + indent_found = False + indent = 0 + offset = 0 + start = pos + 1 + + # Push fake entry to simplify cache bounds checks + self.bMarks.append(length) + self.eMarks.append(length) + self.tShift.append(0) + self.sCount.append(0) + self.bsCount.append(0) + + self.lineMax = len(self.bMarks) - 1 # don't count last fake line + + # pre-check if code blocks are enabled, to speed up is_code_block method + self._code_enabled = "code" in self.md["block"].ruler.get_active_rules() + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}" + f"(line={self.line},level={self.level},tokens={len(self.tokens)})" + ) + + def push(self, ttype: str, tag: str, nesting: Literal[-1, 0, 1]) -> Token: + """Push new token to "stream".""" + token = Token(ttype, tag, nesting) + token.block = True + if nesting < 0: + self.level -= 1 # closing tag + token.level = self.level + if nesting > 0: + self.level += 1 # opening tag + self.tokens.append(token) + return token + + def isEmpty(self, line: int) -> bool: + """.""" + return (self.bMarks[line] + self.tShift[line]) >= self.eMarks[line] + + def skipEmptyLines(self, from_pos: int) -> int: + """.""" + while from_pos < self.lineMax: + try: + if (self.bMarks[from_pos] + self.tShift[from_pos]) < self.eMarks[ + from_pos + ]: + break + except IndexError: + pass + from_pos += 1 + return from_pos + + def skipSpaces(self, pos: int) -> int: + """Skip spaces from given position.""" + while True: + try: + current = self.src[pos] + except IndexError: + break + if not isStrSpace(current): + break + pos += 1 + return pos + + def skipSpacesBack(self, pos: int, minimum: int) -> int: + """Skip spaces from given position in reverse.""" + if pos <= minimum: + return pos + while pos > minimum: + pos -= 1 + if not isStrSpace(self.src[pos]): + return pos + 1 + return pos + + def skipChars(self, pos: int, code: int) -> int: + """Skip character code from given position.""" + while True: + try: + current = self.srcCharCode[pos] + except IndexError: + break + if current != code: + break + pos += 1 + return pos + + def skipCharsStr(self, pos: int, ch: str) -> int: + """Skip character string from given position.""" + while True: + try: + current = self.src[pos] + except IndexError: + break + if current != ch: + break + pos += 1 + return pos + + def skipCharsBack(self, pos: int, code: int, minimum: int) -> int: + """Skip character code reverse from given position - 1.""" + if pos <= minimum: + return pos + while pos > minimum: + pos -= 1 + if code != self.srcCharCode[pos]: + return pos + 1 + return pos + + def skipCharsStrBack(self, pos: int, ch: str, minimum: int) -> int: + """Skip character string reverse from given position - 1.""" + if pos <= minimum: + return pos + while pos > minimum: + pos -= 1 + if ch != self.src[pos]: + return pos + 1 + return pos + + def getLines(self, begin: int, end: int, indent: int, keepLastLF: bool) -> str: + """Cut lines range from source.""" + line = begin + if begin >= end: + return "" + + queue = [""] * (end - begin) + + i = 1 + while line < end: + lineIndent = 0 + lineStart = first = self.bMarks[line] + last = ( + self.eMarks[line] + 1 + if line + 1 < end or keepLastLF + else self.eMarks[line] + ) + + while (first < last) and (lineIndent < indent): + ch = self.src[first] + if isStrSpace(ch): + if ch == "\t": + lineIndent += 4 - (lineIndent + self.bsCount[line]) % 4 + else: + lineIndent += 1 + elif first - lineStart < self.tShift[line]: + lineIndent += 1 + else: + break + first += 1 + + if lineIndent > indent: + # partially expanding tabs in code blocks, e.g '\t\tfoobar' + # with indent=2 becomes ' \tfoobar' + queue[i - 1] = (" " * (lineIndent - indent)) + self.src[first:last] + else: + queue[i - 1] = self.src[first:last] + + line += 1 + i += 1 + + return "".join(queue) + + def is_code_block(self, line: int) -> bool: + """Check if line is a code block, + i.e. the code block rule is enabled and text is indented by more than 3 spaces. + """ + return self._code_enabled and (self.sCount[line] - self.blkIndent) >= 4 diff --git a/.venv/Lib/site-packages/markdown_it/rules_block/table.py b/.venv/Lib/site-packages/markdown_it/rules_block/table.py new file mode 100644 index 0000000..4b666c1 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_block/table.py @@ -0,0 +1,236 @@ +# GFM table, https://github.github.com/gfm/#tables-extension- +from __future__ import annotations + +import re + +from ..common.utils import charStrAt, isStrSpace +from .state_block import StateBlock + +headerLineRe = re.compile(r"^:?-+:?$") +enclosingPipesRe = re.compile(r"^\||\|$") + + +def getLine(state: StateBlock, line: int) -> str: + pos = state.bMarks[line] + state.tShift[line] + maximum = state.eMarks[line] + + # return state.src.substr(pos, max - pos) + return state.src[pos:maximum] + + +def escapedSplit(string: str) -> list[str]: + result: list[str] = [] + pos = 0 + max = len(string) + isEscaped = False + lastPos = 0 + current = "" + ch = charStrAt(string, pos) + + while pos < max: + if ch == "|": + if not isEscaped: + # pipe separating cells, '|' + result.append(current + string[lastPos:pos]) + current = "" + lastPos = pos + 1 + else: + # escaped pipe, '\|' + current += string[lastPos : pos - 1] + lastPos = pos + + isEscaped = ch == "\\" + pos += 1 + + ch = charStrAt(string, pos) + + result.append(current + string[lastPos:]) + + return result + + +def table(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + tbodyLines = None + + # should have at least two lines + if startLine + 2 > endLine: + return False + + nextLine = startLine + 1 + + if state.sCount[nextLine] < state.blkIndent: + return False + + if state.is_code_block(nextLine): + return False + + # first character of the second line should be '|', '-', ':', + # and no other characters are allowed but spaces; + # basically, this is the equivalent of /^[-:|][-:|\s]*$/ regexp + + pos = state.bMarks[nextLine] + state.tShift[nextLine] + if pos >= state.eMarks[nextLine]: + return False + first_ch = state.src[pos] + pos += 1 + if first_ch not in ("|", "-", ":"): + return False + + if pos >= state.eMarks[nextLine]: + return False + second_ch = state.src[pos] + pos += 1 + if second_ch not in ("|", "-", ":") and not isStrSpace(second_ch): + return False + + # if first character is '-', then second character must not be a space + # (due to parsing ambiguity with list) + if first_ch == "-" and isStrSpace(second_ch): + return False + + while pos < state.eMarks[nextLine]: + ch = state.src[pos] + + if ch not in ("|", "-", ":") and not isStrSpace(ch): + return False + + pos += 1 + + lineText = getLine(state, startLine + 1) + + columns = lineText.split("|") + aligns = [] + for i in range(len(columns)): + t = columns[i].strip() + if not t: + # allow empty columns before and after table, but not in between columns; + # e.g. allow ` |---| `, disallow ` ---||--- ` + if i == 0 or i == len(columns) - 1: + continue + else: + return False + + if not headerLineRe.search(t): + return False + if charStrAt(t, len(t) - 1) == ":": + aligns.append("center" if charStrAt(t, 0) == ":" else "right") + elif charStrAt(t, 0) == ":": + aligns.append("left") + else: + aligns.append("") + + lineText = getLine(state, startLine).strip() + if "|" not in lineText: + return False + if state.is_code_block(startLine): + return False + columns = escapedSplit(lineText) + if columns and columns[0] == "": + columns.pop(0) + if columns and columns[-1] == "": + columns.pop() + + # header row will define an amount of columns in the entire table, + # and align row should be exactly the same (the rest of the rows can differ) + columnCount = len(columns) + if columnCount == 0 or columnCount != len(aligns): + return False + + if silent: + return True + + oldParentType = state.parentType + state.parentType = "table" + + # use 'blockquote' lists for termination because it's + # the most similar to tables + terminatorRules = state.md.block.ruler.getRules("blockquote") + + token = state.push("table_open", "table", 1) + token.map = tableLines = [startLine, 0] + + token = state.push("thead_open", "thead", 1) + token.map = [startLine, startLine + 1] + + token = state.push("tr_open", "tr", 1) + token.map = [startLine, startLine + 1] + + for i in range(len(columns)): + token = state.push("th_open", "th", 1) + if aligns[i]: + token.attrs = {"style": "text-align:" + aligns[i]} + + token = state.push("inline", "", 0) + # note in markdown-it this map was removed in v12.0.0 however, we keep it, + # since it is helpful to propagate to children tokens + token.map = [startLine, startLine + 1] + token.content = columns[i].strip() + token.children = [] + + token = state.push("th_close", "th", -1) + + token = state.push("tr_close", "tr", -1) + token = state.push("thead_close", "thead", -1) + + nextLine = startLine + 2 + while nextLine < endLine: + if state.sCount[nextLine] < state.blkIndent: + break + + terminate = False + for i in range(len(terminatorRules)): + if terminatorRules[i](state, nextLine, endLine, True): + terminate = True + break + + if terminate: + break + lineText = getLine(state, nextLine).strip() + if not lineText: + break + if state.is_code_block(nextLine): + break + columns = escapedSplit(lineText) + if columns and columns[0] == "": + columns.pop(0) + if columns and columns[-1] == "": + columns.pop() + + if nextLine == startLine + 2: + token = state.push("tbody_open", "tbody", 1) + token.map = tbodyLines = [startLine + 2, 0] + + token = state.push("tr_open", "tr", 1) + token.map = [nextLine, nextLine + 1] + + for i in range(columnCount): + token = state.push("td_open", "td", 1) + if aligns[i]: + token.attrs = {"style": "text-align:" + aligns[i]} + + token = state.push("inline", "", 0) + # note in markdown-it this map was removed in v12.0.0 however, we keep it, + # since it is helpful to propagate to children tokens + token.map = [nextLine, nextLine + 1] + try: + token.content = columns[i].strip() if columns[i] else "" + except IndexError: + token.content = "" + token.children = [] + + token = state.push("td_close", "td", -1) + + token = state.push("tr_close", "tr", -1) + + nextLine += 1 + + if tbodyLines: + token = state.push("tbody_close", "tbody", -1) + tbodyLines[1] = nextLine + + token = state.push("table_close", "table", -1) + + tableLines[1] = nextLine + state.parentType = oldParentType + state.line = nextLine + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__init__.py b/.venv/Lib/site-packages/markdown_it/rules_core/__init__.py new file mode 100644 index 0000000..c9c5368 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/__init__.py @@ -0,0 +1,19 @@ +__all__ = ( + "StateCore", + "normalize", + "block", + "inline", + "replace", + "smartquotes", + "linkify", + "text_join", +) + +from .block import block +from .inline import inline +from .linkify import linkify +from .normalize import normalize +from .replacements import replace +from .smartquotes import smartquotes +from .state_core import StateCore +from .text_join import text_join diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58b5c6a182bc41212a1a609606d3d7a9330d45a4 GIT binary patch literal 566 zcmXw#L2DE-6vva9*~!eTMZ5@#hY>{BgY8|4AT7m;l)~a=2!wPd+Uz8gHAz>uC(j;w z^)vWc{04#X(v!DB@#4uOQ{UnJf8pi*dGGz)*{Oh!w^#e;-yi_j;qgC`JGedf@EvrZ z0UhiT0VQl844jHYCQTAK6RAv_H1bSjGHbHPxtPhk$s;3yBx+FPLKL!W%E+atWYts< zY^%k5QMhtxsbvRBGgl5uODgy!bF(v{+TP`S5PV<`X|@)$Wo~XH)%MecvdlQ-Yd!z4 zb){urELkZ&{Pv511=QIjvq_3c(n<13&?I4V-%xrvS%u)**688+Oq7i(XlADO}a5`CvW4}{x2eIb~M z1MCsP2W|=3U2k2nFIDGDuk-^yO1O=A?$b>QA-qY-dGZzgc?jU65j-BjlM&P-cshb- MKK}x>zVE;O14Jp4aR2}S literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/block.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/block.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1185d8b89a7b34ff963ddb83505c955aea336101 GIT binary patch literal 998 zcmZ`&&r4K69G}^@@9nJYnneCsG+2Xzh0=RSAexkw2 zLO->WjBJaX-v+XcD5BUyKAy!G(F`@bjBm^uz_ZMtCbgbrY3^lqHoIz7$Y};jDp;9M z!#WF2p|ke#Q__)aB;-t)LQ`dNCYN|H;p&WJSU?Q;&L?4Z8?B*Q68Q)DxYRlEpjhiU zX!*}ER3zGy6u>n+msS`wyO4pIzj+HfZYJr_p^)$tYgba9ur++p(vH!p*4mLoQmkD~ zdBSR)2}|)mx-absxm{^x!Yw{8; z;I7KKVIWx`mEk*)BJN_?e=a(sJ~iMk9Ud#XxVd6I`U=1O6YIYJIkJ}fVb@|fp{y8Xa$ z>x`F2!&+z$EJJVmadqAnRmtu|5ONlnuziQuX}A*1RplUG@|c)&;jst X=>+wkSp+}ATctCku_1rO7`ONXY%$S? literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/inline.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/inline.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be4146532ad28adfe27c9109007b91317f9eb010 GIT binary patch literal 837 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 PogS|eP2XcMDOUUs9#xK9 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/normalize.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/normalize.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f0bf77f1ef6eeecaa6748422f96be485fcd50e7 GIT binary patch literal 826 zcmZ`$&1(}u6rb5mcJpD{9<;3#VHG?i(AI+rm7++RU?qfNEMhvaY<9-Fn`Af4Y$}aW za!_b4rg&+N@g&l}LHq+e=Az?8P!ByBXiuJ;Nt#wfAI$H4f6RLy6NwlQbobTrpa25h$T;bg zID(Z&Asl@XD(c%xGS-;M`?P9RoCYx*uT~EX7Es6ATsV+*^9Qm)67pyvumY0yDQQFy zMc%C@@)`=d!oy5DxJF4(r=ER0kIV(~cdB@Y&jsuO`Nt8t()t%+*aYr)AAk7vm67rc z2HM#C&wQl`Ph*>+nt7ZFz&1##c@ATB+4tv%_sI~C=Q9s-tNBd9yqDoBtCs{&o9p@Y zTuzvh3Jr@`u8o$#WGTb=^)!70tusOyDp*ytLRdNQYpCF0Vysc$C3e72)?&f!wN+z_ z8QF@(%IJ<|mkBjieAh<{Tg2N!Ij4k}6Oj3ua9Nv#p{hm8*ni@gPOwPp6~atgta{NK zpJt)9&7&t8ofPB5#bb*CTHt$Pwqv%Fw>#ILxZH|=ik;oL)Je5d ayX*bfTuUElI-J>kH~@n6t{zD?Z1Nj(0K!oK literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/replacements.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/replacements.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2da780105c3b8b3de2819f41714160af108fc923 GIT binary patch literal 4939 zcmb7HUrbY38o#&ypuKJ7Un!Ie7KM?PwhqoX8blPKDh{+RU^2lnwf0`2rT_NaTW7&C z>4TZTgp4>&LP<8k*=%+oPDXtieA4k{cC!x)7K6FVCPdu_-!!-{`?TM=?QI!DaXEx@ zzVrLO^PO|g`Ofcr{ku-5A)uW5rfuXK9YMUn9jPcX0=YRLBZygoAqEMCWMm;SEE|-O zSeA$6gL1J|3@R7}qYNp-szDX#R7_E*C|o>POcFAJl?Tftr}>uE+#xf)K?-aX!K%DY zl9=M0jjo`L8phJnhVp_&_wmxnAMe22eQ=9c3f0@J)iAx*zmxXB4sHw5Qpg@Hjket|@Sj1T*>903}Fz>EYoR1h3)*IsKJ_ z7$Yo2E`&c-Q1I*@ctITsL`J>Q7#k53zBnHh<44els6Q0tSc?iQ$6~CY-x5*YKBpk( z;+Mq}6N>!N2oEeLC<2iy(M7qS4Me~JE8c2O*b|6w5KUg}9{UxPJihK64tBHIjLPw9 z^w}uza(-A0gBk#AhktGiswDBO(wKC=D6O4TKBG!*v`)3ADxXk$7x%2w)-~F(LOXsO zTWWl0e_&73XD6N0y&GApnkQ7lg5j=d(RAI%I&^w~sOgmYKw?YPKR(7Pk@l|I8)2-uLwys`H)Z!Em$3Qvo}0dIW^{u4-B96th{ zmgmXua?&k?w+Z0~Qsg#-S76bj8fb)~zK%X8CNmYs`jCGF;fF`io$tBO@9ph&LEYy> zwHTwEJw4s$`@1nBm~)-qU2ygfbh}+%=VzTg9laf*3>L;hisDXpZ*K>7qH*?myE^*M zW@J}RE_G(*ZdaGnHGo&J7gm7GQ2mxOwGw9{A7arV(Dz`QPvHH_GUiLnm>b&C8|S9Z zr9Mb&&4Qs}y~H@Hzo}2f=O^YSo|f3(s)$-3QTqyQUtsPzf9}2Co2E};62+RPdH0-q z!FliS&&Tf{PtzR|eteBSxk8_OWc+L6KkR=4+Wib`*6EMd=p!riktOQUgm}A zB2D*Vdx_28Pxq^Nx?j!H{nzd{$G4?>{FsYL1urHQkfH(bZVBd6hrA|;N4`@ya*O~E z+mJh?DU;%3PX=?;o*&GRqembB$m#L~xn0tbB&W?=halplNwoYg>SZ)RiGv;;oD-72}%zC)x<=KkP&I4RfhW{~XT|!B(#l!-J3617R6U{UpJ^+wb^BENveLF4saiGw@V>qR(E5Q;+4;o(4JSdanB;GII4Wd)76 zbz)90dK1*cEZ+mBa2my4Z^Rb{4}z-4eddg_59f&CSRllTyDw$)*{3+mc_KPxGfxI z;I~IR`V=r6?_4?5ujM33zLDuk#eeDua{miL|4%~wZ=(8NME!=^G-+H@n^x4O)X}uM zA*p(;B`Cw>z8lsl>$2hFwB~TK2%s{0rfk-9)0A@GJA}D$wX`Ft-zYK7$YwP+HK|Y1 zCHs=P4Sm(*cb`3L+u0Ys?M3zY=N6${(-16SmNBe%Y{bF0Ka4!?3uT_MhI>j#>UeUKCsZAA09^5RZ$ofsXo~(a+mei9L Hant?>u#WRR literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/smartquotes.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_core/__pycache__/smartquotes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cc3fbbee3ba58292b8a38b3c92f9a329e95d65b GIT binary patch literal 6170 zcmcgQZA=_Tmen&o-`~Rw3=C!l3^qe-ClH8%#LkW}#wKh00oh~;K5jDIfr0se>c)Ji zXV-Vy(~Wnn&7eeLP%L>YuarSv$=pAzv$VeZWoiG=kX_m>B8_*mIw75O_?-K5Kkn{T z4>J(L?fR7HO6snvSFhejz4xkK)o(2pBZAWV%eO|$4k7eM(kT{op+UWP1dRp6ph3h? zj4DdSRD&vtwAE4dpc-mAO2;&V8h~jSZB!f64eDb0L4C|HXowjHjS5^BHO0(>W@zgf zL(~$p4q7RsLachMrpR!&W{mf#LT}Li5;zXVH0We(jQMBuU>Rd)EKs``2V;fWJ*y5l z=i0gw@#`$+{Tz=&k&#i}KRK1)LwqC=_s2qbob&SuKR-K>7{Q^5(MZ^zh_jq=i^ve5 zWK$>}-@)ekpsx;Qtr6}b6Xe2?$mOYcn3qivPHA)jifoQ> z?~O)ywtpfNW`T%iATiFyw}_t5GxUQrY*zxabD9s14%J_ik+D#+t9kjMca*9^ZKXj_ZSj&$(novXAv z)hU@A=_Bd3)alF_(NvQy&uNyaB}2}%TH7j`T36}T7cdEhiQ2_tfQGV){{^iDG=h>U ze#hO&x)ojTEK1YY{uQAin4455X@MTwOJ#>zQo~S5Ew3pO=XJ%Fpej--)(lvPQT?5| z5>U>fYc`;(6;y(j^ce*zXvV8RQR#ty33GLl6(n{(;TKygwbw$~d20TZALdkB`ry-U>+lO+gBK>h%cCkHU*uMdcY=@-dA?98U1)8XkcRuN&8Dv zhBYX}2(IJZMbaSm%Ss0G@9$VWX^;PO*Uo~vsKq|3jw{vzTM?@sXd@%hgL6WJ{_i*@ zf`eh3jdz#u4zMSzcE=vQiWCpP++*`UgH_Urp8JO8AO}SwSb0a$OR!}RU!9;Yt&$@i z+q+5y>+a=VaY*tbkx=&=fU8;aUpu5SN7_*o!*NP@D@! zi0PHWdyB1IoFZ=0DL4+K<|tzP8EPe*B5ty*B%28&fWy2{cKIe|5e`p$uyU7e@i#tPC}$=QVs z(6W(T57Uem_6;lWvH%Aw2HwyvgMGxpwF_464Z((6cwb4g19!NWi)`Lsq;h}fd==>7 z(jJ~x-THgMnx^p2c0GBI2mghAJxyKvYsH^;cJ^fXxAu7ODy*hZnu=c(${9Ox7s00N z3e+wCx3I}>LESo5gabVr?h&Z5x}pxd^;rFGyVx2#Qf%$kjDzq@R(wY)PKAmme(pQc zp}rSs=z=ugkB11JgFIsoZ3LDpBOJ+h&{+%PE;1%mlqh{;&aS@+drxFfF`{ATggto9 z0(R0Dc?oJIf?yZk)# zsKx@I&b}h3UoPSVo1kIbx9Os+z~c>w@z(#Zm@b`LD$r*FzJH_9EDDqtGUBcOh9YaC z>~%J(WXCeivorj;0hv0w~Z1*6<|Jm(>#qEr4g6??`yp8`nHs|$!hmQc>tdmqNNg%58%Gj+VmL7cD#-@89Pk&ED+a}bDxvr# zU?S_G(G^W_tgMf4{mQz@dV;E4nDlY5fYP!7CxGtWr2xcXbovtXOI zW$EmXvxBSt*VgULso>Kxmt=S6Ya3S04XK{=sN^hLI68kcQ~OC%W>$1I=9)$4u~e5- z;aQlTpUzBvGMDWaD;iVhxAmwVs=Uqq@$}8<^yDw*G8aT!Lyi({f!vif+lftYLzc+} zAM`BsEC=uRu2hQ0&OE*%9y_=0?U~nqRaujn{LFK=K6@rxf4e3flqwEoLi4i=KbikY z&bwC8x}sf~d}#QM^`Z62D{JlVKJ^^Rduy|`iya%@V{6`HlE?p*FOWO3>{tqHG`%S{ zz4@sBarqPKpDH(kSH%_mj)=5rdkb<|>HV^y;eXMEZPY`kAeKv3=W$yiIAH1V8<=vZ}l7 z&&s@;^~WX8p*xmEOLp?}>ATap$$N9l7sR8d9?iW_s~XDF-Jf23u0@W@KiDe3Gj4O) zw$J9)E1Q;Db60b%zpH!={KMtPb2T*8!d)dk#qz-pqM$9M5`1 z^D?^<{D;w%Y4MGoCmri=3`oBE?3Klt4E@Y|SZX}}K)+x)yu$|K~ZG-mi@)&>~gW-nqDVG1vUy5PdD8rzNA7yuPe%@l-Cj<~=S|`+oI$cJ|)s z<)C=DO{{Lqbme{Zcan?A482(g5qU3=(dGRO*$=amSwlu6H3Tw72(Ile3RN{fKT9E3 zjZ}Li-TTy44d#TsVZl6a&ezsSKL4HR#p&$iXLGp=qOVP=Ym#c4o*Ojo^8Zll9M0!< z6}Wm1Kzc<%`brMV zeFYv4;4y{s@sNfU$`~YL`wPsq?uWsn!HzbNxVHd?{o5Efs9SIIr3a6Lao{m(=K@Nh zTR&0~7FD0DEgV1rBPMAFCa+?$sq}csV%$o=jpWxvey@-pN!{SU9gRd8%*K_oE1<${ zWQe3B9O2{l7fw3Up0_xB2?qX|V8CUKoN{pVwBKysFnL9jcf)ja&2&`KTl0?ch3ZeM zQyMZ%PA1QqsrJ{N2fiiWiu*T*9v=E4&;th*89jaTv}kJBG&o> zXN}?o0X-%UO|lvuCNWtxSsjVrl%cQHtEI);FlL!wF%f{j1kEVbyJ3NfR@sO;-EM!2l6Off) z;#0CYoQTB|@e@;gB+Bi}vI+?nSw~EKMK(f4#xtnK?)YpzZFX`@K$;n6Dttk;@*Ydwwj`-=PHV#|AgxPhzwt% z@_#{>*U{xKQRSDYHgB&=s}_v&#!UOVz5a$pGPzSN#60QIb(8OgUb47v7++{eSmlgi%OMJM0>9)BvV6#hVEsS*hFz%5eY!im{+A`ok7_M4sY>^I-emul4nT=(8BJfBwpz6)ot z^a7BxZ3IUUKtLjhi9?9MN~FZ9qas!VEz)A$(IwWSQe1Y*5|^S%Y&Zr1swbGw2h2=tJ4x^=DN?CLHaUT%NoTkh3#KS&Sua*0tyZZz)=ir z#(@97Kns)u-BCNFruVO0Oc|{=`U1(4f)Q3FXAfn?F6n|N1HyC_^vJ;Ns_2P)xw_gb z!W9BLfTw+4fKsEU4RShAQ|c>tyUJN3SK=U7X|k7>GSM;5%`l0=gs!In#T<>(Xq#2> zUp6evh%lpQxZrDx^}D+`?>^#`ad*>?-6hJKS=w?p!+_cwEZwDzjJqp7&u(w5*?Zhx ziG1F4SN%qlGJ7fAP2Jf&B;Y;>pSe8D=*<>}{2j{OxUaVtW^=3^QSLQRsyQy+Ny6Dy zC$D&3n1q?EPQ;3&^o?! z?NEC=a)#+R5A~WU`$m~ERy1#5pirP9kdR@2EDCw{L{7_7yKC3egytnivo=d|O?Wj; zP)z)odR}gNUYrKl3gRKpd(rlzBElxH*e76MG1=%!HjT$!_|bB4u-K<@;Qc& z6M-F$9bh7dIRboZ0RaFUv2fk@2zDqAqbOveMt!k`S3`!Qptj~yZh#l7(e9CqM1kXy zDxm`4Rs~^QeHjwFfLCe)uMmhOm~hvL2$uS3!o_j%e> zICOGNB87mIs;5pxN>wHSDdTDNlzp7*fB0&N?@V1~Z`M^WJpf0ZirMuWJM!67%KG!! zAp~cfqTTLA$W?8qQkQn^x?1izlK$E2sqYT6RnYDo4b`Cv_Hm_lA8KezDeBvc|DI7f zNQbk)$(*9l#> z-uG85?hEo-1SV&VaI5ODiWhEB+ZPw*%jC8TlYB9`Yx0Dmt+?k{VrL-7^~9X+yo82lI%m-6)K30M z_LXO2XkhXHvPSbojlBRn%fJ%rjEEYeu{Ix4Qq0B~+x9}&wqwJ#S8HG*w$0>-#_6P4 zOg`+`NZOdxDuGD~^DSa8OWZTkBYUkHdQi|C41*}=mk+|yNhyl*Ow|?bk3OV~{e}j9 NL8HIx1!XFU{Tt^OjZgpp literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/block.py b/.venv/Lib/site-packages/markdown_it/rules_core/block.py new file mode 100644 index 0000000..a6c3bb8 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/block.py @@ -0,0 +1,13 @@ +from ..token import Token +from .state_core import StateCore + + +def block(state: StateCore) -> None: + if state.inlineMode: + token = Token("inline", "", 0) + token.content = state.src + token.map = [0, 1] + token.children = [] + state.tokens.append(token) + else: + state.md.block.parse(state.src, state.md, state.env, state.tokens) diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/inline.py b/.venv/Lib/site-packages/markdown_it/rules_core/inline.py new file mode 100644 index 0000000..c3fd0b5 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/inline.py @@ -0,0 +1,10 @@ +from .state_core import StateCore + + +def inline(state: StateCore) -> None: + """Parse inlines""" + for token in state.tokens: + if token.type == "inline": + if token.children is None: + token.children = [] + state.md.inline.parse(token.content, state.md, state.env, token.children) diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/linkify.py b/.venv/Lib/site-packages/markdown_it/rules_core/linkify.py new file mode 100644 index 0000000..efbc9d4 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/linkify.py @@ -0,0 +1,149 @@ +from __future__ import annotations + +import re +from typing import Protocol + +from ..common.utils import arrayReplaceAt, isLinkClose, isLinkOpen +from ..token import Token +from .state_core import StateCore + +HTTP_RE = re.compile(r"^http://") +MAILTO_RE = re.compile(r"^mailto:") +TEST_MAILTO_RE = re.compile(r"^mailto:", flags=re.IGNORECASE) + + +def linkify(state: StateCore) -> None: + """Rule for identifying plain-text links.""" + if not state.md.options.linkify: + return + + if not state.md.linkify: + raise ModuleNotFoundError("Linkify enabled but not installed.") + + for inline_token in state.tokens: + if inline_token.type != "inline" or not state.md.linkify.pretest( + inline_token.content + ): + continue + + tokens = inline_token.children + + htmlLinkLevel = 0 + + # We scan from the end, to keep position when new tags added. + # Use reversed logic in links start/end match + assert tokens is not None + i = len(tokens) + while i >= 1: + i -= 1 + assert isinstance(tokens, list) + currentToken = tokens[i] + + # Skip content of markdown links + if currentToken.type == "link_close": + i -= 1 + while ( + tokens[i].level != currentToken.level + and tokens[i].type != "link_open" + ): + i -= 1 + continue + + # Skip content of html tag links + if currentToken.type == "html_inline": + if isLinkOpen(currentToken.content) and htmlLinkLevel > 0: + htmlLinkLevel -= 1 + if isLinkClose(currentToken.content): + htmlLinkLevel += 1 + if htmlLinkLevel > 0: + continue + + if currentToken.type == "text" and state.md.linkify.test( + currentToken.content + ): + text = currentToken.content + links: list[_LinkType] = state.md.linkify.match(text) or [] + + # Now split string to nodes + nodes = [] + level = currentToken.level + lastPos = 0 + + # forbid escape sequence at the start of the string, + # this avoids http\://example.com/ from being linkified as + # http://example.com/ + if ( + links + and links[0].index == 0 + and i > 0 + and tokens[i - 1].type == "text_special" + ): + links = links[1:] + + for link in links: + url = link.url + fullUrl = state.md.normalizeLink(url) + if not state.md.validateLink(fullUrl): + continue + + urlText = link.text + + # Linkifier might send raw hostnames like "example.com", where url + # starts with domain name. So we prepend http:// in those cases, + # and remove it afterwards. + if not link.schema: + urlText = HTTP_RE.sub( + "", state.md.normalizeLinkText("http://" + urlText) + ) + elif link.schema == "mailto:" and TEST_MAILTO_RE.search(urlText): + urlText = MAILTO_RE.sub( + "", state.md.normalizeLinkText("mailto:" + urlText) + ) + else: + urlText = state.md.normalizeLinkText(urlText) + + pos = link.index + + if pos > lastPos: + token = Token("text", "", 0) + token.content = text[lastPos:pos] + token.level = level + nodes.append(token) + + token = Token("link_open", "a", 1) + token.attrs = {"href": fullUrl} + token.level = level + level += 1 + token.markup = "linkify" + token.info = "auto" + nodes.append(token) + + token = Token("text", "", 0) + token.content = urlText + token.level = level + nodes.append(token) + + token = Token("link_close", "a", -1) + level -= 1 + token.level = level + token.markup = "linkify" + token.info = "auto" + nodes.append(token) + + lastPos = link.last_index + + if lastPos < len(text): + token = Token("text", "", 0) + token.content = text[lastPos:] + token.level = level + nodes.append(token) + + inline_token.children = tokens = arrayReplaceAt(tokens, i, nodes) + + +class _LinkType(Protocol): + url: str + text: str + index: int + last_index: int + schema: str | None diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/normalize.py b/.venv/Lib/site-packages/markdown_it/rules_core/normalize.py new file mode 100644 index 0000000..c9f8d0d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/normalize.py @@ -0,0 +1,18 @@ +"""Normalize input string.""" +import re + +from .state_core import StateCore + +# https://spec.commonmark.org/0.29/#line-ending +NEWLINES_RE = re.compile(r"\r\n?|\n") +NULL_RE = re.compile(r"\0") + + +def normalize(state: StateCore) -> None: + # Normalize newlines + string = NEWLINES_RE.sub("\n", state.src) + + # Replace NULL characters + string = NULL_RE.sub("\uFFFD", string) + + state.src = string diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/replacements.py b/.venv/Lib/site-packages/markdown_it/rules_core/replacements.py new file mode 100644 index 0000000..14912e1 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/replacements.py @@ -0,0 +1,126 @@ +"""Simple typographic replacements + +* ``(c)``, ``(C)`` → © +* ``(tm)``, ``(TM)`` → ™ +* ``(r)``, ``(R)`` → ® +* ``+-`` → ± +* ``...`` → … +* ``?....`` → ?.. +* ``!....`` → !.. +* ``????????`` → ??? +* ``!!!!!`` → !!! +* ``,,,`` → , +* ``--`` → &ndash +* ``---`` → &mdash +""" +from __future__ import annotations + +import logging +import re + +from ..token import Token +from .state_core import StateCore + +LOGGER = logging.getLogger(__name__) + +# TODO: +# - fractionals 1/2, 1/4, 3/4 -> ½, ¼, ¾ +# - multiplication 2 x 4 -> 2 × 4 + +RARE_RE = re.compile(r"\+-|\.\.|\?\?\?\?|!!!!|,,|--") + +# Workaround for phantomjs - need regex without /g flag, +# or root check will fail every second time +# SCOPED_ABBR_TEST_RE = r"\((c|tm|r)\)" + +SCOPED_ABBR_RE = re.compile(r"\((c|tm|r)\)", flags=re.IGNORECASE) + +PLUS_MINUS_RE = re.compile(r"\+-") + +ELLIPSIS_RE = re.compile(r"\.{2,}") + +ELLIPSIS_QUESTION_EXCLAMATION_RE = re.compile(r"([?!])…") + +QUESTION_EXCLAMATION_RE = re.compile(r"([?!]){4,}") + +COMMA_RE = re.compile(r",{2,}") + +EM_DASH_RE = re.compile(r"(^|[^-])---(?=[^-]|$)", flags=re.MULTILINE) + +EN_DASH_RE = re.compile(r"(^|\s)--(?=\s|$)", flags=re.MULTILINE) + +EN_DASH_INDENT_RE = re.compile(r"(^|[^-\s])--(?=[^-\s]|$)", flags=re.MULTILINE) + + +SCOPED_ABBR = {"c": "©", "r": "®", "tm": "™"} + + +def replaceFn(match: re.Match[str]) -> str: + return SCOPED_ABBR[match.group(1).lower()] + + +def replace_scoped(inlineTokens: list[Token]) -> None: + inside_autolink = 0 + + for token in inlineTokens: + if token.type == "text" and not inside_autolink: + token.content = SCOPED_ABBR_RE.sub(replaceFn, token.content) + + if token.type == "link_open" and token.info == "auto": + inside_autolink -= 1 + + if token.type == "link_close" and token.info == "auto": + inside_autolink += 1 + + +def replace_rare(inlineTokens: list[Token]) -> None: + inside_autolink = 0 + + for token in inlineTokens: + if ( + token.type == "text" + and (not inside_autolink) + and RARE_RE.search(token.content) + ): + # +- -> ± + token.content = PLUS_MINUS_RE.sub("±", token.content) + + # .., ..., ....... -> … + token.content = ELLIPSIS_RE.sub("…", token.content) + + # but ?..... & !..... -> ?.. & !.. + token.content = ELLIPSIS_QUESTION_EXCLAMATION_RE.sub("\\1..", token.content) + token.content = QUESTION_EXCLAMATION_RE.sub("\\1\\1\\1", token.content) + + # ,, ,,, ,,,, -> , + token.content = COMMA_RE.sub(",", token.content) + + # em-dash + token.content = EM_DASH_RE.sub("\\1\u2014", token.content) + + # en-dash + token.content = EN_DASH_RE.sub("\\1\u2013", token.content) + token.content = EN_DASH_INDENT_RE.sub("\\1\u2013", token.content) + + if token.type == "link_open" and token.info == "auto": + inside_autolink -= 1 + + if token.type == "link_close" and token.info == "auto": + inside_autolink += 1 + + +def replace(state: StateCore) -> None: + if not state.md.options.typographer: + return + + for token in state.tokens: + if token.type != "inline": + continue + if token.children is None: + continue + + if SCOPED_ABBR_RE.search(token.content): + replace_scoped(token.children) + + if RARE_RE.search(token.content): + replace_rare(token.children) diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/smartquotes.py b/.venv/Lib/site-packages/markdown_it/rules_core/smartquotes.py new file mode 100644 index 0000000..c98fbd7 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/smartquotes.py @@ -0,0 +1,202 @@ +"""Convert straight quotation marks to typographic ones +""" +from __future__ import annotations + +import re +from typing import Any + +from ..common.utils import charCodeAt, isMdAsciiPunct, isPunctChar, isWhiteSpace +from ..token import Token +from .state_core import StateCore + +QUOTE_TEST_RE = re.compile(r"['\"]") +QUOTE_RE = re.compile(r"['\"]") +APOSTROPHE = "\u2019" # ’ + + +def replaceAt(string: str, index: int, ch: str) -> str: + # When the index is negative, the behavior is different from the js version. + # But basically, the index will not be negative. + assert index >= 0 + return string[:index] + ch + string[index + 1 :] + + +def process_inlines(tokens: list[Token], state: StateCore) -> None: + stack: list[dict[str, Any]] = [] + + for i, token in enumerate(tokens): + thisLevel = token.level + + j = 0 + for j in range(len(stack))[::-1]: + if stack[j]["level"] <= thisLevel: + break + else: + # When the loop is terminated without a "break". + # Subtract 1 to get the same index as the js version. + j -= 1 + + stack = stack[: j + 1] + + if token.type != "text": + continue + + text = token.content + pos = 0 + maximum = len(text) + + while pos < maximum: + goto_outer = False + lastIndex = pos + t = QUOTE_RE.search(text[lastIndex:]) + if not t: + break + + canOpen = canClose = True + pos = t.start(0) + lastIndex + 1 + isSingle = t.group(0) == "'" + + # Find previous character, + # default to space if it's the beginning of the line + lastChar: None | int = 0x20 + + if t.start(0) + lastIndex - 1 >= 0: + lastChar = charCodeAt(text, t.start(0) + lastIndex - 1) + else: + for j in range(i)[::-1]: + if tokens[j].type == "softbreak" or tokens[j].type == "hardbreak": + break + # should skip all tokens except 'text', 'html_inline' or 'code_inline' + if not tokens[j].content: + continue + + lastChar = charCodeAt(tokens[j].content, len(tokens[j].content) - 1) + break + + # Find next character, + # default to space if it's the end of the line + nextChar: None | int = 0x20 + + if pos < maximum: + nextChar = charCodeAt(text, pos) + else: + for j in range(i + 1, len(tokens)): + # nextChar defaults to 0x20 + if tokens[j].type == "softbreak" or tokens[j].type == "hardbreak": + break + # should skip all tokens except 'text', 'html_inline' or 'code_inline' + if not tokens[j].content: + continue + + nextChar = charCodeAt(tokens[j].content, 0) + break + + isLastPunctChar = lastChar is not None and ( + isMdAsciiPunct(lastChar) or isPunctChar(chr(lastChar)) + ) + isNextPunctChar = nextChar is not None and ( + isMdAsciiPunct(nextChar) or isPunctChar(chr(nextChar)) + ) + + isLastWhiteSpace = lastChar is not None and isWhiteSpace(lastChar) + isNextWhiteSpace = nextChar is not None and isWhiteSpace(nextChar) + + if isNextWhiteSpace: # noqa: SIM114 + canOpen = False + elif isNextPunctChar and not (isLastWhiteSpace or isLastPunctChar): + canOpen = False + + if isLastWhiteSpace: # noqa: SIM114 + canClose = False + elif isLastPunctChar and not (isNextWhiteSpace or isNextPunctChar): + canClose = False + + if nextChar == 0x22 and t.group(0) == '"': # 0x22: " # noqa: SIM102 + if ( + lastChar is not None and lastChar >= 0x30 and lastChar <= 0x39 + ): # 0x30: 0, 0x39: 9 + # special case: 1"" - count first quote as an inch + canClose = canOpen = False + + if canOpen and canClose: + # Replace quotes in the middle of punctuation sequence, but not + # in the middle of the words, i.e.: + # + # 1. foo " bar " baz - not replaced + # 2. foo-"-bar-"-baz - replaced + # 3. foo"bar"baz - not replaced + canOpen = isLastPunctChar + canClose = isNextPunctChar + + if not canOpen and not canClose: + # middle of word + if isSingle: + token.content = replaceAt( + token.content, t.start(0) + lastIndex, APOSTROPHE + ) + continue + + if canClose: + # this could be a closing quote, rewind the stack to get a match + for j in range(len(stack))[::-1]: + item = stack[j] + if stack[j]["level"] < thisLevel: + break + if item["single"] == isSingle and stack[j]["level"] == thisLevel: + item = stack[j] + + if isSingle: + openQuote = state.md.options.quotes[2] + closeQuote = state.md.options.quotes[3] + else: + openQuote = state.md.options.quotes[0] + closeQuote = state.md.options.quotes[1] + + # replace token.content *before* tokens[item.token].content, + # because, if they are pointing at the same token, replaceAt + # could mess up indices when quote length != 1 + token.content = replaceAt( + token.content, t.start(0) + lastIndex, closeQuote + ) + tokens[item["token"]].content = replaceAt( + tokens[item["token"]].content, item["pos"], openQuote + ) + + pos += len(closeQuote) - 1 + if item["token"] == i: + pos += len(openQuote) - 1 + + text = token.content + maximum = len(text) + + stack = stack[:j] + goto_outer = True + break + if goto_outer: + goto_outer = False + continue + + if canOpen: + stack.append( + { + "token": i, + "pos": t.start(0) + lastIndex, + "single": isSingle, + "level": thisLevel, + } + ) + elif canClose and isSingle: + token.content = replaceAt( + token.content, t.start(0) + lastIndex, APOSTROPHE + ) + + +def smartquotes(state: StateCore) -> None: + if not state.md.options.typographer: + return + + for token in state.tokens: + if token.type != "inline" or not QUOTE_RE.search(token.content): + continue + if token.children is not None: + process_inlines(token.children, state) diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/state_core.py b/.venv/Lib/site-packages/markdown_it/rules_core/state_core.py new file mode 100644 index 0000000..a938041 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/state_core.py @@ -0,0 +1,25 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from ..ruler import StateBase +from ..token import Token +from ..utils import EnvType + +if TYPE_CHECKING: + from markdown_it import MarkdownIt + + +class StateCore(StateBase): + def __init__( + self, + src: str, + md: MarkdownIt, + env: EnvType, + tokens: list[Token] | None = None, + ) -> None: + self.src = src + self.md = md # link to parser instance + self.env = env + self.tokens: list[Token] = tokens or [] + self.inlineMode = False diff --git a/.venv/Lib/site-packages/markdown_it/rules_core/text_join.py b/.venv/Lib/site-packages/markdown_it/rules_core/text_join.py new file mode 100644 index 0000000..d54ccbb --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_core/text_join.py @@ -0,0 +1,34 @@ +"""Join raw text tokens with the rest of the text + +This is set as a separate rule to provide an opportunity for plugins +to run text replacements after text join, but before escape join. + +For example, `\\:)` shouldn't be replaced with an emoji. +""" +from __future__ import annotations + +from ..token import Token +from .state_core import StateCore + + +def text_join(state: StateCore) -> None: + """Join raw text for escape sequences (`text_special`) tokens with the rest of the text""" + + for inline_token in state.tokens[:]: + if inline_token.type != "inline": + continue + + # convert text_special to text and join all adjacent text nodes + new_tokens: list[Token] = [] + for child_token in inline_token.children or []: + if child_token.type == "text_special": + child_token.type = "text" + if ( + child_token.type == "text" + and new_tokens + and new_tokens[-1].type == "text" + ): + new_tokens[-1].content += child_token.content + else: + new_tokens.append(child_token) + inline_token.children = new_tokens diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__init__.py b/.venv/Lib/site-packages/markdown_it/rules_inline/__init__.py new file mode 100644 index 0000000..3a8026e --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/__init__.py @@ -0,0 +1,31 @@ +__all__ = ( + "StateInline", + "text", + "fragments_join", + "link_pairs", + "linkify", + "escape", + "newline", + "backtick", + "emphasis", + "image", + "link", + "autolink", + "entity", + "html_inline", + "strikethrough", +) +from . import emphasis, strikethrough +from .autolink import autolink +from .backticks import backtick +from .balance_pairs import link_pairs +from .entity import entity +from .escape import escape +from .fragments_join import fragments_join +from .html_inline import html_inline +from .image import image +from .link import link +from .linkify import linkify +from .newline import newline +from .state_inline import StateInline +from .text import text diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..127f993f02b931bb29d13eb203d15ebb1f9d8618 GIT binary patch literal 833 zcmYL`O=}b}9L6)VFEhKdv%Bp|DMfS2BIhCz)CPNw+R| z@Dq6TGkEvlckmko#)~I!g&qV?=B33D=J|z?JWrnak)~Z_#+%Rk^Y0--zwF{}n6(=> z-;8`gGlbDBn1wtLAr3_YHv+qE@TO?ursF1Wi8gLKZt+OOICk9T9nrxZ#}V&}F77&x zc_I>=IPUPC=;5B@E>A^@Q^yJKi$3lZU{rQ@aLrSB#3()2R$l6dKPX?uyi*uQ7)Y#4brxu>H%C!FWGM*l6H zq3+zhOM-RQ=_%o)oKjy1*cf0#fQ Ao&W#< literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/autolink.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/autolink.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..213eeaf745f5ac2d11574802a474fe720822ee52 GIT binary patch literal 2793 zcmeHJK~Ec35PrM1cWrEAY=asHnn2?eJH!MMHBl%fMT9gElAw^N4OyTY?^0~9z3%Rs z+Qd$bR4I0p)}U4jJ(WWbM7{7odV#tU?o$u0k{-Ar(Niz&Jj2>RLvyQCsZa8IGxKKV zoA+jR{C=?8>ky3LFMDT>n-O|J7=19i#I^>+GbA8^lF&F3Xu%*+QF@%F5RF6>*7bBd zSOw$v)DAmtJXFV2)iDW-NDHjU2xgI)W(3RU#&I@9`Rg``lN+1Fm!HDcF^$*6p_mkk ziF3J0-#tDs*B=<~3S8`LJK;U~HrIZtgFExyrOBy}AEYx60}~zZ*Hk8amwIYkVB$g7 z>GR#0nq(eL1|hr&e;(H1UhYua8*BtqGe2J6CnC_HBEwPhmKKC z+YgD-02lzCrjMcwqg5*@Y&jSa=rDS{%>NADDs{VGD-6*d95t&9dx(|epbcQLI+jZA zj#3|jt@H1C0wb_c>m*AsGG@V?W zTRo5N2ddkdW(b;|tN$}xyBoNje>uY`+V8r7sopEM74kh`st;SBQ%9!cxER9}kBu{m zIE~GGLX(Lc8wrJtnwZouQba{0-O;msM;~l^|w- zy3QxDwg1lTnCM%^I5rulEm)0G!{VkRGj&wxu+Y_(@k+ zKtIYSL(xPO(-4axp-7mWPDs)nAWWJZ5o0Rp53Tz6BR$Z=-BCqF<;M6ZcUe>;njGiG zLW0;js>oq6sHxl)Ue)?XhgxUV)+-XPM!2hdFd{0gm*ud`bhS#BhBpHoAc7>L6b z|B0w_`By`48N<9gmOg8wb&2Z&eRH}0n{CR(Npv>AH zr{+@&?)isH?jPBflB2O~a~6j3L)pPny}KagrR)dgy84pYn)@_w&KXM9`i1roD<|lJ>*=k>KKe-6v(k^9lZZ#pRW9taAHV~|Z!KMDip=HBboi{u1l67sc zo^{r{dg+z1)wha`?+~B+{FvQR z89~03XdIq2iWfNL2oV|Y%d%9dujfcPO~f5UZ0?Q90+eK*au!(f!c%X-v}K?u>IJg= zhEA5PO}Vp$o_x<1jZCBTwt=?MS@RZy9G=|$LO35@^V}@fk7lh~Og}|A7p`p~vaU4l MtgGJND|`j>FKpCgI{*Lx literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/backticks.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/backticks.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92b3cf54dd93f68ebf600dab79716b43c0671e98 GIT binary patch literal 2581 zcmcImO-vhC5Ps|R{`m(7>;ywGHUwzgCQuTkQ3y>#6DXuOO+^z4WQ983E%@JkyZlA# z%Bfn#prklzq?i+Mf+|wQF~>-~AoYUnNNiR)5Jf%YMw?Wsa%pFcZ73m4FCEG6&3o^g z*?IHLj`tU{*?>UKf8RO!2ZPX4ZBY`ss64+2%3Z`Go(Q8M#Oru6Ohj};Is)mCfPy7l z$qr^-e~;K&4(WMH(DAfD@r*!yN%QQt`XPFXaC6Tzz=dZT&P}Ms0m&x`ebI0rDqLf) zxDK_x>vlD%l&Ed1v=|5rQAwq-AdTUuU$^DFFj6p*@OyqouZ1b2;EuzRn$W@iPOIX9 ztg8WyCqgF>!o-wL)+I<8E_lt1P{9U#?v{jJ*2(%1c*AXP@OlU^jvf9=cGmx3N8EJ0 z1_cq;q68%YVOt_orF17~uwhI4+cWNm{Q}k7dzu!6d+rvQ2KtJ*lF3jl+~J5!i2G$U zNdzl)qY;uREn9xw@OC^J@>L*`=_0axHbu$0Ng}}{SPpR-cYAOYtSrOJ3Qx#vDaHgN zGr$;}C0Ln#12b%q?=5E7BGcP;uVZGXoyH6+GuI%W2~Or@I;45K4>|e?Zm_=`WLe>9 zo`IZdRSJ?Y$dqgtHg2sTe|z2q2{ z!IxfR<@{HxjvckP_fs2QwZB)~Dm|Omht5IXYmkLYg*)Br*?n;%6$3&GBv0tS@^Y|uJ68fLI@2bxqk^=saINgu~ll-I5+X2cJ^zJCHn*8CISjJFNEF?rl?R{`<%ge;s4(}yEiQWNU#CuK< zLsBg69SHD(>mrT?1-~SEdwinQb+OMiF1mWcJ~8C&g#-!MbuJc+d0WSY=(x8(aMddY zB;iOLj(j76=+zRy$0nk~0jUj-g$1!lL|ZwRt??<9Ev>K{0^{H(b^v)vq!=u-?rC@O z>;_}HF?D?^ZN2_=#+qa56pL-cWJz`_dM4F=y*GJQsj$w5r^CsQH)&+7NHa4>GMDBD z=LQ$Vxhujj6Au*%Y}+?g7X#ew)$|&v|+5y zbmok2Ke5&*cE`M7&am*oO3VF*yuC9`DbD6Jb;qQ*nwPjmZu#JHaLsjc-PM(Kbvve6} zy0&~>d)|I@<+Ggq{f#E~l4sGg(y;Q;TGNSi_Z^R7ccr>-_9@nC2-JNnMa^2KEg4gm zZT{^Pr035UG}>4DJ0iHMN2bb666Tki9jLxB+5J#o`@~qO<<~r8&K$_H&Rb?h&)w+z zrY~KW)jPiHQ;Zf-Yehdh>v|cq%5c3_a6xKNEhqUQiW82)yU%63L#Je2Wi+zw0ab4ol80|ZDAPZ9SkYTjV0Qo32g iv?1M*XX}&HCjB9?Fa60Tf@#@Sm{yuzXe<04SpE&_<2|+j literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/balance_pairs.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/balance_pairs.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0549f7c1fdd8fda46f9cc90ba7355273f33a4e7 GIT binary patch literal 3269 zcmb_ePi))P87C!*k|;{D6gje-s-a_Bww%a+mS90zdze#4nUgqfkY>Of1p*^7wk(Nq zN!g8Es?&fSAkANaqDIRF+agvZ zp>LP%vNZ$t6pJ`4i@rsSvwe=sV6ziu65!t_L%e_%eQ2@O6D=Gmz{&z?hgops1~9V$U?U4onUG17 zWyFoiP?3_UqD!V^XJ!VnhKqK{1ZCi9neG&6=lBh#X|O|@+F%|0ZUliBYHJ)Ub&CFX z@ZHmz%i)`|pcN$Ua`vJd5S>`3zlVpTdlPqS`>WCF1t9VF{d-K>;JtzTf6LV zof>m$@26HRfk-S{L+en7pe~+|=S7BRQ%g*Kg%{GoBE#oamRKn*#j@!P&*WG!!;8$F zw7@Yej0&kG1WIM|5_;zae)Ot{3f}&|Uc7iAqU{d>uO zUeHN)1>AEwY5LP`M)}oAkS!LLbQ|)=>ja8Xw*oNg)ol_gxjMzQim;@+ksM0;`Fx>} z&*}CYdpDh1&FRi1p5=IPmbyJ^Ot6|Bi*GdS};_)pmq6RNF7lYpHgAXcdRn2 z`XXhr;c(xlH)-YCmbdA_+(BhsrTd=K!zw*oi$9**nXA+1H1Dy>+9P>euCeOzvATDx z(bHF+)q>%N@+WecZqiuj_#^kWyWTTW^Oeahcf;F#U%n@6ba%zKc@>~^06?_={?z7F z)vdZ>`pI|7bCt-W*mevYHG%`xpMG)cvs-HLwC3-5c=Ex?&1=<(+R?}1o$#JdjlQMQ zZ~xtD>7l@x1M7aXYOAJIW?T)7?@p+JGi7I^x4-Odc!HHvPdyQ>`*_u)wX#H8fIV>!GpTAAU9U z+o>lL>gk!^~cMJS?eFJg?6v) zgw_7DdwpvE+uM#t|3Jmj7#iO_rw&c--BpJ!Di|x9ctj z=IdjcHq71IPK*WwWFBNb@m1fi-Fckb$<;@Hy!ZZ-X*G61?TSN2+#c}c^efjkJ!NNe z-io;b%Hp4>@Bu7NEY-d?!JvJ)`XdbBa)m7;$ZM^L7uuJl&WP5v2`**rvMwWQ?E~P@ z+{L4)fIUbM~zG9EyEC_LELAG*MX3K>$tk$xX3TmZM&ZLp@RtO5lrYU7eD3d8{r#oOXy*@_gQuQ>(#5|L-3nj1@jM)Z z<^GHqZMf*tj7E8s;Jr~TaJ)*Wfx)u#8&{z6MlGaQpj$XB8CqWKu-g*J2ZF!Hif;b{vzrJO>5z oN8&h$(2|pS;nB3>IQ|Vb^=ItF->~rmvVh~ke+X6=?l*M*4UyFU-v9sr literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/emphasis.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/emphasis.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57b46bb3fd6fce91d27b39523ad6f4cd21c6f427 GIT binary patch literal 3879 zcmbVPOKcm*8J^)j_@+qPlqK1c)(=^tEz3#cS7n=y6Il%vLvZQ_X;j+mhP#z0kxP1Z zWk)I%2yKE=h!9gP3Q;F3r^;}F`ski|Ezr~2Zb>hEP|yH{Z>sGa8Wd>%89rrid&q#A z{b%N%Z~lMgf9WrNzXw4Z`{L}>8$N{oP6zeos1o@3X&_dSf)t!a89ae8QXC4Gc4W8- zF2hgoFm@^Yr~HJVxD^4uqT*3R_&VpD5${t96Ty~O*0ii48>y_OKgD#;VYx@tbSjfF zRAPCrz?vG<(kV?%){dq-kr)0rgz)o!!=_b~N7HP2d$-_#`PN;v<-DU4s0A*M37*4w zPI26*QfOM(jzCBD*szP689?Z64S#_*ob|nVe%e*1o8P-sJ!m87>M!AR0dT1nFExc% z1Vy|Hy3w{E=DEC>5UV35OQ23Sztf>6U8jtl4Jurx@?2d8dkKx*4Nf%OQKy^V`fkNJ z4+f&R0Hv$BTBl%kZ=G&_fA79q)1r=o(eh_J-0sKN?(OU)ocAM?bR-(EbDoHIJ{Hq- zl^BvLC#R&0OlDLf$+{#3)- zIAP(##0^JSJl$s@LZ6uM&^`SRw1{Yl)l)1nt!k6TlqE21i&Hhl;DXX8URRP9FmQtG3)4i0=Y2TSs#s>kVtDcPG^B4r#SvuRaNq?l75Q!}|KSx@Oh zxjD7SX0JbSt(LTfA8D@3{5h(uc)a)8D-~`jyjPY1_5w^cN>g zXD=lKJIjF{Gtg6-y*;-!w{hs++jovW44hv4!PovB#Z#-%mFVC6`wO@d46k}tJf)NC z-&?=_Fc>Kam5!c*uFOxEdQDgF6JPkr?yl0w-~7C?yJz*2l~10ucb58Y z53UV9Z13OLXSN@y>}s!s_m;zbX1K4?-d%3*H{1JP_?`a1H=Nt;*>a-5fvvqr@cb(F zi&$~@YR^iK$@hL1+w`_Q2i3rsXfX5t7H zG5I!+8v%{83wIExPQhb`^Y*JeTNMEj&qDxMa4a7KPHOHiHASESkF;`*z}dFEEWq+i z$`J%EPJW9)3w8#`Pgm_uu*U+qfS;ZXIM-jnX}!Uk#P*uj5H7!h&215Xc#DGq9Lc^fl)(}{~?vF-Yrsj;d~$9G;W8< z`l?jIca%yXAAp?pH@4k28xqu1hYyvrsp0>@`3@Gb9lPm?+bHJm#8Je{|C&Q{DB>Sy zIf-Sbr!*x#Jq#Uzf(=<--5^wFQO+dZ(;27 zw$eV+wP*1{#p5kp|NKxT+`Eoft`@H2;*48w0=h1>|D~SAoB3`=q42k}CA&YdC zUN2o=J7EU*m4kg|uy3R54?TB!?(Z`rXUyQ4XB_1M@X($Xz5z2hurXF1JZHi$cE{432HJA$RD-E))nAyUL;cW@!II|AB&I6B3_q#aEgrcONz37aS@Gj}Hy4 zT)h{A^yhgj4XnJgp#bTwbac{$_;~-}A}PJ~>znr+F!WVAy69{j=Et|Mtz9#Ng85%Q zemDN*_`UbcgD1_-Q{~QcCj5NSN50XBETZ?!l~ zWK=_rII51woQoQ(1p;ivGYpMh=>ea#1p;gV497%)2q9`TXQP&=5=qtO0> zV0nYZ`1<<~!iS&uI!fVnVLfe1Z~WDF{GS5aae&?Sctot8NpG6$gU;eV%4XA+NK|8% zXe0_#+j!{B%(v0{`zI_g(Et3dlJjimcve#*d3;%BpfsU{Kx-ju~N zD12+BB`cZ&14lQNTUSm6htjW?}2WM!x(=fB7EQ<=(Xo! UHx5336Q96sFLGGKC)ob~0wDW5i~s-t literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/entity.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/entity.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76336eb931b60130976237c70003157a1bf6ac85 GIT binary patch literal 2482 zcmdT`e@qis9DmpA-IZ%Ab}d3>VyA*!P#i4i1b>79x-QC8#LZG|YVXjacfIoNK#J{x z$&$g64NOQZaf$UWAuO@`Yg@Kt?ys5XA3#mkU0g=u_6L6~X(E3uS+@6%9x^9!%l_I+ z?)%>N^S-~{d*Ancci-t`0cvl3eBhEw1MnC#W<$Kuo_vkE>wpJ5A%OtkEj%d^vL#?4 z@YpJmvNd3psQ`s|il-%7W&#WWEIG@wx!dmD4|ev8VcF~j75qYfMW#=`bhLWSw!?YNP<3$ zKGRYbgs;^q&ZkI(Tb~g|Y|`RIlqaJ50Dwfol0-*2jBzp=EF$aZt;iYL)@Ut~{Z%v5 z1N4{a0+>R1aQq*h!K&ViJm8G^KkPWSp;ISnjzE0rbz(cjS6U~A zmT>i4!UbA)Xu^;dQsY8I3`;r?fByr4v{Aj&@`a;@ZO5Ainqz#|QBR&>1;AB+3J_PRU^nxucD)LAORw9n~pKi3%~* zh9rH(_S% z=*g>>Cw49{UV|-4O!QwXpJ%-3t_8;T$W!&br+VH~oe^$}x5O-&wPuu@XYZVS?`RVu zKe)YlZ`IApsmjdB8&wnZVqHV_m6`o_4$mCU)g8D?F4VP6wx#KGe;TIQ%o`6qJ0H03 zotf)?=l<3L30!3b8$jyp6q`AeZOr!PD)vuM%QUFqraceK>z7GTwk@**Y5nZ2$qeSa z^#umFHcdJUEbvv|yfSrVy5Yuq6V#+5zoi;=?4rXp?*GvLi96kWvuCPj+I8c6&bw>g zvFjs$-d$eU3>>cIGO(%Ydgxjx(|!Bwt+UhWw3Z3w%9`dJO`{!%e9`nx%a<*8`@cH$ z;NAI_ZoI&XEzd;w$X7dEcBgWtGJA5iYToxca_!7--SMvjTC{I`f({LE8*~d4^wNkT z%Sx=?I9v3r8|kS#is*nQN~)3EMw;sm)zQ}4)d4He z4BUpNtrrwUGE!v*Kn}y`1q8b7fUNK+w+_KZ#NtOyJ&Q QsJJqk(Pgd6m@{1e35*^XvH$=8 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/escape.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/escape.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e56563936c0acb6256c2d5e23b293c54a48c705f GIT binary patch literal 1939 zcma(SOK%%RcxHFKYp*wU9!(#J6o)pUrmag-q>2&(#c9$;fGUNmC>YFUXH#$eSa)U< znsi+`RV8d%5l0}!y%li@Du;6Gf8f->VHtuj;?$cV;=%=H)^QUat@xy!?=|0Z=9~Sd zqeBG@CO;X;EXn}9L zSs4XyNYio#pwJg^T3Jxz;l)Aq9JURUkeEpfy=bDCk-&H1e(F7o+au-frW}g zs#;{q!Ba)uFdxE}C_Lrpj(N6_vkE2+5YAAUSUI!cP#K%f94;8#x(xwFi0s?E&ZMir z1(({I9k?Vg`A(}XT}fneX~)Jb(iQeG3c>6N05Dt-TmgxT9RM&tf-7cIThb@kmLx}M z`*o$eyf_A>fGZ&>dx+VecOmIv(L*iG&J_iajFh{)Dh3ezBRZ=CC!UmdNp`|5TL4_S z9h-zg%##b!Z53Du{)cCHEAg*gPpVUK11RKoWRy{A_9>R#OTJ$ghxLkQJM_40Sy$OE z-s@6uN56vYoJ%1$gu=e}D5EsryXq=#&_4}jJAVXSh5IV0tgpk5>1zjyZ1=Skb|pt+ zCO*sqEVxPmx~dyaZ=W3Jg6%yh%D6}8^{B?bbu`|&IPiZ)AVFbj9P_J3p-MxKW`hbd z_#qGYwgo%@tUrHX3)tY)Pi(K|m{*)MDVm0*=P00ZYs}&*6^k~ZGF#r%uTYU-gNimr zR4UGq4CYsf2GggflBdp{9;1q37aV_}@;c7W6{%zuX6?9!`BQ*-^|+f`D0%&gm7mK~ z(Z~!jtISZE`xJ}}Rk!AwjW5>@bM3INRcvfsZ zr^ZZ@b?jnl%0gz0b?%aBI3zW$6X(>qv$1&+8_($^n>wQ#Srf;`>`QhkF>e;;Q*T%^ zDPlS1QTBRd^@}D+@nVquVIgff$M9UvBx%ckMvk>|O%xY!7q5*k{7^}rjb#}$)aY`& z8ZRfkNY8Svnk!E<6z!vhrG;A0(zW`ob*0aX?rKO%WoYS4IoXs!FkHEK{TdgxENjVX zqMY1_bkz>r%#1}kEN?Vb2I?{)27 z-M6x@etczr<@Jr8zWU5(qh4n(3(>o`61WxeqCHIobad8+s%I+6W(Y*PYZEu~O>JA> z*mhB#Y$%c1;JUK6eql{s?@Qb}e!uJM6ZbEyA0OkTSyihp*7e)UgGj6*Zglt7j86|$ z6ffLen_Uk-eP_?w_>&+Xgl{Sz$d4sXwXhBU9Yk0G_u*;CV3l=A5tXT5NAlXV@8#@Iq( zKZVayc!0u#6b?{0Na1r79-=T#;qw$8rtk=bM=4~3a*V>06uwO12!*duI7;EG6uw5` zyO{sfD148?_bE(M_yL7iDRe0;QF!gGc#taTG_s9!nreof&)bE>oMYukYaBHH-?DW@ zF#nBEX~wp5tvj-Z@m~Twzz{yjb-|Imjo76c#gmNX?>TvqElm+Z_^Tj5>312x!5_gu eQ+@$<)($rTLw6h>-IF#s_uDM&*My~@@AWS~)#~g3 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/fragments_join.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/fragments_join.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e581c8490d3963d92a76678258bef55d4f1baae GIT binary patch literal 1964 zcmaJ?O>7%Q6yCMhj)^y6lct3Kj*_^9H=J6PLTvwzVgm!^PRkXKfg0h zBjB@6_D`{$;pNBMLGP(&2Kp};_GPH5RGb36uXbYO5q4OUrumu#$UM`~AxE?Daj%e2 zQ+zOZ!l87+(WNg!?+8^1x;vu%46WCVV9c6Wvr)N(m{Y_yMcOjM1YxU`*Qf!nwvH$x zMiH|-amu+oDmj#uh?B*X8g}lA4`N}G!${K$S{B<3F}%uT+| z%$7~~6Cuqs15RY(3N~rCkF=NvQn+l)2{ckg_i$D#Qw&H3Gr*~O8k~+z!!mfhmPU%0 zP&B%(0rKAt25sVnYz^EgQB9_MnLC%VeC@yJ)2jWK?s86HCJho2>NZG^) z8{kBIFvwK}M8Uh|gK?dsHpV)DgU%ogD`5X@E|SP0i0>GIs}B_w za-d-)Z)EcTMk#PXWrF-b0;r+mWZHLs!h4JGJ;jr_fLqC^7dEl&MFS;XmyIa{OfTZQ zgH^SJy{@cdGbm9qLii3sWDd|}X{&}+wmd0YCd89WjWWvHm-h$y_x|h^^$vyXstcN> z&S6?)PDx#WSkP_a6mXVN^%}U$+`f(~6kP-NqWZp;g@T|tr{JjR3brfiym3#ZP^?r5 zmb4tEDleK2rN|g;l4qJ`41b%QTqau1f+%UG;23tgRP}nF{X{N6bX)-a2>N(kXb%WI zz3W&1=h5h0ewA)V1-Wlyx-q>ix$)Ny;t4mN z*c12T$(G#L{IGGOezi3`T90hV4Y|4K#$NtChFWpuTnB*c>ED=d%x@34^6LlkuqzMm zR`%soOBrZ>vKiZ++E<2J%Ec{tQ{GNYggQP(UpfD%VPilOzg{AD>3#^{Z{>9 z#7#^!BPWn8S!vERuGi;UF}W!=o~ujkln{TuIrt#mep86ab#}i7@&gGw7hU-h(8LA~ zA+?8*LlcT^U_&kH~Ej|4Kn=lyW=V$+tRL-pPzaOMd7M5C|3tsNFc@lPSqj=mwH Q?eVq%kG+w9_``Sp4<{Gg@&Et; literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/html_inline.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/html_inline.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6aa5586aa688262d4a153bbbf4b3023d9ca2959a GIT binary patch literal 2005 zcmbtU-ES0C6uVq&OP_s-`w;0 zV@pd60iF8%@Ki=b=nu9DNp1>jXF*s%1~NDc+1v!jF`2h`TbK}RaYBT>V2GAv%M&ul z5>^ZuN8S+)WypWm6~hbQY83F*oC;2Bxty zof)=AcI-*YBSe~{!Y>`j`1hl5kTZ8hbAT!BU)AlUaYAqjX9 zxP-i3SY}W?s@^bWyJn6&if<|R&7OLo_E*j=zIt=wzSzG87Kln73mla_)54CQW*&va z+zi6?J7`(BGU3SvUgAN&@mBMU)y-zgu$OHjgEP?W=6#PVFf{hxO;i#l#1f*W&wqqz0qe; z4k+_nD6R8nz0^S6C`2hqMJe!>^S%Q6&h^`&WGF_&h~8%L2P(C|Y5c$F&3% za;`^t+n|b@^G(aWTfc1DdAl)`BwP0ZRr1{|c0AT@ z$p(=&cB3a;SmM2xpe$fS#9HUHS#9R%BeiYr;OxPNYEMn=d8qEFsXG?ss<^D~t+#fp z%BZzt&YHDmPSln7^}@A6x&7J)mG%e93yZ>{{Roo(Okx_j~7%gfp!uzVcf`Y_&Gi}zOYw+c54)%I#fIu~N|vC8Y!7pwYG+bcJu`nK)2qBo<9yQ;#S^xfUx@A-Dm5Bj}vc;zifBf`VuyWDCm*`$Lc<8aZsc1`PW*$bQhV*7aV4WmVuf?oZVJ qE86!9+Px|ZoK|jMMZhW@YmBYNd%3pq`>P08^;p2}j{n7W0r)>JLatK) literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/image.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/image.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e97b1f979d46674eded69a0efceb3c1059abc69 GIT binary patch literal 4208 zcmcInTWk~A8J_X@GQN!+Uy_(M7s6(fVM%rag}szr(Iy50VG9jNOX}7#nIRc_JkFk( zu*r5@W!sh3rl_$iB%4(w+`iN-4B+rg^rBrQI@fJj%`qcl7FA2e+ z%St_x=lpZ#{I~DFoa4W`-3|iAsb3wP9qo%uGyS6ab%iOiMa9k=||cO>)W~OpVJmtH$S}>zqOVUf-jsY@j5{u za&Z?;ocY5Ve+z91SVO%pqOm5;&};c0daYP*+6vM!GCM{bFxold&YdgR@7A8z?BJ-| zfH)p$n`+~1hCdhyTkU(AR%z9OS92u#Vi!MY!y7s=XzconN&~MOBsO``E6?Lh+ZEVd z8>;;_&Jq~1Rkd^W8bXq@g-r6=D~4^6dhF=5;{}lN)U<4W?q(ybw}^ZbH>c{1L-p+( z=m)!4k;K7N4)5xj2P( zjBgx|hF4Q6cxYtMgaOkQZ~VDfq>O!7XwSY(O^T4 z>Owx%8y{-CZ_S)rbv3XAD@^EcYY*bXTRaV_RcyF6IMM34g*+-)8h@>^e{1G^N8tsk zY+K!^aBqm#&mMwU^s|9?bwVfi9!L0~)yW?r3>Lz&b#hQA9XiSC4%E2i$hvtJUUZ8h zC?c<0gk)@n*C`=612-f}M$fYly!?SpJzilHJ6fgD?HA`7En9Z zVM=nkZI&13cqHr0Tnx$lgdim*FekF$9f9WJ7%wY=WZcShQ!1gmo3}8`0_qi{yRN{s zjDw4pv9u-dykRfJOIHxiJe`{172PTrw=>;hsL;)G^YW~2i75)$LQl^MA_rGH-8P+) z6kbwv8~!p0e74k_aW&Md+y-mCJI8+(N8gHEkO9ZY zWGop0uo6mYE;1=_eD7J5iu2Qo96277mG7M$@4X`T9v5SBB62b|o#0XLSSp^13||3w zA``-;h%6}l5ZrVV5M4QvjG+XV`ap^b%ByHz+kToA^?4uniW3M~SI{dd__b}hC#R2e*WZ}h?73B0|n9SbO)%XclEg7@Wx>_XMk zQ}OgvJ;N2xaCv@(zbmW?_x7$P?_F5;oL)M)X(ecHZtu@k%$*^FJxc>%sk-3}JU=-p|q*N@Ln`qgMs3uJ2I3JM;Z7{awXN*WW2!Dv$jxu6cu+ z%aa?)p3IDH+6j*@H~LFq(?!7AzN>F({?1LBXbWU48slG{&CXVt?h4agWe!!CLo4CC z5-C$oIy>JeZoypeyS>Srr{w!H7oz^#FG|G~^y)6iQXHFY7=KNRR zECx&aKK(Wr_wr{iYk`i!iTsI7Sn~x71Ni}ff+qa!Me5hA7TnXoHfQ>>V{fVN`p?RJ zE9TGkYk`pF_2=Ht(>V%|!`rX3fLyR66W(w#7`|fgX6Qz!bm&HR`Ot&Vu-4g~311rr zbT()wj!%}tNOuFEp_kFKrY#ZIZ8LLLSm+36M?8$nnbXSG$D$bPV zf4}hCg_Ypl&}wMy_(OVh!y7C(@{Z!`rEqy<-8%&N*WFh>SZN>5Sgtv>P|v5`rSAaA zXq`PUx&P+$YOc2BGubo6fzsiJF7`3N*al_sUjDsmu)h-QuLjvlkS!0d^*;&uD3|H5mU33NU@{ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/link.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/link.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0293cc985f221816fc8019a13568b78cf568fece GIT binary patch literal 4080 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 W#a5=i(7B6%6?vDf2mf?VF48{&t(jQ> literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/state_inline.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/state_inline.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60f2f0157917b6f739d5f4316bb4d1cf9b41d8ae GIT binary patch literal 5990 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/strikethrough.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/strikethrough.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2439e13b28f7566d7f2996e76956d95de470a685 GIT binary patch literal 4229 zcmcInU2Gf25#Hq;k4N%IQL=t0+mbG|9E+AL$9C;Fj$+ldESIfnr*@OZu401Woh3@t zk=;AlqHq#aBSA@9jVQE$s3+-Bh6*%~d8}WXr;}2UJ?KG2Q51eDl-dP~ytK2+AN@p1 zn*v>syR)-9Gk0?{^X-1-^LY@o?|F9!&)M)sj;$YDv9U=atPrU{lHy7CK_Sv-QAP}_&cS_%ci3ls433G z1gEjdDUQ+C5n?nNaqiYZXZvecxYe@mDccMcP20`>VSZ zry?k>Rd_4frUa8Sg-G>jK$AGx1bnCBnsS*g)5-LH^k3`ZCPC{ijc5cu?%p<1vzLRA zQCr~|hbolGtr3wC5m~fu|jW;)t%xbd^g1n-U@E7Rw&>euF%`#Z#=7I&sMZx zWV*nUKJdl1AMh-AVgm0M1^a&+Dj#!1s)o{B$U7MhYr0AdS&hbq<*_IkRf!zc<*2Ny zsVIR+lnr&lkd5T1s&&axO_8IDBF8C5Rw_X&C*r!%Z{z77Kd13w^Hj!0giZ(#-SdAz z3kkMRvS14dRU0yfZ70)fbE>A;d@`kKwlkJU>T1YubE%|mb2^FH9z7P-Sc2%p&(x>J z^B|2Nfes{Q?|hD=(Y%&BFv7PQYBlW?bK<`*@7O2 z%?6ti!*;~L2(_)L3NuV-px8LBi!jRN_T|s7UK)G{e5eoJj*boXsrsmqObyc*9~!}0@N?oUMZ(ZTOUW7N}q$&ut>_XAaXFgOtZU{Hq&a4H2$(IHhI zq`p#;54A|#I8DYAsve26s&HC2NPJW^hDmaKXt+C-wng@O@ky1u3Qy*OzkUQlbp~xp zwR7QYc;;Hs?VoGTHs{V;?&g{A{>kMl*3@sh+?m^t(vjI$U#oN>R+x&QcNalhU9TZ^uegs&h5EiqUS+bpqdLu%M)I-EcItB1v=;6`I}{`gYY zV%K`(iIrEZ#?E4WW3l0Aq2ajIaJ<;qQfNG3HJ*6sbNT!)Ik(%h)rj1l%#X4{25+?> zuavp}Ko|Vam#D7f=gm2u(SRa=Js3 z<4P({aSEoz&*W$^%3*TW#3s**E0n(dN^iN;3MQ{`EQR@58Fo^8dm0qZ4oH}tJI{mm zefKhp0+hmiiZDpf2;I||giCRnuI&=52r#Q^P&k;;=wVHPQWL4_QAC(kOZWkHg|D&e z2Kj1f-(#2mf7k_YL+Pb&Jp$w2rg)gIuYZ#_*`cv+uRbX9UZ%0tbc|HNVSAUkuWw2k zE3pM-z8WKy2qTUho;_6=^~ghnKx$rX~w5lVv_5ed-l zDD4>1@J2eN+ME#`vR#_08*y!@grMUoLPLSj4@7}76>^g{%AjWq+nY#g>JJ%|>$Ynw zIuRcmA0zE_$pb(~42Gq)2sp{8GOUg0G`%aZCX?e-K#Bki8-QamRoBVuz&Zzi{T~cn zigoofKiKfs=1x9I&RnmS{GlhE#fG+JJpX>iv*~Rpc#m4%qs#o7x4kI&a<$q1%$1^4 z4=Zz*vzPO?*1T=I_=j5ZBTL$%W*s_}5jO!lqQ+(0q}PxtI&Dj=mT?>ITNti1oatb7tiugBZE_6fpc;~T#bNRf zAggw1I>%y}q(tMgfhKwo#wj;t}bO+4_AEF8F4tj_~&dJL^i6%zn z@=?gLy8JM149k$!dUxrBOtY31jvFDT?JXTuBV#J0Dk}{%>q?pJ z32TZvagC592{}s{{{~&8Icf8;aYAf2?U}Gn{m9a}l*-8FF6fK+ihdSH8_XJBOja5fVx-OJjk^(AoS4$z;M7h-!=zja&xS zu07PFlQr~K@>5pg=*{|l(#s@oKy?i9I}}nj`3`g;(e^|l_s2n}8i^1Zv9`pn2IZ4C zyH*hP6t7Yt_GPFmpCXnRB}a=rV@Uz7F%EYV!iX-$V$#P~1hTYp8by%0h;@Zvpu O3AewT#5K5%N&g!~f_`iO literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/text.cpython-312.pyc b/.venv/Lib/site-packages/markdown_it/rules_inline/__pycache__/text.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15c07f7cb45af260e7cdefa369a628597ab34980 GIT binary patch literal 1031 zcma)5&rcIU6rQ(RN<%3iB8W3^y0~x28h8Pe93%o-kbT}d~Y)I+2^Yu!tTEd&c0R& z`6h!Sb01C)+Qnpz7{q`$Nx&oknI(qu0VWkgrC_+IYLrp+soQWbx+Y!e@_^?%2uc9Z zJL>2T9kSx4Mf)2>4xs|!62cXPW`q`mR)jW$>j)hPeF#B>TL}FKw-Fv8Xb6uHrVzpi zPY_-rEFiqXGA_%ao11ZJIp}88nPXN&ITS2inHZuWa&SXPStA(|mDv-vposk6ti$yM zHKSzIm{?&wVu$MlO@tYxQJ`~lMI;5xpHU2W;Uh#;J!04YHyhpverc7lYeEO4l??Fq z44H?hr-Yu;Dob{qQO*&mGopl#JCkRJkISajfNPk^iy0gXl%blmIl2Wr)aOy$JDtfiy5xkl2q9Ocq9p-YlCP*<3FHFVP~KO& zqUE&gVBTA`TE84zAK#qVnAqYQQ(wA6yG^0I$Gh|_=UGw' +import re + +from .state_inline import StateInline + +EMAIL_RE = re.compile( + r"^([a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$" # noqa: E501 +) +AUTOLINK_RE = re.compile(r"^([a-zA-Z][a-zA-Z0-9+.\-]{1,31}):([^<>\x00-\x20]*)$") + + +def autolink(state: StateInline, silent: bool) -> bool: + pos = state.pos + + if state.src[pos] != "<": + return False + + start = state.pos + maximum = state.posMax + + while True: + pos += 1 + if pos >= maximum: + return False + + ch = state.src[pos] + + if ch == "<": + return False + if ch == ">": + break + + url = state.src[start + 1 : pos] + + if AUTOLINK_RE.search(url) is not None: + fullUrl = state.md.normalizeLink(url) + if not state.md.validateLink(fullUrl): + return False + + if not silent: + token = state.push("link_open", "a", 1) + token.attrs = {"href": fullUrl} + token.markup = "autolink" + token.info = "auto" + + token = state.push("text", "", 0) + token.content = state.md.normalizeLinkText(url) + + token = state.push("link_close", "a", -1) + token.markup = "autolink" + token.info = "auto" + + state.pos += len(url) + 2 + return True + + if EMAIL_RE.search(url) is not None: + fullUrl = state.md.normalizeLink("mailto:" + url) + if not state.md.validateLink(fullUrl): + return False + + if not silent: + token = state.push("link_open", "a", 1) + token.attrs = {"href": fullUrl} + token.markup = "autolink" + token.info = "auto" + + token = state.push("text", "", 0) + token.content = state.md.normalizeLinkText(url) + + token = state.push("link_close", "a", -1) + token.markup = "autolink" + token.info = "auto" + + state.pos += len(url) + 2 + return True + + return False diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/backticks.py b/.venv/Lib/site-packages/markdown_it/rules_inline/backticks.py new file mode 100644 index 0000000..fc60d6b --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/backticks.py @@ -0,0 +1,72 @@ +# Parse backticks +import re + +from .state_inline import StateInline + +regex = re.compile("^ (.+) $") + + +def backtick(state: StateInline, silent: bool) -> bool: + pos = state.pos + + if state.src[pos] != "`": + return False + + start = pos + pos += 1 + maximum = state.posMax + + # scan marker length + while pos < maximum and (state.src[pos] == "`"): + pos += 1 + + marker = state.src[start:pos] + openerLength = len(marker) + + if state.backticksScanned and state.backticks.get(openerLength, 0) <= start: + if not silent: + state.pending += marker + state.pos += openerLength + return True + + matchStart = matchEnd = pos + + # Nothing found in the cache, scan until the end of the line (or until marker is found) + while True: + try: + matchStart = state.src.index("`", matchEnd) + except ValueError: + break + matchEnd = matchStart + 1 + + # scan marker length + while matchEnd < maximum and (state.src[matchEnd] == "`"): + matchEnd += 1 + + closerLength = matchEnd - matchStart + + if closerLength == openerLength: + # Found matching closer length. + if not silent: + token = state.push("code_inline", "code", 0) + token.markup = marker + token.content = state.src[pos:matchStart].replace("\n", " ") + if ( + token.content.startswith(" ") + and token.content.endswith(" ") + and len(token.content.strip()) > 0 + ): + token.content = token.content[1:-1] + state.pos = matchEnd + return True + + # Some different length found, put it in cache as upper limit of where closer can be found + state.backticks[closerLength] = matchStart + + # Scanned through the end, didn't find anything + state.backticksScanned = True + + if not silent: + state.pending += marker + state.pos += openerLength + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/balance_pairs.py b/.venv/Lib/site-packages/markdown_it/rules_inline/balance_pairs.py new file mode 100644 index 0000000..bbb2101 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/balance_pairs.py @@ -0,0 +1,137 @@ +"""Balance paired characters (*, _, etc) in inline tokens.""" +from __future__ import annotations + +from .state_inline import Delimiter, StateInline + + +def processDelimiters(state: StateInline, delimiters: list[Delimiter]) -> None: + """For each opening emphasis-like marker find a matching closing one.""" + if not delimiters: + return + + openersBottom = {} + maximum = len(delimiters) + + # headerIdx is the first delimiter of the current (where closer is) delimiter run + headerIdx = 0 + lastTokenIdx = -2 # needs any value lower than -1 + jumps: list[int] = [] + closerIdx = 0 + while closerIdx < maximum: + closer = delimiters[closerIdx] + + jumps.append(0) + + # markers belong to same delimiter run if: + # - they have adjacent tokens + # - AND markers are the same + # + if ( + delimiters[headerIdx].marker != closer.marker + or lastTokenIdx != closer.token - 1 + ): + headerIdx = closerIdx + lastTokenIdx = closer.token + + # Length is only used for emphasis-specific "rule of 3", + # if it's not defined (in strikethrough or 3rd party plugins), + # we can default it to 0 to disable those checks. + # + closer.length = closer.length or 0 + + if not closer.close: + closerIdx += 1 + continue + + # Previously calculated lower bounds (previous fails) + # for each marker, each delimiter length modulo 3, + # and for whether this closer can be an opener; + # https://github.com/commonmark/cmark/commit/34250e12ccebdc6372b8b49c44fab57c72443460 + if closer.marker not in openersBottom: + openersBottom[closer.marker] = [-1, -1, -1, -1, -1, -1] + + minOpenerIdx = openersBottom[closer.marker][ + (3 if closer.open else 0) + (closer.length % 3) + ] + + openerIdx = headerIdx - jumps[headerIdx] - 1 + + newMinOpenerIdx = openerIdx + + while openerIdx > minOpenerIdx: + opener = delimiters[openerIdx] + + if opener.marker != closer.marker: + openerIdx -= jumps[openerIdx] + 1 + continue + + if opener.open and opener.end < 0: + isOddMatch = False + + # from spec: + # + # If one of the delimiters can both open and close emphasis, then the + # sum of the lengths of the delimiter runs containing the opening and + # closing delimiters must not be a multiple of 3 unless both lengths + # are multiples of 3. + # + if ( + (opener.close or closer.open) + and ((opener.length + closer.length) % 3 == 0) + and (opener.length % 3 != 0 or closer.length % 3 != 0) + ): + isOddMatch = True + + if not isOddMatch: + # If previous delimiter cannot be an opener, we can safely skip + # the entire sequence in future checks. This is required to make + # sure algorithm has linear complexity (see *_*_*_*_*_... case). + # + if openerIdx > 0 and not delimiters[openerIdx - 1].open: + lastJump = jumps[openerIdx - 1] + 1 + else: + lastJump = 0 + + jumps[closerIdx] = closerIdx - openerIdx + lastJump + jumps[openerIdx] = lastJump + + closer.open = False + opener.end = closerIdx + opener.close = False + newMinOpenerIdx = -1 + + # treat next token as start of run, + # it optimizes skips in **<...>**a**<...>** pathological case + lastTokenIdx = -2 + + break + + openerIdx -= jumps[openerIdx] + 1 + + if newMinOpenerIdx != -1: + # If match for this delimiter run failed, we want to set lower bound for + # future lookups. This is required to make sure algorithm has linear + # complexity. + # + # See details here: + # https:#github.com/commonmark/cmark/issues/178#issuecomment-270417442 + # + openersBottom[closer.marker][ + (3 if closer.open else 0) + ((closer.length or 0) % 3) + ] = newMinOpenerIdx + + closerIdx += 1 + + +def link_pairs(state: StateInline) -> None: + tokens_meta = state.tokens_meta + maximum = len(state.tokens_meta) + + processDelimiters(state, state.delimiters) + + curr = 0 + while curr < maximum: + curr_meta = tokens_meta[curr] + if curr_meta and "delimiters" in curr_meta: + processDelimiters(state, curr_meta["delimiters"]) + curr += 1 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/emphasis.py b/.venv/Lib/site-packages/markdown_it/rules_inline/emphasis.py new file mode 100644 index 0000000..9a98f9e --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/emphasis.py @@ -0,0 +1,102 @@ +# Process *this* and _that_ +# +from __future__ import annotations + +from .state_inline import Delimiter, StateInline + + +def tokenize(state: StateInline, silent: bool) -> bool: + """Insert each marker as a separate text token, and add it to delimiter list""" + start = state.pos + marker = state.src[start] + + if silent: + return False + + if marker not in ("_", "*"): + return False + + scanned = state.scanDelims(state.pos, marker == "*") + + for _ in range(scanned.length): + token = state.push("text", "", 0) + token.content = marker + state.delimiters.append( + Delimiter( + marker=ord(marker), + length=scanned.length, + token=len(state.tokens) - 1, + end=-1, + open=scanned.can_open, + close=scanned.can_close, + ) + ) + + state.pos += scanned.length + + return True + + +def _postProcess(state: StateInline, delimiters: list[Delimiter]) -> None: + i = len(delimiters) - 1 + while i >= 0: + startDelim = delimiters[i] + + # /* _ */ /* * */ + if startDelim.marker != 0x5F and startDelim.marker != 0x2A: + i -= 1 + continue + + # Process only opening markers + if startDelim.end == -1: + i -= 1 + continue + + endDelim = delimiters[startDelim.end] + + # If the previous delimiter has the same marker and is adjacent to this one, + # merge those into one strong delimiter. + # + # `whatever` -> `whatever` + # + isStrong = ( + i > 0 + and delimiters[i - 1].end == startDelim.end + 1 + # check that first two markers match and adjacent + and delimiters[i - 1].marker == startDelim.marker + and delimiters[i - 1].token == startDelim.token - 1 + # check that last two markers are adjacent (we can safely assume they match) + and delimiters[startDelim.end + 1].token == endDelim.token + 1 + ) + + ch = chr(startDelim.marker) + + token = state.tokens[startDelim.token] + token.type = "strong_open" if isStrong else "em_open" + token.tag = "strong" if isStrong else "em" + token.nesting = 1 + token.markup = ch + ch if isStrong else ch + token.content = "" + + token = state.tokens[endDelim.token] + token.type = "strong_close" if isStrong else "em_close" + token.tag = "strong" if isStrong else "em" + token.nesting = -1 + token.markup = ch + ch if isStrong else ch + token.content = "" + + if isStrong: + state.tokens[delimiters[i - 1].token].content = "" + state.tokens[delimiters[startDelim.end + 1].token].content = "" + i -= 1 + + i -= 1 + + +def postProcess(state: StateInline) -> None: + """Walk through delimiter list and replace text tokens with tags.""" + _postProcess(state, state.delimiters) + + for token in state.tokens_meta: + if token and "delimiters" in token: + _postProcess(state, token["delimiters"]) diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/entity.py b/.venv/Lib/site-packages/markdown_it/rules_inline/entity.py new file mode 100644 index 0000000..ec9d396 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/entity.py @@ -0,0 +1,53 @@ +# Process html entity - {, ¯, ", ... +import re + +from ..common.entities import entities +from ..common.utils import fromCodePoint, isValidEntityCode +from .state_inline import StateInline + +DIGITAL_RE = re.compile(r"^&#((?:x[a-f0-9]{1,6}|[0-9]{1,7}));", re.IGNORECASE) +NAMED_RE = re.compile(r"^&([a-z][a-z0-9]{1,31});", re.IGNORECASE) + + +def entity(state: StateInline, silent: bool) -> bool: + pos = state.pos + maximum = state.posMax + + if state.src[pos] != "&": + return False + + if pos + 1 >= maximum: + return False + + if state.src[pos + 1] == "#": + if match := DIGITAL_RE.search(state.src[pos:]): + if not silent: + match1 = match.group(1) + code = ( + int(match1[1:], 16) if match1[0].lower() == "x" else int(match1, 10) + ) + + token = state.push("text_special", "", 0) + token.content = ( + fromCodePoint(code) + if isValidEntityCode(code) + else fromCodePoint(0xFFFD) + ) + token.markup = match.group(0) + token.info = "entity" + + state.pos += len(match.group(0)) + return True + + else: + if (match := NAMED_RE.search(state.src[pos:])) and match.group(1) in entities: + if not silent: + token = state.push("text_special", "", 0) + token.content = entities[match.group(1)] + token.markup = match.group(0) + token.info = "entity" + + state.pos += len(match.group(0)) + return True + + return False diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/escape.py b/.venv/Lib/site-packages/markdown_it/rules_inline/escape.py new file mode 100644 index 0000000..9f68b5d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/escape.py @@ -0,0 +1,92 @@ +""" +Process escaped chars and hardbreaks +""" +from ..common.utils import isStrSpace +from .state_inline import StateInline + + +def escape(state: StateInline, silent: bool) -> bool: + """Process escaped chars and hardbreaks.""" + pos = state.pos + maximum = state.posMax + + if state.src[pos] != "\\": + return False + + pos += 1 + + # '\' at the end of the inline block + if pos >= maximum: + return False + + ch1 = state.src[pos] + ch1_ord = ord(ch1) + if ch1 == "\n": + if not silent: + state.push("hardbreak", "br", 0) + pos += 1 + # skip leading whitespaces from next line + while pos < maximum: + ch = state.src[pos] + if not isStrSpace(ch): + break + pos += 1 + + state.pos = pos + return True + + escapedStr = state.src[pos] + + if ch1_ord >= 0xD800 and ch1_ord <= 0xDBFF and pos + 1 < maximum: + ch2 = state.src[pos + 1] + ch2_ord = ord(ch2) + if ch2_ord >= 0xDC00 and ch2_ord <= 0xDFFF: + escapedStr += ch2 + pos += 1 + + origStr = "\\" + escapedStr + + if not silent: + token = state.push("text_special", "", 0) + token.content = escapedStr if ch1 in _ESCAPED else origStr + token.markup = origStr + token.info = "escape" + + state.pos = pos + 1 + return True + + +_ESCAPED = { + "!", + '"', + "#", + "$", + "%", + "&", + "'", + "(", + ")", + "*", + "+", + ",", + "-", + ".", + "/", + ":", + ";", + "<", + "=", + ">", + "?", + "@", + "[", + "\\", + "]", + "^", + "_", + "`", + "{", + "|", + "}", + "~", +} diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/fragments_join.py b/.venv/Lib/site-packages/markdown_it/rules_inline/fragments_join.py new file mode 100644 index 0000000..f795c13 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/fragments_join.py @@ -0,0 +1,43 @@ +from .state_inline import StateInline + + +def fragments_join(state: StateInline) -> None: + """ + Clean up tokens after emphasis and strikethrough postprocessing: + merge adjacent text nodes into one and re-calculate all token levels + + This is necessary because initially emphasis delimiter markers (``*, _, ~``) + are treated as their own separate text tokens. Then emphasis rule either + leaves them as text (needed to merge with adjacent text) or turns them + into opening/closing tags (which messes up levels inside). + """ + level = 0 + maximum = len(state.tokens) + + curr = last = 0 + while curr < maximum: + # re-calculate levels after emphasis/strikethrough turns some text nodes + # into opening/closing tags + if state.tokens[curr].nesting < 0: + level -= 1 # closing tag + state.tokens[curr].level = level + if state.tokens[curr].nesting > 0: + level += 1 # opening tag + + if ( + state.tokens[curr].type == "text" + and curr + 1 < maximum + and state.tokens[curr + 1].type == "text" + ): + # collapse two adjacent text nodes + state.tokens[curr + 1].content = ( + state.tokens[curr].content + state.tokens[curr + 1].content + ) + else: + if curr != last: + state.tokens[last] = state.tokens[curr] + last += 1 + curr += 1 + + if curr != last: + del state.tokens[last:] diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/html_inline.py b/.venv/Lib/site-packages/markdown_it/rules_inline/html_inline.py new file mode 100644 index 0000000..9065e1d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/html_inline.py @@ -0,0 +1,43 @@ +# Process html tags +from ..common.html_re import HTML_TAG_RE +from ..common.utils import isLinkClose, isLinkOpen +from .state_inline import StateInline + + +def isLetter(ch: int) -> bool: + lc = ch | 0x20 # to lower case + # /* a */ and /* z */ + return (lc >= 0x61) and (lc <= 0x7A) + + +def html_inline(state: StateInline, silent: bool) -> bool: + pos = state.pos + + if not state.md.options.get("html", None): + return False + + # Check start + maximum = state.posMax + if state.src[pos] != "<" or pos + 2 >= maximum: + return False + + # Quick fail on second char + ch = state.src[pos + 1] + if ch not in ("!", "?", "/") and not isLetter(ord(ch)): # /* / */ + return False + + match = HTML_TAG_RE.search(state.src[pos:]) + if not match: + return False + + if not silent: + token = state.push("html_inline", "", 0) + token.content = state.src[pos : pos + len(match.group(0))] + + if isLinkOpen(token.content): + state.linkLevel += 1 + if isLinkClose(token.content): + state.linkLevel -= 1 + + state.pos += len(match.group(0)) + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/image.py b/.venv/Lib/site-packages/markdown_it/rules_inline/image.py new file mode 100644 index 0000000..b4a32a9 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/image.py @@ -0,0 +1,148 @@ +# Process ![image]( "title") +from __future__ import annotations + +from ..common.utils import isStrSpace, normalizeReference +from ..token import Token +from .state_inline import StateInline + + +def image(state: StateInline, silent: bool) -> bool: + label = None + href = "" + oldPos = state.pos + max = state.posMax + + if state.src[state.pos] != "!": + return False + + if state.pos + 1 < state.posMax and state.src[state.pos + 1] != "[": + return False + + labelStart = state.pos + 2 + labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, False) + + # parser failed to find ']', so it's not a valid link + if labelEnd < 0: + return False + + pos = labelEnd + 1 + + if pos < max and state.src[pos] == "(": + # + # Inline link + # + + # [link]( "title" ) + # ^^ skipping these spaces + pos += 1 + while pos < max: + ch = state.src[pos] + if not isStrSpace(ch) and ch != "\n": + break + pos += 1 + + if pos >= max: + return False + + # [link]( "title" ) + # ^^^^^^ parsing link destination + start = pos + res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax) + if res.ok: + href = state.md.normalizeLink(res.str) + if state.md.validateLink(href): + pos = res.pos + else: + href = "" + + # [link]( "title" ) + # ^^ skipping these spaces + start = pos + while pos < max: + ch = state.src[pos] + if not isStrSpace(ch) and ch != "\n": + break + pos += 1 + + # [link]( "title" ) + # ^^^^^^^ parsing link title + res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax) + if pos < max and start != pos and res.ok: + title = res.str + pos = res.pos + + # [link]( "title" ) + # ^^ skipping these spaces + while pos < max: + ch = state.src[pos] + if not isStrSpace(ch) and ch != "\n": + break + pos += 1 + else: + title = "" + + if pos >= max or state.src[pos] != ")": + state.pos = oldPos + return False + + pos += 1 + + else: + # + # Link reference + # + if "references" not in state.env: + return False + + # /* [ */ + if pos < max and state.src[pos] == "[": + start = pos + 1 + pos = state.md.helpers.parseLinkLabel(state, pos) + if pos >= 0: + label = state.src[start:pos] + pos += 1 + else: + pos = labelEnd + 1 + else: + pos = labelEnd + 1 + + # covers label == '' and label == undefined + # (collapsed reference link and shortcut reference link respectively) + if not label: + label = state.src[labelStart:labelEnd] + + label = normalizeReference(label) + + ref = state.env["references"].get(label, None) + if not ref: + state.pos = oldPos + return False + + href = ref["href"] + title = ref["title"] + + # + # We found the end of the link, and know for a fact it's a valid link + # so all that's left to do is to call tokenizer. + # + if not silent: + content = state.src[labelStart:labelEnd] + + tokens: list[Token] = [] + state.md.inline.parse(content, state.md, state.env, tokens) + + token = state.push("image", "img", 0) + token.attrs = {"src": href, "alt": ""} + token.children = tokens or None + token.content = content + + if title: + token.attrSet("title", title) + + # note, this is not part of markdown-it JS, but is useful for renderers + if label and state.md.options.get("store_labels", False): + token.meta["label"] = label + + state.pos = pos + state.posMax = max + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/link.py b/.venv/Lib/site-packages/markdown_it/rules_inline/link.py new file mode 100644 index 0000000..78cf912 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/link.py @@ -0,0 +1,151 @@ +# Process [link]( "stuff") + +from ..common.utils import isStrSpace, normalizeReference +from .state_inline import StateInline + + +def link(state: StateInline, silent: bool) -> bool: + href = "" + title = "" + label = None + oldPos = state.pos + maximum = state.posMax + start = state.pos + parseReference = True + + if state.src[state.pos] != "[": + return False + + labelStart = state.pos + 1 + labelEnd = state.md.helpers.parseLinkLabel(state, state.pos, True) + + # parser failed to find ']', so it's not a valid link + if labelEnd < 0: + return False + + pos = labelEnd + 1 + + if pos < maximum and state.src[pos] == "(": + # + # Inline link + # + + # might have found a valid shortcut link, disable reference parsing + parseReference = False + + # [link]( "title" ) + # ^^ skipping these spaces + pos += 1 + while pos < maximum: + ch = state.src[pos] + if not isStrSpace(ch) and ch != "\n": + break + pos += 1 + + if pos >= maximum: + return False + + # [link]( "title" ) + # ^^^^^^ parsing link destination + start = pos + res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax) + if res.ok: + href = state.md.normalizeLink(res.str) + if state.md.validateLink(href): + pos = res.pos + else: + href = "" + + # [link]( "title" ) + # ^^ skipping these spaces + start = pos + while pos < maximum: + ch = state.src[pos] + if not isStrSpace(ch) and ch != "\n": + break + pos += 1 + + # [link]( "title" ) + # ^^^^^^^ parsing link title + res = state.md.helpers.parseLinkTitle(state.src, pos, state.posMax) + if pos < maximum and start != pos and res.ok: + title = res.str + pos = res.pos + + # [link]( "title" ) + # ^^ skipping these spaces + while pos < maximum: + ch = state.src[pos] + if not isStrSpace(ch) and ch != "\n": + break + pos += 1 + + if pos >= maximum or state.src[pos] != ")": + # parsing a valid shortcut link failed, fallback to reference + parseReference = True + + pos += 1 + + if parseReference: + # + # Link reference + # + if "references" not in state.env: + return False + + if pos < maximum and state.src[pos] == "[": + start = pos + 1 + pos = state.md.helpers.parseLinkLabel(state, pos) + if pos >= 0: + label = state.src[start:pos] + pos += 1 + else: + pos = labelEnd + 1 + + else: + pos = labelEnd + 1 + + # covers label == '' and label == undefined + # (collapsed reference link and shortcut reference link respectively) + if not label: + label = state.src[labelStart:labelEnd] + + label = normalizeReference(label) + + ref = ( + state.env["references"][label] if label in state.env["references"] else None + ) + if not ref: + state.pos = oldPos + return False + + href = ref["href"] + title = ref["title"] + + # + # We found the end of the link, and know for a fact it's a valid link + # so all that's left to do is to call tokenizer. + # + if not silent: + state.pos = labelStart + state.posMax = labelEnd + + token = state.push("link_open", "a", 1) + token.attrs = {"href": href} + + if title: + token.attrSet("title", title) + + # note, this is not part of markdown-it JS, but is useful for renderers + if label and state.md.options.get("store_labels", False): + token.meta["label"] = label + + state.linkLevel += 1 + state.md.inline.tokenize(state) + state.linkLevel -= 1 + + token = state.push("link_close", "a", -1) + + state.pos = pos + state.posMax = maximum + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/linkify.py b/.venv/Lib/site-packages/markdown_it/rules_inline/linkify.py new file mode 100644 index 0000000..a8a1815 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/linkify.py @@ -0,0 +1,61 @@ +"""Process links like https://example.org/""" +import re + +from .state_inline import StateInline + +# RFC3986: scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) +SCHEME_RE = re.compile(r"(?:^|[^a-z0-9.+-])([a-z][a-z0-9.+-]*)$", re.IGNORECASE) + + +def linkify(state: StateInline, silent: bool) -> bool: + """Rule for identifying plain-text links.""" + if not state.md.options.linkify: + return False + if state.linkLevel > 0: + return False + if not state.md.linkify: + raise ModuleNotFoundError("Linkify enabled but not installed.") + + pos = state.pos + maximum = state.posMax + + if ( + (pos + 3) > maximum + or state.src[pos] != ":" + or state.src[pos + 1] != "/" + or state.src[pos + 2] != "/" + ): + return False + + if not (match := SCHEME_RE.match(state.pending)): + return False + + proto = match.group(1) + if not (link := state.md.linkify.match_at_start(state.src[pos - len(proto) :])): + return False + url: str = link.url + + # disallow '*' at the end of the link (conflicts with emphasis) + url = url.rstrip("*") + + full_url = state.md.normalizeLink(url) + if not state.md.validateLink(full_url): + return False + + if not silent: + state.pending = state.pending[: -len(proto)] + + token = state.push("link_open", "a", 1) + token.attrs = {"href": full_url} + token.markup = "linkify" + token.info = "auto" + + token = state.push("text", "", 0) + token.content = state.md.normalizeLinkText(url) + + token = state.push("link_close", "a", -1) + token.markup = "linkify" + token.info = "auto" + + state.pos += len(url) - len(proto) + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/newline.py b/.venv/Lib/site-packages/markdown_it/rules_inline/newline.py new file mode 100644 index 0000000..ca8f1db --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/newline.py @@ -0,0 +1,43 @@ +"""Proceess '\n'.""" +from ..common.utils import charStrAt, isStrSpace +from .state_inline import StateInline + + +def newline(state: StateInline, silent: bool) -> bool: + pos = state.pos + + if state.src[pos] != "\n": + return False + + pmax = len(state.pending) - 1 + maximum = state.posMax + + # ' \n' -> hardbreak + # Lookup in pending chars is bad practice! Don't copy to other rules! + # Pending string is stored in concat mode, indexed lookups will cause + # conversion to flat mode. + if not silent: + if pmax >= 0 and charStrAt(state.pending, pmax) == " ": + if pmax >= 1 and charStrAt(state.pending, pmax - 1) == " ": + # Find whitespaces tail of pending chars. + ws = pmax - 1 + while ws >= 1 and charStrAt(state.pending, ws - 1) == " ": + ws -= 1 + state.pending = state.pending[:ws] + + state.push("hardbreak", "br", 0) + else: + state.pending = state.pending[:-1] + state.push("softbreak", "br", 0) + + else: + state.push("softbreak", "br", 0) + + pos += 1 + + # skip heading spaces for next line + while pos < maximum and isStrSpace(state.src[pos]): + pos += 1 + + state.pos = pos + return True diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/state_inline.py b/.venv/Lib/site-packages/markdown_it/rules_inline/state_inline.py new file mode 100644 index 0000000..c0c491c --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/state_inline.py @@ -0,0 +1,166 @@ +from __future__ import annotations + +from collections import namedtuple +from dataclasses import dataclass +from typing import TYPE_CHECKING, Any, Literal + +from .._compat import DATACLASS_KWARGS +from ..common.utils import isMdAsciiPunct, isPunctChar, isWhiteSpace +from ..ruler import StateBase +from ..token import Token +from ..utils import EnvType + +if TYPE_CHECKING: + from markdown_it import MarkdownIt + + +@dataclass(**DATACLASS_KWARGS) +class Delimiter: + # Char code of the starting marker (number). + marker: int + + # Total length of these series of delimiters. + length: int + + # A position of the token this delimiter corresponds to. + token: int + + # If this delimiter is matched as a valid opener, `end` will be + # equal to its position, otherwise it's `-1`. + end: int + + # Boolean flags that determine if this delimiter could open or close + # an emphasis. + open: bool + close: bool + + level: bool | None = None + + +Scanned = namedtuple("Scanned", ["can_open", "can_close", "length"]) + + +class StateInline(StateBase): + def __init__( + self, src: str, md: MarkdownIt, env: EnvType, outTokens: list[Token] + ) -> None: + self.src = src + self.env = env + self.md = md + self.tokens = outTokens + self.tokens_meta: list[dict[str, Any] | None] = [None] * len(outTokens) + + self.pos = 0 + self.posMax = len(self.src) + self.level = 0 + self.pending = "" + self.pendingLevel = 0 + + # Stores { start: end } pairs. Useful for backtrack + # optimization of pairs parse (emphasis, strikes). + self.cache: dict[int, int] = {} + + # List of emphasis-like delimiters for current tag + self.delimiters: list[Delimiter] = [] + + # Stack of delimiter lists for upper level tags + self._prev_delimiters: list[list[Delimiter]] = [] + + # backticklength => last seen position + self.backticks: dict[int, int] = {} + self.backticksScanned = False + + # Counter used to disable inline linkify-it execution + # inside and markdown links + self.linkLevel = 0 + + def __repr__(self) -> str: + return ( + f"{self.__class__.__name__}" + f"(pos=[{self.pos} of {self.posMax}], token={len(self.tokens)})" + ) + + def pushPending(self) -> Token: + token = Token("text", "", 0) + token.content = self.pending + token.level = self.pendingLevel + self.tokens.append(token) + self.pending = "" + return token + + def push(self, ttype: str, tag: str, nesting: Literal[-1, 0, 1]) -> Token: + """Push new token to "stream". + If pending text exists - flush it as text token + """ + if self.pending: + self.pushPending() + + token = Token(ttype, tag, nesting) + token_meta = None + + if nesting < 0: + # closing tag + self.level -= 1 + self.delimiters = self._prev_delimiters.pop() + + token.level = self.level + + if nesting > 0: + # opening tag + self.level += 1 + self._prev_delimiters.append(self.delimiters) + self.delimiters = [] + token_meta = {"delimiters": self.delimiters} + + self.pendingLevel = self.level + self.tokens.append(token) + self.tokens_meta.append(token_meta) + return token + + def scanDelims(self, start: int, canSplitWord: bool) -> Scanned: + """ + Scan a sequence of emphasis-like markers, and determine whether + it can start an emphasis sequence or end an emphasis sequence. + + - start - position to scan from (it should point at a valid marker); + - canSplitWord - determine if these markers can be found inside a word + + """ + pos = start + maximum = self.posMax + marker = self.src[start] + + # treat beginning of the line as a whitespace + lastChar = self.src[start - 1] if start > 0 else " " + + while pos < maximum and self.src[pos] == marker: + pos += 1 + + count = pos - start + + # treat end of the line as a whitespace + nextChar = self.src[pos] if pos < maximum else " " + + isLastPunctChar = isMdAsciiPunct(ord(lastChar)) or isPunctChar(lastChar) + isNextPunctChar = isMdAsciiPunct(ord(nextChar)) or isPunctChar(nextChar) + + isLastWhiteSpace = isWhiteSpace(ord(lastChar)) + isNextWhiteSpace = isWhiteSpace(ord(nextChar)) + + left_flanking = not ( + isNextWhiteSpace + or (isNextPunctChar and not (isLastWhiteSpace or isLastPunctChar)) + ) + right_flanking = not ( + isLastWhiteSpace + or (isLastPunctChar and not (isNextWhiteSpace or isNextPunctChar)) + ) + + if not canSplitWord: + can_open = left_flanking and ((not right_flanking) or isLastPunctChar) + can_close = right_flanking and ((not left_flanking) or isNextPunctChar) + else: + can_open = left_flanking + can_close = right_flanking + + return Scanned(can_open, can_close, count) diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/strikethrough.py b/.venv/Lib/site-packages/markdown_it/rules_inline/strikethrough.py new file mode 100644 index 0000000..ec81628 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/strikethrough.py @@ -0,0 +1,127 @@ +# ~~strike through~~ +from __future__ import annotations + +from .state_inline import Delimiter, StateInline + + +def tokenize(state: StateInline, silent: bool) -> bool: + """Insert each marker as a separate text token, and add it to delimiter list""" + start = state.pos + ch = state.src[start] + + if silent: + return False + + if ch != "~": + return False + + scanned = state.scanDelims(state.pos, True) + length = scanned.length + + if length < 2: + return False + + if length % 2: + token = state.push("text", "", 0) + token.content = ch + length -= 1 + + i = 0 + while i < length: + token = state.push("text", "", 0) + token.content = ch + ch + state.delimiters.append( + Delimiter( + marker=ord(ch), + length=0, # disable "rule of 3" length checks meant for emphasis + token=len(state.tokens) - 1, + end=-1, + open=scanned.can_open, + close=scanned.can_close, + ) + ) + + i += 2 + + state.pos += scanned.length + + return True + + +def _postProcess(state: StateInline, delimiters: list[Delimiter]) -> None: + loneMarkers = [] + maximum = len(delimiters) + + i = 0 + while i < maximum: + startDelim = delimiters[i] + + if startDelim.marker != 0x7E: # /* ~ */ + i += 1 + continue + + if startDelim.end == -1: + i += 1 + continue + + endDelim = delimiters[startDelim.end] + + token = state.tokens[startDelim.token] + token.type = "s_open" + token.tag = "s" + token.nesting = 1 + token.markup = "~~" + token.content = "" + + token = state.tokens[endDelim.token] + token.type = "s_close" + token.tag = "s" + token.nesting = -1 + token.markup = "~~" + token.content = "" + + if ( + state.tokens[endDelim.token - 1].type == "text" + and state.tokens[endDelim.token - 1].content == "~" + ): + loneMarkers.append(endDelim.token - 1) + + i += 1 + + # If a marker sequence has an odd number of characters, it's split + # like this: `~~~~~` -> `~` + `~~` + `~~`, leaving one marker at the + # start of the sequence. + # + # So, we have to move all those markers after subsequent s_close tags. + # + while loneMarkers: + i = loneMarkers.pop() + j = i + 1 + + while (j < len(state.tokens)) and (state.tokens[j].type == "s_close"): + j += 1 + + j -= 1 + + if i != j: + token = state.tokens[j] + state.tokens[j] = state.tokens[i] + state.tokens[i] = token + + +def postProcess(state: StateInline) -> None: + """Walk through delimiter list and replace text tokens with tags.""" + tokens_meta = state.tokens_meta + maximum = len(state.tokens_meta) + _postProcess(state, state.delimiters) + + curr = 0 + while curr < maximum: + try: + curr_meta = tokens_meta[curr] + except IndexError: + pass + else: + if curr_meta and "delimiters" in curr_meta: + _postProcess(state, curr_meta["delimiters"]) + curr += 1 diff --git a/.venv/Lib/site-packages/markdown_it/rules_inline/text.py b/.venv/Lib/site-packages/markdown_it/rules_inline/text.py new file mode 100644 index 0000000..f306b2e --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/rules_inline/text.py @@ -0,0 +1,53 @@ +# Skip text characters for text token, place those to pending buffer +# and increment current pos +from .state_inline import StateInline + +# Rule to skip pure text +# '{}$%@~+=:' reserved for extensions + +# !!!! Don't confuse with "Markdown ASCII Punctuation" chars +# http://spec.commonmark.org/0.15/#ascii-punctuation-character + + +_TerminatorChars = { + "\n", + "!", + "#", + "$", + "%", + "&", + "*", + "+", + "-", + ":", + "<", + "=", + ">", + "@", + "[", + "\\", + "]", + "^", + "_", + "`", + "{", + "}", + "~", +} + + +def text(state: StateInline, silent: bool) -> bool: + pos = state.pos + posMax = state.posMax + while (pos < posMax) and state.src[pos] not in _TerminatorChars: + pos += 1 + + if pos == state.pos: + return False + + if not silent: + state.pending += state.src[state.pos : pos] + + state.pos = pos + + return True diff --git a/.venv/Lib/site-packages/markdown_it/token.py b/.venv/Lib/site-packages/markdown_it/token.py new file mode 100644 index 0000000..90008b7 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/token.py @@ -0,0 +1,180 @@ +from __future__ import annotations + +from collections.abc import Callable, MutableMapping +import dataclasses as dc +from typing import Any, Literal +import warnings + +from markdown_it._compat import DATACLASS_KWARGS + + +def convert_attrs(value: Any) -> Any: + """Convert Token.attrs set as ``None`` or ``[[key, value], ...]`` to a dict. + + This improves compatibility with upstream markdown-it. + """ + if not value: + return {} + if isinstance(value, list): + return dict(value) + return value + + +@dc.dataclass(**DATACLASS_KWARGS) +class Token: + type: str + """Type of the token (string, e.g. "paragraph_open")""" + + tag: str + """HTML tag name, e.g. 'p'""" + + nesting: Literal[-1, 0, 1] + """Level change (number in {-1, 0, 1} set), where: + - `1` means the tag is opening + - `0` means the tag is self-closing + - `-1` means the tag is closing + """ + + attrs: dict[str, str | int | float] = dc.field(default_factory=dict) + """HTML attributes. + Note this differs from the upstream "list of lists" format, + although than an instance can still be initialised with this format. + """ + + map: list[int] | None = None + """Source map info. Format: `[ line_begin, line_end ]`""" + + level: int = 0 + """Nesting level, the same as `state.level`""" + + children: list[Token] | None = None + """Array of child nodes (inline and img tokens).""" + + content: str = "" + """Inner content, in the case of a self-closing tag (code, html, fence, etc.),""" + + markup: str = "" + """'*' or '_' for emphasis, fence string for fence, etc.""" + + info: str = "" + """Additional information: + - Info string for "fence" tokens + - The value "auto" for autolink "link_open" and "link_close" tokens + - The string value of the item marker for ordered-list "list_item_open" tokens + """ + + meta: dict[Any, Any] = dc.field(default_factory=dict) + """A place for plugins to store any arbitrary data""" + + block: bool = False + """True for block-level tokens, false for inline tokens. + Used in renderer to calculate line breaks + """ + + hidden: bool = False + """If true, ignore this element when rendering. + Used for tight lists to hide paragraphs. + """ + + def __post_init__(self) -> None: + self.attrs = convert_attrs(self.attrs) + + def attrIndex(self, name: str) -> int: + warnings.warn( # noqa: B028 + "Token.attrIndex should not be used, since Token.attrs is a dictionary", + UserWarning, + ) + if name not in self.attrs: + return -1 + return list(self.attrs.keys()).index(name) + + def attrItems(self) -> list[tuple[str, str | int | float]]: + """Get (key, value) list of attrs.""" + return list(self.attrs.items()) + + def attrPush(self, attrData: tuple[str, str | int | float]) -> None: + """Add `[ name, value ]` attribute to list. Init attrs if necessary.""" + name, value = attrData + self.attrSet(name, value) + + def attrSet(self, name: str, value: str | int | float) -> None: + """Set `name` attribute to `value`. Override old value if exists.""" + self.attrs[name] = value + + def attrGet(self, name: str) -> None | str | int | float: + """Get the value of attribute `name`, or null if it does not exist.""" + return self.attrs.get(name, None) + + def attrJoin(self, name: str, value: str) -> None: + """Join value to existing attribute via space. + Or create new attribute if not exists. + Useful to operate with token classes. + """ + if name in self.attrs: + current = self.attrs[name] + if not isinstance(current, str): + raise TypeError( + f"existing attr 'name' is not a str: {self.attrs[name]}" + ) + self.attrs[name] = f"{current} {value}" + else: + self.attrs[name] = value + + def copy(self, **changes: Any) -> Token: + """Return a shallow copy of the instance.""" + return dc.replace(self, **changes) + + def as_dict( + self, + *, + children: bool = True, + as_upstream: bool = True, + meta_serializer: Callable[[dict[Any, Any]], Any] | None = None, + filter: Callable[[str, Any], bool] | None = None, + dict_factory: Callable[..., MutableMapping[str, Any]] = dict, + ) -> MutableMapping[str, Any]: + """Return the token as a dictionary. + + :param children: Also convert children to dicts + :param as_upstream: Ensure the output dictionary is equal to that created by markdown-it + For example, attrs are converted to null or lists + :param meta_serializer: hook for serializing ``Token.meta`` + :param filter: A callable whose return code determines whether an + attribute or element is included (``True``) or dropped (``False``). + Is called with the (key, value) pair. + :param dict_factory: A callable to produce dictionaries from. + For example, to produce ordered dictionaries instead of normal Python + dictionaries, pass in ``collections.OrderedDict``. + + """ + mapping = dict_factory((f.name, getattr(self, f.name)) for f in dc.fields(self)) + if filter: + mapping = dict_factory((k, v) for k, v in mapping.items() if filter(k, v)) + if as_upstream and "attrs" in mapping: + mapping["attrs"] = ( + None + if not mapping["attrs"] + else [[k, v] for k, v in mapping["attrs"].items()] + ) + if meta_serializer and "meta" in mapping: + mapping["meta"] = meta_serializer(mapping["meta"]) + if children and mapping.get("children", None): + mapping["children"] = [ + child.as_dict( + children=children, + filter=filter, + dict_factory=dict_factory, + as_upstream=as_upstream, + meta_serializer=meta_serializer, + ) + for child in mapping["children"] + ] + return mapping + + @classmethod + def from_dict(cls, dct: MutableMapping[str, Any]) -> Token: + """Convert a dict to a Token.""" + token = cls(**dct) + if token.children: + token.children = [cls.from_dict(c) for c in token.children] # type: ignore[arg-type] + return token diff --git a/.venv/Lib/site-packages/markdown_it/tree.py b/.venv/Lib/site-packages/markdown_it/tree.py new file mode 100644 index 0000000..6641e5a --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/tree.py @@ -0,0 +1,345 @@ +"""A tree representation of a linear markdown-it token stream. + +This module is not part of upstream JavaScript markdown-it. +""" +from __future__ import annotations + +from collections.abc import Generator, Sequence +import textwrap +from typing import Any, NamedTuple, TypeVar, overload + +from .token import Token + + +class _NesterTokens(NamedTuple): + opening: Token + closing: Token + + +_NodeType = TypeVar("_NodeType", bound="SyntaxTreeNode") + + +class SyntaxTreeNode: + """A Markdown syntax tree node. + + A class that can be used to construct a tree representation of a linear + `markdown-it-py` token stream. + + Each node in the tree represents either: + - root of the Markdown document + - a single unnested `Token` + - a `Token` "_open" and "_close" token pair, and the tokens nested in + between + """ + + def __init__( + self, tokens: Sequence[Token] = (), *, create_root: bool = True + ) -> None: + """Initialize a `SyntaxTreeNode` from a token stream. + + If `create_root` is True, create a root node for the document. + """ + # Only nodes representing an unnested token have self.token + self.token: Token | None = None + + # Only containers have nester tokens + self.nester_tokens: _NesterTokens | None = None + + # Root node does not have self.parent + self._parent: Any = None + + # Empty list unless a non-empty container, or unnested token that has + # children (i.e. inline or img) + self._children: list[Any] = [] + + if create_root: + self._set_children_from_tokens(tokens) + return + + if not tokens: + raise ValueError( + "Can only create root from empty token sequence." + " Set `create_root=True`." + ) + elif len(tokens) == 1: + inline_token = tokens[0] + if inline_token.nesting: + raise ValueError( + "Unequal nesting level at the start and end of token stream." + ) + self.token = inline_token + if inline_token.children: + self._set_children_from_tokens(inline_token.children) + else: + self.nester_tokens = _NesterTokens(tokens[0], tokens[-1]) + self._set_children_from_tokens(tokens[1:-1]) + + def __repr__(self) -> str: + return f"{type(self).__name__}({self.type})" + + @overload + def __getitem__(self: _NodeType, item: int) -> _NodeType: + ... + + @overload + def __getitem__(self: _NodeType, item: slice) -> list[_NodeType]: + ... + + def __getitem__(self: _NodeType, item: int | slice) -> _NodeType | list[_NodeType]: + return self.children[item] + + def to_tokens(self: _NodeType) -> list[Token]: + """Recover the linear token stream.""" + + def recursive_collect_tokens(node: _NodeType, token_list: list[Token]) -> None: + if node.type == "root": + for child in node.children: + recursive_collect_tokens(child, token_list) + elif node.token: + token_list.append(node.token) + else: + assert node.nester_tokens + token_list.append(node.nester_tokens.opening) + for child in node.children: + recursive_collect_tokens(child, token_list) + token_list.append(node.nester_tokens.closing) + + tokens: list[Token] = [] + recursive_collect_tokens(self, tokens) + return tokens + + @property + def children(self: _NodeType) -> list[_NodeType]: + return self._children + + @children.setter + def children(self: _NodeType, value: list[_NodeType]) -> None: + self._children = value + + @property + def parent(self: _NodeType) -> _NodeType | None: + return self._parent # type: ignore + + @parent.setter + def parent(self: _NodeType, value: _NodeType | None) -> None: + self._parent = value + + @property + def is_root(self) -> bool: + """Is the node a special root node?""" + return not (self.token or self.nester_tokens) + + @property + def is_nested(self) -> bool: + """Is this node nested?. + + Returns `True` if the node represents a `Token` pair and tokens in the + sequence between them, where `Token.nesting` of the first `Token` in + the pair is 1 and nesting of the other `Token` is -1. + """ + return bool(self.nester_tokens) + + @property + def siblings(self: _NodeType) -> Sequence[_NodeType]: + """Get siblings of the node. + + Gets the whole group of siblings, including self. + """ + if not self.parent: + return [self] + return self.parent.children + + @property + def type(self) -> str: + """Get a string type of the represented syntax. + + - "root" for root nodes + - `Token.type` if the node represents an unnested token + - `Token.type` of the opening token, with "_open" suffix stripped, if + the node represents a nester token pair + """ + if self.is_root: + return "root" + if self.token: + return self.token.type + assert self.nester_tokens + return _removesuffix(self.nester_tokens.opening.type, "_open") + + @property + def next_sibling(self: _NodeType) -> _NodeType | None: + """Get the next node in the sequence of siblings. + + Returns `None` if this is the last sibling. + """ + self_index = self.siblings.index(self) + if self_index + 1 < len(self.siblings): + return self.siblings[self_index + 1] + return None + + @property + def previous_sibling(self: _NodeType) -> _NodeType | None: + """Get the previous node in the sequence of siblings. + + Returns `None` if this is the first sibling. + """ + self_index = self.siblings.index(self) + if self_index - 1 >= 0: + return self.siblings[self_index - 1] + return None + + def _add_child( + self, + tokens: Sequence[Token], + ) -> None: + """Make a child node for `self`.""" + child = type(self)(tokens, create_root=False) + child.parent = self + self.children.append(child) + + def _set_children_from_tokens(self, tokens: Sequence[Token]) -> None: + """Convert the token stream to a tree structure and set the resulting + nodes as children of `self`.""" + reversed_tokens = list(reversed(tokens)) + while reversed_tokens: + token = reversed_tokens.pop() + + if not token.nesting: + self._add_child([token]) + continue + if token.nesting != 1: + raise ValueError("Invalid token nesting") + + nested_tokens = [token] + nesting = 1 + while reversed_tokens and nesting: + token = reversed_tokens.pop() + nested_tokens.append(token) + nesting += token.nesting + if nesting: + raise ValueError(f"unclosed tokens starting {nested_tokens[0]}") + + self._add_child(nested_tokens) + + def pretty( + self, *, indent: int = 2, show_text: bool = False, _current: int = 0 + ) -> str: + """Create an XML style string of the tree.""" + prefix = " " * _current + text = prefix + f"<{self.type}" + if not self.is_root and self.attrs: + text += " " + " ".join(f"{k}={v!r}" for k, v in self.attrs.items()) + text += ">" + if ( + show_text + and not self.is_root + and self.type in ("text", "text_special") + and self.content + ): + text += "\n" + textwrap.indent(self.content, prefix + " " * indent) + for child in self.children: + text += "\n" + child.pretty( + indent=indent, show_text=show_text, _current=_current + indent + ) + return text + + def walk( + self: _NodeType, *, include_self: bool = True + ) -> Generator[_NodeType, None, None]: + """Recursively yield all descendant nodes in the tree starting at self. + + The order mimics the order of the underlying linear token + stream (i.e. depth first). + """ + if include_self: + yield self + for child in self.children: + yield from child.walk(include_self=True) + + # NOTE: + # The values of the properties defined below directly map to properties + # of the underlying `Token`s. A root node does not translate to a `Token` + # object, so calling these property getters on a root node will raise an + # `AttributeError`. + # + # There is no mapping for `Token.nesting` because the `is_nested` property + # provides that data, and can be called on any node type, including root. + + def _attribute_token(self) -> Token: + """Return the `Token` that is used as the data source for the + properties defined below.""" + if self.token: + return self.token + if self.nester_tokens: + return self.nester_tokens.opening + raise AttributeError("Root node does not have the accessed attribute") + + @property + def tag(self) -> str: + """html tag name, e.g. \"p\" """ + return self._attribute_token().tag + + @property + def attrs(self) -> dict[str, str | int | float]: + """Html attributes.""" + return self._attribute_token().attrs + + def attrGet(self, name: str) -> None | str | int | float: + """Get the value of attribute `name`, or null if it does not exist.""" + return self._attribute_token().attrGet(name) + + @property + def map(self) -> tuple[int, int] | None: + """Source map info. Format: `tuple[ line_begin, line_end ]`""" + map_ = self._attribute_token().map + if map_: + # Type ignore because `Token`s attribute types are not perfect + return tuple(map_) # type: ignore + return None + + @property + def level(self) -> int: + """nesting level, the same as `state.level`""" + return self._attribute_token().level + + @property + def content(self) -> str: + """In a case of self-closing tag (code, html, fence, etc.), it + has contents of this tag.""" + return self._attribute_token().content + + @property + def markup(self) -> str: + """'*' or '_' for emphasis, fence string for fence, etc.""" + return self._attribute_token().markup + + @property + def info(self) -> str: + """fence infostring""" + return self._attribute_token().info + + @property + def meta(self) -> dict[Any, Any]: + """A place for plugins to store an arbitrary data.""" + return self._attribute_token().meta + + @property + def block(self) -> bool: + """True for block-level tokens, false for inline tokens.""" + return self._attribute_token().block + + @property + def hidden(self) -> bool: + """If it's true, ignore this element when rendering. + Used for tight lists to hide paragraphs.""" + return self._attribute_token().hidden + + +def _removesuffix(string: str, suffix: str) -> str: + """Remove a suffix from a string. + + Replace this with str.removesuffix() from stdlib when minimum Python + version is 3.9. + """ + if suffix and string.endswith(suffix): + return string[: -len(suffix)] + return string diff --git a/.venv/Lib/site-packages/markdown_it/utils.py b/.venv/Lib/site-packages/markdown_it/utils.py new file mode 100644 index 0000000..a979372 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it/utils.py @@ -0,0 +1,176 @@ +from __future__ import annotations + +from collections.abc import MutableMapping as MutableMappingABC +from pathlib import Path +from typing import Any, Callable, Iterable, MutableMapping, TypedDict, cast + +EnvType = MutableMapping[str, Any] # note: could use TypeAlias in python 3.10 +"""Type for the environment sandbox used in parsing and rendering, +which stores mutable variables for use by plugins and rules. +""" + + +class OptionsType(TypedDict): + """Options for parsing.""" + + maxNesting: int + """Internal protection, recursion limit.""" + html: bool + """Enable HTML tags in source.""" + linkify: bool + """Enable autoconversion of URL-like texts to links.""" + typographer: bool + """Enable smartquotes and replacements.""" + quotes: str + """Quote characters.""" + xhtmlOut: bool + """Use '/' to close single tags (
).""" + breaks: bool + """Convert newlines in paragraphs into
.""" + langPrefix: str + """CSS language prefix for fenced blocks.""" + highlight: Callable[[str, str, str], str] | None + """Highlighter function: (content, lang, attrs) -> str.""" + + +class PresetType(TypedDict): + """Preset configuration for markdown-it.""" + + options: OptionsType + """Options for parsing.""" + components: MutableMapping[str, MutableMapping[str, list[str]]] + """Components for parsing and rendering.""" + + +class OptionsDict(MutableMappingABC): # type: ignore + """A dictionary, with attribute access to core markdownit configuration options.""" + + # Note: ideally we would probably just remove attribute access entirely, + # but we keep it for backwards compatibility. + + def __init__(self, options: OptionsType) -> None: + self._options = cast(OptionsType, dict(options)) + + def __getitem__(self, key: str) -> Any: + return self._options[key] # type: ignore[literal-required] + + def __setitem__(self, key: str, value: Any) -> None: + self._options[key] = value # type: ignore[literal-required] + + def __delitem__(self, key: str) -> None: + del self._options[key] # type: ignore + + def __iter__(self) -> Iterable[str]: # type: ignore + return iter(self._options) + + def __len__(self) -> int: + return len(self._options) + + def __repr__(self) -> str: + return repr(self._options) + + def __str__(self) -> str: + return str(self._options) + + @property + def maxNesting(self) -> int: + """Internal protection, recursion limit.""" + return self._options["maxNesting"] + + @maxNesting.setter + def maxNesting(self, value: int) -> None: + self._options["maxNesting"] = value + + @property + def html(self) -> bool: + """Enable HTML tags in source.""" + return self._options["html"] + + @html.setter + def html(self, value: bool) -> None: + self._options["html"] = value + + @property + def linkify(self) -> bool: + """Enable autoconversion of URL-like texts to links.""" + return self._options["linkify"] + + @linkify.setter + def linkify(self, value: bool) -> None: + self._options["linkify"] = value + + @property + def typographer(self) -> bool: + """Enable smartquotes and replacements.""" + return self._options["typographer"] + + @typographer.setter + def typographer(self, value: bool) -> None: + self._options["typographer"] = value + + @property + def quotes(self) -> str: + """Quote characters.""" + return self._options["quotes"] + + @quotes.setter + def quotes(self, value: str) -> None: + self._options["quotes"] = value + + @property + def xhtmlOut(self) -> bool: + """Use '/' to close single tags (
).""" + return self._options["xhtmlOut"] + + @xhtmlOut.setter + def xhtmlOut(self, value: bool) -> None: + self._options["xhtmlOut"] = value + + @property + def breaks(self) -> bool: + """Convert newlines in paragraphs into
.""" + return self._options["breaks"] + + @breaks.setter + def breaks(self, value: bool) -> None: + self._options["breaks"] = value + + @property + def langPrefix(self) -> str: + """CSS language prefix for fenced blocks.""" + return self._options["langPrefix"] + + @langPrefix.setter + def langPrefix(self, value: str) -> None: + self._options["langPrefix"] = value + + @property + def highlight(self) -> Callable[[str, str, str], str] | None: + """Highlighter function: (content, langName, langAttrs) -> escaped HTML.""" + return self._options["highlight"] + + @highlight.setter + def highlight(self, value: Callable[[str, str, str], str] | None) -> None: + self._options["highlight"] = value + + +def read_fixture_file(path: str | Path) -> list[list[Any]]: + text = Path(path).read_text(encoding="utf-8") + tests = [] + section = 0 + last_pos = 0 + lines = text.splitlines(keepends=True) + for i in range(len(lines)): + if lines[i].rstrip() == ".": + if section == 0: + tests.append([i, lines[i - 1].strip()]) + section = 1 + elif section == 1: + tests[-1].append("".join(lines[last_pos + 1 : i])) + section = 2 + elif section == 2: + tests[-1].append("".join(lines[last_pos + 1 : i])) + section = 0 + + last_pos = i + return tests diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/INSTALLER b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE new file mode 100644 index 0000000..582ddf5 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 ExecutableBookProject + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE.markdown-it b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE.markdown-it new file mode 100644 index 0000000..7ffa058 --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/LICENSE.markdown-it @@ -0,0 +1,22 @@ +Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin. + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/METADATA b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/METADATA new file mode 100644 index 0000000..8a2978b --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/METADATA @@ -0,0 +1,205 @@ +Metadata-Version: 2.1 +Name: markdown-it-py +Version: 3.0.0 +Summary: Python port of markdown-it. Markdown parsing, done right! +Keywords: markdown,lexer,parser,commonmark,markdown-it +Author-email: Chris Sewell +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: Text Processing :: Markup +Requires-Dist: mdurl~=0.1 +Requires-Dist: psutil ; extra == "benchmarking" +Requires-Dist: pytest ; extra == "benchmarking" +Requires-Dist: pytest-benchmark ; extra == "benchmarking" +Requires-Dist: pre-commit~=3.0 ; extra == "code_style" +Requires-Dist: commonmark~=0.9 ; extra == "compare" +Requires-Dist: markdown~=3.4 ; extra == "compare" +Requires-Dist: mistletoe~=1.0 ; extra == "compare" +Requires-Dist: mistune~=2.0 ; extra == "compare" +Requires-Dist: panflute~=2.3 ; extra == "compare" +Requires-Dist: linkify-it-py>=1,<3 ; extra == "linkify" +Requires-Dist: mdit-py-plugins ; extra == "plugins" +Requires-Dist: gprof2dot ; extra == "profiling" +Requires-Dist: mdit-py-plugins ; extra == "rtd" +Requires-Dist: myst-parser ; extra == "rtd" +Requires-Dist: pyyaml ; extra == "rtd" +Requires-Dist: sphinx ; extra == "rtd" +Requires-Dist: sphinx-copybutton ; extra == "rtd" +Requires-Dist: sphinx-design ; extra == "rtd" +Requires-Dist: sphinx_book_theme ; extra == "rtd" +Requires-Dist: jupyter_sphinx ; extra == "rtd" +Requires-Dist: coverage ; extra == "testing" +Requires-Dist: pytest ; extra == "testing" +Requires-Dist: pytest-cov ; extra == "testing" +Requires-Dist: pytest-regressions ; extra == "testing" +Project-URL: Documentation, https://markdown-it-py.readthedocs.io +Project-URL: Homepage, https://github.com/executablebooks/markdown-it-py +Provides-Extra: benchmarking +Provides-Extra: code_style +Provides-Extra: compare +Provides-Extra: linkify +Provides-Extra: plugins +Provides-Extra: profiling +Provides-Extra: rtd +Provides-Extra: testing + +# markdown-it-py + +[![Github-CI][github-ci]][github-link] +[![Coverage Status][codecov-badge]][codecov-link] +[![PyPI][pypi-badge]][pypi-link] +[![Conda][conda-badge]][conda-link] +[![Code style: black][black-badge]][black-link] +[![PyPI - Downloads][install-badge]][install-link] + +> Markdown parser done right. + +- Follows the __[CommonMark spec](http://spec.commonmark.org/)__ for baseline parsing +- Configurable syntax: you can add new rules and even replace existing ones. +- Pluggable: Adds syntax extensions to extend the parser (see the [plugin list][md-plugins]). +- High speed (see our [benchmarking tests][md-performance]) +- [Safe by default][md-security] +- Member of [Google's Assured Open Source Software](https://cloud.google.com/assured-open-source-software/docs/supported-packages) + +This is a Python port of [markdown-it], and some of its associated plugins. +For more details see: . + +For details on [markdown-it] itself, see: + +- The __[Live demo](https://markdown-it.github.io)__ +- [The markdown-it README][markdown-it-readme] + +## Installation + +```bash +conda install -c conda-forge markdown-it-py +``` + +or + +```bash +pip install markdown-it-py[plugins] +``` + +or with extras + +```bash +conda install -c conda-forge markdown-it-py linkify-it-py mdit-py-plugins +pip install markdown-it-py[linkify,plugins] +``` + +## Usage + +### Python API Usage + +Render markdown to HTML with markdown-it-py and a custom configuration +with and without plugins and features: + +```python +from markdown_it import MarkdownIt +from mdit_py_plugins.front_matter import front_matter_plugin +from mdit_py_plugins.footnote import footnote_plugin + +md = ( + MarkdownIt('commonmark' ,{'breaks':True,'html':True}) + .use(front_matter_plugin) + .use(footnote_plugin) + .enable('table') +) +text = (""" +--- +a: 1 +--- + +a | b +- | - +1 | 2 + +A footnote [^1] + +[^1]: some details +""") +tokens = md.parse(text) +html_text = md.render(text) + +## To export the html to a file, uncomment the lines below: +# from pathlib import Path +# Path("output.html").write_text(html_text) +``` + +### Command-line Usage + +Render markdown to HTML with markdown-it-py from the +command-line: + +```console +usage: markdown-it [-h] [-v] [filenames [filenames ...]] + +Parse one or more markdown files, convert each to HTML, and print to stdout + +positional arguments: + filenames specify an optional list of files to convert + +optional arguments: + -h, --help show this help message and exit + -v, --version show program's version number and exit + +Interactive: + + $ markdown-it + markdown-it-py [version 0.0.0] (interactive) + Type Ctrl-D to complete input, or Ctrl-C to exit. + >>> # Example + ... > markdown *input* + ... +

Example

+
+

markdown input

+
+ +Batch: + + $ markdown-it README.md README.footer.md > index.html + +``` + +## References / Thanks + +Big thanks to the authors of [markdown-it]: + +- Alex Kocharin [github/rlidwka](https://github.com/rlidwka) +- Vitaly Puzrin [github/puzrin](https://github.com/puzrin) + +Also [John MacFarlane](https://github.com/jgm) for his work on the CommonMark spec and reference implementations. + +[github-ci]: https://github.com/executablebooks/markdown-it-py/workflows/Python%20package/badge.svg?branch=master +[github-link]: https://github.com/executablebooks/markdown-it-py +[pypi-badge]: https://img.shields.io/pypi/v/markdown-it-py.svg +[pypi-link]: https://pypi.org/project/markdown-it-py +[conda-badge]: https://anaconda.org/conda-forge/markdown-it-py/badges/version.svg +[conda-link]: https://anaconda.org/conda-forge/markdown-it-py +[codecov-badge]: https://codecov.io/gh/executablebooks/markdown-it-py/branch/master/graph/badge.svg +[codecov-link]: https://codecov.io/gh/executablebooks/markdown-it-py +[black-badge]: https://img.shields.io/badge/code%20style-black-000000.svg +[black-link]: https://github.com/ambv/black +[install-badge]: https://img.shields.io/pypi/dw/markdown-it-py?label=pypi%20installs +[install-link]: https://pypistats.org/packages/markdown-it-py + +[CommonMark spec]: http://spec.commonmark.org/ +[markdown-it]: https://github.com/markdown-it/markdown-it +[markdown-it-readme]: https://github.com/markdown-it/markdown-it/blob/master/README.md +[md-security]: https://markdown-it-py.readthedocs.io/en/latest/other.html +[md-performance]: https://markdown-it-py.readthedocs.io/en/latest/other.html +[md-plugins]: https://markdown-it-py.readthedocs.io/en/latest/plugins.html + diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/RECORD b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/RECORD new file mode 100644 index 0000000..936f27d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/RECORD @@ -0,0 +1,142 @@ +../../Scripts/markdown-it.exe,sha256=VPSFTImOyPpwTwVmz7HGJOJDEu5qebqkM8F9__gw5uA,108446 +markdown_it/__init__.py,sha256=9v3vCD7XQJujcZLU2F14T8O88JJO93rZaUoKu7cocH8,113 +markdown_it/__pycache__/__init__.cpython-312.pyc,, +markdown_it/__pycache__/_compat.cpython-312.pyc,, +markdown_it/__pycache__/_punycode.cpython-312.pyc,, +markdown_it/__pycache__/main.cpython-312.pyc,, +markdown_it/__pycache__/parser_block.cpython-312.pyc,, +markdown_it/__pycache__/parser_core.cpython-312.pyc,, +markdown_it/__pycache__/parser_inline.cpython-312.pyc,, +markdown_it/__pycache__/renderer.cpython-312.pyc,, +markdown_it/__pycache__/ruler.cpython-312.pyc,, +markdown_it/__pycache__/token.cpython-312.pyc,, +markdown_it/__pycache__/tree.cpython-312.pyc,, +markdown_it/__pycache__/utils.cpython-312.pyc,, +markdown_it/_compat.py,sha256=mfhalPobHpl8uYt2V6SCOZq3HqaGlWP8MjICwDvS_xE,246 +markdown_it/_punycode.py,sha256=Y_m-fzc5Ey_Kw09MPNN5TUMnPXm2cACUZE_qwUkfFrM,2364 +markdown_it/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +markdown_it/cli/__pycache__/__init__.cpython-312.pyc,, +markdown_it/cli/__pycache__/parse.cpython-312.pyc,, +markdown_it/cli/parse.py,sha256=ZiTSx6t7nLk7rGAtIi0a02EB9sDGJn7YLjKKtufdwNA,2901 +markdown_it/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +markdown_it/common/__pycache__/__init__.cpython-312.pyc,, +markdown_it/common/__pycache__/entities.cpython-312.pyc,, +markdown_it/common/__pycache__/html_blocks.cpython-312.pyc,, +markdown_it/common/__pycache__/html_re.cpython-312.pyc,, +markdown_it/common/__pycache__/normalize_url.cpython-312.pyc,, +markdown_it/common/__pycache__/utils.cpython-312.pyc,, +markdown_it/common/entities.py,sha256=6ulEjBAWYH5lVobgpn5lChPYhPKkdPyVHpNT7O1_x90,156 +markdown_it/common/html_blocks.py,sha256=1cMBp6jIdXqCHvEs2mpJqVGqTuFi6ExL4VO754yksgU,932 +markdown_it/common/html_re.py,sha256=0q5QFkSnX_l7Ob37MDSj2UYT0onCPz_07hUod2K-a6A,929 +markdown_it/common/normalize_url.py,sha256=avOXnLd9xw5jU1q5PLftjAM9pvGx8l9QDEkmZSyrMgg,2568 +markdown_it/common/utils.py,sha256=l2ypUup7jVBwGZJb8M2lxllmTWq8wN5TMV40Mndqu1A,10728 +markdown_it/helpers/__init__.py,sha256=9W7GycpZcq2up1CdVcUpdN77i9Vl4N0CT3y3qMkTjY4,253 +markdown_it/helpers/__pycache__/__init__.cpython-312.pyc,, +markdown_it/helpers/__pycache__/parse_link_destination.cpython-312.pyc,, +markdown_it/helpers/__pycache__/parse_link_label.cpython-312.pyc,, +markdown_it/helpers/__pycache__/parse_link_title.cpython-312.pyc,, +markdown_it/helpers/parse_link_destination.py,sha256=whJoEo42RmgiVpyc2TmTb73nPK3L-DZuZqfE2f8B20Q,1977 +markdown_it/helpers/parse_link_label.py,sha256=HXAnGlAL-2Op6I-lfeuzBIJBjESCRZws6xKKS3lKFSg,1036 +markdown_it/helpers/parse_link_title.py,sha256=5h5YctAUPmaeBqAlCDzzB220-i64HxYyJ27ui-xMBn0,1425 +markdown_it/main.py,sha256=7BYAkBbDmgbdVGNrpAaWZ_-u2-DoYsOCtXWg5uv3Gvg,12772 +markdown_it/parser_block.py,sha256=1bvZMDIdfBYrRNHpZPzmX6W4GXXaFUDqq2iaxDWP-BM,3911 +markdown_it/parser_core.py,sha256=asPHnvL0sk2oqWC69VM8OAqKs-Dk--GRHhGwZonLm6s,1010 +markdown_it/parser_inline.py,sha256=0ZAiRx2GkQ35va1QRxDeDZvpa44wZBNnVFsGzCyj_Po,4997 +markdown_it/port.yaml,sha256=F6WvtDFxjuZ5o0NtmJO0P8SkG6OfONCj_ggKgx4iYWU,2446 +markdown_it/presets/__init__.py,sha256=tLc9od5iXBEkKR6wbXOVPC5S5vkGYK-67tQslhWu7LY,970 +markdown_it/presets/__pycache__/__init__.cpython-312.pyc,, +markdown_it/presets/__pycache__/commonmark.cpython-312.pyc,, +markdown_it/presets/__pycache__/default.cpython-312.pyc,, +markdown_it/presets/__pycache__/zero.cpython-312.pyc,, +markdown_it/presets/commonmark.py,sha256=pqVnOnMmCmiZWHvNnXx4E1FS8VV07jcqUW1EsHuv9rE,2868 +markdown_it/presets/default.py,sha256=TgqnjjHX6SWcElk5yjW1hoP8t2-ESZ0QyrmHprmIL18,1810 +markdown_it/presets/zero.py,sha256=2vETQRRW1v9Ug3TsdRhM9r6wgZRuTcvojwcqDcsZfkI,2112 +markdown_it/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26 +markdown_it/renderer.py,sha256=jZ62oK-y-qaz8o8TDxCUMvS5OavraJ2-1uaWVqrUCv0,9970 +markdown_it/ruler.py,sha256=J18Pru7u77kqJfnMC5oiFWgnw_58vkbfk5hWQBgED7s,9199 +markdown_it/rules_block/__init__.py,sha256=8su1tOxDw_IR9JSdgqfkGZSNdYpZZCBC9MMmFODdbmE,553 +markdown_it/rules_block/__pycache__/__init__.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/blockquote.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/code.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/fence.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/heading.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/hr.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/html_block.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/lheading.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/list.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/paragraph.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/reference.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/state_block.cpython-312.pyc,, +markdown_it/rules_block/__pycache__/table.cpython-312.pyc,, +markdown_it/rules_block/blockquote.py,sha256=7uymS36dcrned3DsIaRcqcbFU1NlymhvsZpEXTD3_n8,8887 +markdown_it/rules_block/code.py,sha256=ASAnisg4hS2RhnP_7_1_pjx4NbFSYmrs6lHDgtHPXIo,859 +markdown_it/rules_block/fence.py,sha256=BJgU-PqZ4vAlCqGcrc8UtdLpJJyMeRWN-G-Op-zxrMc,2537 +markdown_it/rules_block/heading.py,sha256=e9NnvXLbY1bvowq_Pd4S-g6LbVg3iCx26qzwv3jLUyE,1746 +markdown_it/rules_block/hr.py,sha256=fPJ-tubFKjxJxhKPiTAxVP-_LHYbAq32iZ52J5sFxOU,1226 +markdown_it/rules_block/html_block.py,sha256=wA8pb34LtZr1BkIATgGKQBIGX5jQNOkwZl9UGEqvb5M,2721 +markdown_it/rules_block/lheading.py,sha256=fWoEuUo7S2svr5UMKmyQMkh0hheYAHg2gMM266Mogs4,2625 +markdown_it/rules_block/list.py,sha256=gIodkAJFyOIyKCZCj5lAlL7jIj5kAzrDb-K-2MFNplY,9668 +markdown_it/rules_block/paragraph.py,sha256=pQqTn8yYDI6_mWX-_m6PXY4wvDQB1nZ4dVUp3gKu1GA,1818 +markdown_it/rules_block/reference.py,sha256=qzR-KJ_60W8ZzuwYGLlO1bgHHVQP4qlYG4yFpOpNlsA,6168 +markdown_it/rules_block/state_block.py,sha256=HowsQyy5hGUibH4HRZWKfLIlXeDUnuWL7kpF0-rSwoM,8422 +markdown_it/rules_block/table.py,sha256=Zjkc0378QtfQzrhrNWC2kVYsGnOLaZyD3dXG1ugfX-s,6987 +markdown_it/rules_core/__init__.py,sha256=JZNOpLZ4i1vR56StidUa-A_As1XtbDwQR0iEErOXyOI,394 +markdown_it/rules_core/__pycache__/__init__.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/block.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/inline.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/linkify.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/normalize.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/replacements.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/smartquotes.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/state_core.cpython-312.pyc,, +markdown_it/rules_core/__pycache__/text_join.cpython-312.pyc,, +markdown_it/rules_core/block.py,sha256=0_JY1CUy-H2OooFtIEZAACtuoGUMohgxo4Z6A_UinSg,372 +markdown_it/rules_core/inline.py,sha256=9oWmeBhJHE7x47oJcN9yp6UsAZtrEY_A-VmfoMvKld4,325 +markdown_it/rules_core/linkify.py,sha256=mjQqpk_lHLh2Nxw4UFaLxa47Fgi-OHnmDamlgXnhmv0,5141 +markdown_it/rules_core/normalize.py,sha256=qVkBO4elitPzyP_sQENho-ycUl8s4eNZ1zZrsR2AAgk,402 +markdown_it/rules_core/replacements.py,sha256=NHL9MOuEnPuMFPLDtTYDK9yj7F2FSleMr6bPro-ciaQ,3470 +markdown_it/rules_core/smartquotes.py,sha256=CtawEcTHYgzIWZwxIGs8e8oSKhm0B7th2305I3FNEc0,7443 +markdown_it/rules_core/state_core.py,sha256=HqWZCUr5fW7xG6jeQZDdO0hE9hxxyl3_-bawgOy57HY,570 +markdown_it/rules_core/text_join.py,sha256=JVuq_27LoI0IjJDmCXOuRiTs1rmSFhFUUjh6MdF_YCk,1172 +markdown_it/rules_inline/__init__.py,sha256=Zvl8P8V830vDhcQKEleLKZ_paC-ypTn7eWpmFa9yySQ,696 +markdown_it/rules_inline/__pycache__/__init__.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/autolink.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/backticks.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/balance_pairs.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/emphasis.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/entity.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/escape.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/fragments_join.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/html_inline.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/image.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/link.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/linkify.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/newline.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/state_inline.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/strikethrough.cpython-312.pyc,, +markdown_it/rules_inline/__pycache__/text.cpython-312.pyc,, +markdown_it/rules_inline/autolink.py,sha256=l4EY7OLzuda350cT6Du_dggEwcb96TvD7YPXf2H6P1M,2079 +markdown_it/rules_inline/backticks.py,sha256=J7bezjjNxiXlKqvHc0fJkHZwH7-2nBsXVjcKydk8E4M,2037 +markdown_it/rules_inline/balance_pairs.py,sha256=vifasmne02sNaBBwuZsA4yI02vmv1gvVN4qR-b9m62E,4851 +markdown_it/rules_inline/emphasis.py,sha256=7aDLZx0Jlekuvbu3uEUTDhJp00Z0Pj6g4C3-VLhI8Co,3123 +markdown_it/rules_inline/entity.py,sha256=CE8AIGMi5isEa24RNseo0wRmTTaj5YLbgTFdDmBesAU,1651 +markdown_it/rules_inline/escape.py,sha256=5DEa7O6ByUfXdXZudcF7JZwLxXG1njAuXIOUsNDPPqU,1658 +markdown_it/rules_inline/fragments_join.py,sha256=_3JbwWYJz74gRHeZk6T8edVJT2IVSsi7FfmJJlieQlA,1493 +markdown_it/rules_inline/html_inline.py,sha256=SBg6HR0HRqCdrkkec0dfOYuQdAqyfeLRFLeQggtgjvg,1130 +markdown_it/rules_inline/image.py,sha256=AMO7kls5c-C4A_S2rBiIlKD8BQ8vIgyWUX7vCpXy_Qs,4135 +markdown_it/rules_inline/link.py,sha256=wRdTMxjNYFiV6uouZMML3fIPvyFrPtMHWzJNBQcQLV0,4318 +markdown_it/rules_inline/linkify.py,sha256=gmHw59SsMQLImv6v1RkDY9lcQAmTN-UZ4GwRFiR8jlg,1704 +markdown_it/rules_inline/newline.py,sha256=LEIhBB_3PPLeCAgaC2naheMjW5N6b9UaAB6sh47Ckz8,1296 +markdown_it/rules_inline/state_inline.py,sha256=rXmMX0P0pCf-v-013YB24MBQxMn2dJhoSZQMNYAZ8HQ,5101 +markdown_it/rules_inline/strikethrough.py,sha256=pwcPlyhkh5pqFVxRCSrdW5dNCIOtU4eDit7TVDTPIVA,3214 +markdown_it/rules_inline/text.py,sha256=GwmMVZziAmhj48l9VaXAXwzzUKDkhaA14thv-TCaS2M,901 +markdown_it/token.py,sha256=NEvuoYAeDh8_6zT6fukzdoncusVOjyUKw2zjsNgZmp4,6439 +markdown_it/tree.py,sha256=YxSqq3qSuhHHm1nQpPUhyDA4VIWHu_G_92bKdUcXXGM,11421 +markdown_it/utils.py,sha256=zPoQ8lhvxtJfg6iNSim0LcnAL0Y4XnV3G4DIIKmL8OU,5365 +markdown_it_py-3.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +markdown_it_py-3.0.0.dist-info/LICENSE,sha256=SiJg1uLND1oVGh6G2_59PtVSseK-q_mUHBulxJy85IQ,1078 +markdown_it_py-3.0.0.dist-info/LICENSE.markdown-it,sha256=eSxIxahJoV_fnjfovPnm0d0TsytGxkKnSKCkapkZ1HM,1073 +markdown_it_py-3.0.0.dist-info/METADATA,sha256=0-kME4KQNSCGPzfSEFgQc8MhUd5cmG-LO007BFk3_fw,6940 +markdown_it_py-3.0.0.dist-info/RECORD,, +markdown_it_py-3.0.0.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81 +markdown_it_py-3.0.0.dist-info/entry_points.txt,sha256=T81l7fHQ3pllpQ4wUtQK6a8g_p6wxQbnjKVHCk2WMG4,58 diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/WHEEL b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/WHEEL new file mode 100644 index 0000000..668ba4d --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.7.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/entry_points.txt b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000..7d829cd --- /dev/null +++ b/.venv/Lib/site-packages/markdown_it_py-3.0.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +markdown-it=markdown_it.cli.parse:main + diff --git a/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/INSTALLER b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/LICENSE b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/LICENSE new file mode 100644 index 0000000..2a920c5 --- /dev/null +++ b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/LICENSE @@ -0,0 +1,46 @@ +Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin. +Copyright (c) 2021 Taneli Hukkinen + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +-------------------------------------------------------------------------------- + +.parse() is based on Joyent's node.js `url` code: + +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/METADATA b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/METADATA new file mode 100644 index 0000000..b4670e8 --- /dev/null +++ b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/METADATA @@ -0,0 +1,32 @@ +Metadata-Version: 2.1 +Name: mdurl +Version: 0.1.2 +Summary: Markdown URL utilities +Keywords: markdown,commonmark +Author-email: Taneli Hukkinen +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: MacOS +Classifier: Operating System :: Microsoft :: Windows +Classifier: Operating System :: POSIX :: Linux +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Typing :: Typed +Project-URL: Homepage, https://github.com/executablebooks/mdurl + +# mdurl + +[![Build Status](https://github.com/executablebooks/mdurl/workflows/Tests/badge.svg?branch=master)](https://github.com/executablebooks/mdurl/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush) +[![codecov.io](https://codecov.io/gh/executablebooks/mdurl/branch/master/graph/badge.svg)](https://codecov.io/gh/executablebooks/mdurl) +[![PyPI version](https://img.shields.io/pypi/v/mdurl)](https://pypi.org/project/mdurl) + +This is a Python port of the JavaScript [mdurl](https://www.npmjs.com/package/mdurl) package. +See the [upstream README.md file](https://github.com/markdown-it/mdurl/blob/master/README.md) for API documentation. + diff --git a/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/RECORD b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/RECORD new file mode 100644 index 0000000..0e7b30f --- /dev/null +++ b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/RECORD @@ -0,0 +1,18 @@ +mdurl-0.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +mdurl-0.1.2.dist-info/LICENSE,sha256=fGBd9uKGZ6lgMRjpgnT2SknOPu0NJvzM6VNKNF4O-VU,2338 +mdurl-0.1.2.dist-info/METADATA,sha256=tTsp1I9Jk2cFP9o8gefOJ9JVg4Drv4PmYCOwLrfd0l0,1638 +mdurl-0.1.2.dist-info/RECORD,, +mdurl-0.1.2.dist-info/WHEEL,sha256=4TfKIB_xu-04bc2iKz6_zFt-gEFEEDU_31HGhqzOCE8,81 +mdurl/__init__.py,sha256=1vpE89NyXniIRZNC_4f6BPm3Ub4bPntjfyyhLRR7opU,547 +mdurl/__pycache__/__init__.cpython-312.pyc,, +mdurl/__pycache__/_decode.cpython-312.pyc,, +mdurl/__pycache__/_encode.cpython-312.pyc,, +mdurl/__pycache__/_format.cpython-312.pyc,, +mdurl/__pycache__/_parse.cpython-312.pyc,, +mdurl/__pycache__/_url.cpython-312.pyc,, +mdurl/_decode.py,sha256=3Q_gDQqU__TvDbu7x-b9LjbVl4QWy5g_qFwljcuvN_Y,3004 +mdurl/_encode.py,sha256=goJLUFt1h4rVZNqqm9t15Nw2W-bFXYQEy3aR01ImWvs,2602 +mdurl/_format.py,sha256=xZct0mdePXA0H3kAqxjGtlB5O86G35DAYMGkA44CmB4,626 +mdurl/_parse.py,sha256=ezZSkM2_4NQ2Zx047sEdcJG7NYQRFHiZK7Y8INHFzwY,11374 +mdurl/_url.py,sha256=5kQnRQN2A_G4svLnRzZcG0bfoD9AbBrYDXousDHZ3z0,284 +mdurl/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26 diff --git a/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/WHEEL b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/WHEEL new file mode 100644 index 0000000..668ba4d --- /dev/null +++ b/.venv/Lib/site-packages/mdurl-0.1.2.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.7.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/mdurl/__init__.py b/.venv/Lib/site-packages/mdurl/__init__.py new file mode 100644 index 0000000..cdbb640 --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/__init__.py @@ -0,0 +1,18 @@ +__all__ = ( + "decode", + "DECODE_DEFAULT_CHARS", + "DECODE_COMPONENT_CHARS", + "encode", + "ENCODE_DEFAULT_CHARS", + "ENCODE_COMPONENT_CHARS", + "format", + "parse", + "URL", +) +__version__ = "0.1.2" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT + +from mdurl._decode import DECODE_COMPONENT_CHARS, DECODE_DEFAULT_CHARS, decode +from mdurl._encode import ENCODE_COMPONENT_CHARS, ENCODE_DEFAULT_CHARS, encode +from mdurl._format import format +from mdurl._parse import url_parse as parse +from mdurl._url import URL diff --git a/.venv/Lib/site-packages/mdurl/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/mdurl/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f5b96d426d16c8f269fb9e43da2c2fbb44c243b5 GIT binary patch literal 664 zcmZut&ubGw6rSD9{>mn{f=2MP;Kd-WKaNs_kloNq+=Rw}3w+Ef36 zUi};VTRinTP(64MZ-L%CIXg*vs6LqQz4yI&^Sw9U+U+J#_U3%=^CJ_0pLKF=D%W=P zUb!zI2N2{2G;%YysL3p7u?B1~8`=g?T!T8yg)Z};$9(8(&ZbQkz(B_iZLv1Iqhpuu zuwA%ofD^ClcYW#PWLD-x-iwp|C{A#k40_YyJKW#z9ZqCt%l1ca$D=e!uX%?oHeE^j zzpgF&PuItiv#gT#GUI|sYkD|5wVy{XqL;txZMzn4D95cD>K{;qTgOffc1;-E(@y%w zoMQcq;_81)yLY9FaYiY|GQfC6xG2hnO4=+}mm|Dc^p?a;b+gbdy_@Q0a4jxd+xN6O zZ`HH;3S@K3D=|IMS8%0h@Tcg%LQ|o}L6eN3n232*F43gONjT=^5t&s24Kh*n#s}d_ zgaew1Ioi)=bHc;8JStJNB8wFo79Wr(D)MxxO4%nOkk)&Kaj_^WjHBg=^!8YpA5-$0 vKTyhsI^wZ{wPhH_+H3~qnY-?Qoz7YC3#1ny{h{#^gqPsSckqzkSC{_+T#~av literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/mdurl/__pycache__/_decode.cpython-312.pyc b/.venv/Lib/site-packages/mdurl/__pycache__/_decode.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df544ac406a1e5cd5684deda933f6cc8bfc33322 GIT binary patch literal 3839 zcmc&1TTENYb;j3^>-Phb070xFyu1Ozl5N_gG%3MAXcH13bh|8(YkV(YVr+KqbsqFu z@<-H~4N6QCDUMooowgsWvLE?urENE@s%EAB*dcAacTt7Z?T5dLntZHMY11>;zJ@q$ zwE61Do;h>QxpSU#X6DaUs|i8-&eh(zkIV@Dolexo6aoDB2LRke6Np0`4xHNfWQ1!JLINUe-;T zIV)!ZoaGYZwH2s1FP6=LNF*u-#85OMz?2>5-;ME+AV0EX{^tIphriwWt$ocMdu6ob z=0ZX79YG`=o^VJ|ptEOX3&#he9PbYXf^&Qj(?v^74UNcQ! zR11`GG>hU`!aMQQ4zc7Hun6BNt?xr;8xV?XM4h^%q)};cM#A$36~8@7jLL!0ibuO+ zUD2p=Nl4{UN09UlMG{1-*d!!rsJ<#kT+3-VMzogcT9v{tcW=UY%^xpky49HNiRA5S;VV@CnqB9@?JH^&g&^ z5O^X?jRzK{e7tZ@j4n=%hdADInndUMpeRfY1_ZJ1^swi=;28`DgmY8J1Hp4V@%W(UCJWY}ogthjRAjEZe-fyEZY9uW!73BDFiGt^M5UN*%a5nZz4bN6LBSdr3{6 zwO+FJXWz5Y^%}QWWN{`=JO&L>kj6x9 z<$V7cU~VF@yceW$-a^Kfvw2>tez-k~bPc6Rnh)`v(&}+$J45G{`k`_aM@}O#u)A0l zJ8w~;?eRnAPDvi*m3G97Ni`6c?CmY@1UhHBI}e@xVNcw<4+?;8CLEX*yapv0vT-IB z35wBZSda~i0V0M1VcAXi#ju|e{1-wZBoN*DvW7q^3bAR~G(0qNYHXmtZ+yV3mGw|C zLXlbG262i^*;xKupeoU%BXmQ_`eJI3R+u!xUpNF^0&Q68({HU?S`q^rj@n0##+;+^ zVbj51^A8=q#PEjMdhOuy!K|w}6S}+WBl2#E-gs&jgp66nUU=h}gHRG|T9Q6d?xkY_B(Grb_sAQ?DTSxK*~ z)FGA&qokJ%GuuUzH6qZ6oiCTdk~?5fJyNOX4vl{d8e0@O21QO3Xo@x^jc32Q#uc2_ zl5MsZY%^Ba_BF})oUNVD+bS7n$_GIFRjf4?qq4)=FTq-eVy#87_A1a6{YuvUsKSPq z#HWJuCDvAOI!k_Wz2Fy9gJb2N<%EGZ(*m8}`^r?*(*`c^h586`ZWXX;(Q{K7A=)RhjSm zDxbG{gwVr}&|+Jl1))GobiqM!w4@d`X?Kryv|JTviH_0kpCA7geuXWHq}!@M_fCv< zMG7T;LGjeG0dcq5_ut;`M3=Yeh={MltBO3$ZuwPjYrU&5vra-SV zwDOjkQhu2*`tw$MVsMi+Ci*s5bF%*mo9N4%%*nu& z7JB+trAE`v)rs_I#(8TZ>)e|eTer3+HJfH@O8efSyv3E`)5lgrIm>Iw!Mw$qaxM=h z`|=j|rp1Ix_uPk`utLe0+Sv&KA@hP zwVrin*YghDp*-Av&ivl^3HRXWSlNy>l5Of)uRri=rhMwC*<@|0_8eQ6)aO}aa&%dr z#9IPJW=k@#(z10PBa16>@{1>LVN~<_zYs3QF`RS1etmF@f$6`Wcq%DBQ7KLTgYr~3 z2zmSmW7UuW{Sj3S)uTUER}FQe`v%)kEpxvH)4tv|)XCiMz_jnS9mmWk2t)7HDmNC` zS0Y@l2`|P-VAcC2aqxlc!IO42+cU#ixSZ@89vv13`6kHG0uf_WK7&xh)m1VQlY0l#7M=Bjme4 zrxj5+0v&__6`%FmYa6d^Y+M3_BX)ubhJ*`;iY^J|;=?$h2PDMM>U>7lvb%s`{U^I? zE$Q+_$!$Dpi$m$hFp%_K-@Y@{LpOL)#Bc->khr zPU+Y?^P72Z-n=*S-kbS@-Cl>FeE*|?`7S_z#~r;GtAKd%V*roQ6ygv^2q;NJ2?Aq- zU`UctQp2QROq!ymBo(ES=BQa4GYXcZHCjg?-o#VOAR}tyOi`MnqV@!eIyf`$iJ!7<hm7*|f|rdoI8E&ZR3I-|KEacRt?Z zyW4fPGjL|vdWe@jT!NK9kYw?kS4c=2nx0l^SSii%ah74{d6vK`)rtjL5+UNn0*pRJ z3X*jST0)}rsHdQ2phVCdS|JqT_&DAX8DvxoM|@V3A41a~AhcqTO*&06=(H75A!SM* zhn3t4v0&BvN3BBYGYGWS`FbACz>%^|pL4VZXXH=|TCnSsqxQ2J#AnQzFc(J0R+=^* zvq*O8GnGRgofm9u#5O8OG2s1yopBv;SI2Z-yiaRQM&OB{05!g!gT6}mRpP?F0pR|B zU%q@9u!?vWRFlZ0=6IE4=S8(C7#SKFiH{CXP7dFU#Dn9ZcxdG6$YeyNm`sLGaViO( zqMEYM5mi#)Q!1GjxqwkM^S43 zwd`!)vb67>XwD5+T7CCM3n$9P<~_T+(DzX^Pwd$13$E24CH1+rv}T-gJ06`95|7q z=^Hn4G(74neE8FWKiR!`qT=f;xt_G-O>1o7?7Ht^*J}EirR{)34&MQVXjg9Z1!#>X zAu#Dhp3lU2iDfc8$Kr#;1&4qcJ}tCp7<~+>XoZvyLr*yjlNIAp@EkeViitC!B6SbPoa?=vs1v){OaD zPzdP(q01B-6%unE@hn3aLC|8^7-0%kMQagQ+oEadfLTVxjI}%D*STha%eoi?4QBw= zEw%ufJ{%hZWYfm3X_7%gP5&#eT3*%t75goUg`+jeU4W{R{g7S`(+Rdj3(iB^H4R}6 z-QI6&d(67uDI{nAHht}nuap1(rPXX9*7g(0lkzzL z?}0Pn#5_&IzQ2-sm(b6M$8fc+IgIEI`Zf6>5g^6`goqD3U{DP`7gU0k@H$?v*b0qm z9hl=&{Oyc5xZGR|&H*9KGJ-VNb4a=joYD!X{)zsTLtE}(x%*0yDfE6~eKZL0-&+3o zk=sM;V{hKa%8EGsCQt>cmtW!PFSxq{ZeaBfhyCxuKNK)&F)u>CL?RZil8hjzp4!!v z6%%nboy??Dd`b>jRSNE~L~2fK!tAFoJ0AO|=XeR9 zI^?!$saj1{mk=)i={$T=1{BXBh-627F1$y#uK#eG_UDH8EVg`j)s_oZELN!MYM1wK4Il_kpAA4wm{id>hPD|E6z~`N9wT zwCxT)cLpo3TY~Iq~`XJFTaR zRPk1+_eu7NeY>@%V68N?7O7_q9i@w#)U)ovil^my+gls`o4%(PHCIEHb@_?=RGv7v zjBIqCS@j7aypc6;sQ0{VjywEz<#u*bS^=FRrxH*O2A{ z#+h_l5Z}_t0k>KgkI!a73LlS)*b`MJn-&DPx$rxyhnZnTeA`te;&+IMA01kRs5IPB zLSm*T!-#MP;)jsfg)28ys%Ln7=z3^49vTh@r$#5^L)U^gBWh!9bm;onjqBsXda z_OA0erXk3R*JB8suudxPA|VpeLpDCc61(l4JL!WQ0k|%#1EI?w6{P_05nTlT080&# zfjZX1!B!qym-yc4!S45a4Tuxas~k{ApI=9S<)1G2ME&P~Hby{}-m?s@1+e1(XDy;+ zWS*h*(8L78w;7&f_$kBBk}{Jk#BrUxW3dReG-?`@iCWb)nQS`LwY9Rr#EL^)AZo7Z z>k>6Ik~f)X0zVmILX}udA_lEmF6A$QqWm^flj;&R2vrxgvN~&Wu5rBrCT-QAYFUSD6S)qP07bwW7}i^_ZKve)0o5lV3Q2VYY4*6wu3fi>W z!=88<%IUe#cz6umq4}gpF2YH|u<_BmRbn%Nx+EE4(Ohn&3V@Nz5&l6l$z7`y>{Y_Q zFc$R(IG%$k`riKBJ|Qy5!wqnTJXLn|s%6|FS3u>z2g>oE0>=0d4Sz?Drb5V`+L{d0}n z8#C=V*YF(pKxNFlBaTtUv5=-QD`}>zX*9z|S}2>;Df! zVn-Z@isJ+vE#)H1;aBlQqwdJP3691#|C~?EDxOD!^V}OkKJL7~f_f)X>rxsv8Yy zL~}ek8)YWw*fg8Al=__^vq(&`?6jyuH6v=TLtlR*H9bkuB5^&IpwiMvXId{IbfyWw z=u8`Al+Lsc;dD*_b80D?CjPb#Ko2nr8^cL#Ohf8O{1akKOX^7tv;=7&wb1JB5Fj%1 z;0znRmY_fj6GgL?=pkBK48z~D5-k$ru!uB(DiVh;6(!KMg zf9K1feBHr9nxQkmpK+Q_v8jnvLNqXmC^JbhA`zWoCq-g9MYE!DGR3gT=oAIggi%q? zP*Hkf5~fAjNdyNi6AYEO&LDRE|9hjmbNmuR(aiWrbZWeZVs5gj>G6>mN%_yysW>&k zGUI2W3>!W_;GbpuXJE;j6!+qa`&Ng2OX9P8V0zh33iSd9j6Y4a2Z1 zEe?;XN>Xq^v0BB0C@o3cY=BepBUV*n99G_1IGuu@(Q|sbi_^y~TXBFopT#Wb_UK6cmC;q)Nw6m03M|1g|Il? zCONB-g2cR-q=hQZz<5~Xe5A5%Y|?{7i^q*_1kEBZwWW|MWzauCS8@j0#CjDZ&VZ&c zR!#@5L0XwK0*`7O+=`jgFmE}6v2li+hW<~s_FXzK`Ymb7nAm^ z$|zj{Yt)x$D?QSzQne;MJK>N(nIupgeqKBu87pU%d7xb&L5#D4?rfY6pb}nDmo|{7 zOI>Rx`7|mR3NK3g1M*Sl{XfXZQqtF^vuc8UTWro!Q}%~Ln25J*9mlZSIHQ4F4FwqW6l{;Vt=-!c`nPeqdZ#tw z2mf?kQspdT=j=J03GcA#cAinqzcP+ZvQ#s!OgU)*OE+`n$VPKG?c^M?-ZB+j1z4{c zq-#T`;enGqr0^EEE4@<7RVe#oz5`F@+_aiHl5xRmZqCiQ&}wuedsvyzRdDXjr-^h( z`qgtzvRqo0hxCT9d=U7D^F$+q0rjV^1o)NcuEvIX!mpQ`^ob2@+22 zJ11>hZ(NG}nO)qjqVKcAS>J_x9nAMD>r0+smlVskr&O|1FX!Dv$y=mUiq*)odSyzq z0oK}-6>N$?T4c|(Z~OhhIm6;sg||}6$Py}L8ITu*oI@gZM$Y(As`MJp4hHv<*4E2c zPqkiYIwd!0O>67u>pwyf@l!Oy5%EqDzbxWcM7-toPb9!?>Glu`h&qOa#9!1Vs3i2K z6ERkFjtmT*Ki3;MA0F*T)oAaDg_xV(ROWb|C`$Vfz)Mx)RwI!4ZgNBVnvRIsR{qsbeT zJR#CM)H5*D7wPT~UmQUsG;|v*=0k+LlH!|h+&pe+z86MX^6d;Xrz*)%zzuA z4TT5M?kR|YT$hqDjIt1&4 zs%g0RW1<%FY|&Y~3q(i??v|9qjcAc%6Ok?q^3DmGVp!3_#HOYb6y)Y0B%L%YTBIf- z%U!xeL=Yo*Ow>+N6QUu?Mwr-*q$~mgZC13!re}{xD@pea69R%PSVqJXa2tW1Xh>2Y zN*(;Bh{r|CY%~!g(VYO0jKHYOr}kQmm9`{mZcQ=Ouqpq}g+@^nxJLJiv}4m%LV}>n z8M6TQE4W8^s=jvJ!-zRtpQZ1mKjpH-zuSYqU>4iH>Uh?XA9;SVP~W)} zeNo@_t+#p2+qU9u%l8z#9oe%l?Ows(wB|p!;y;)V6#VTu;tQMLtX*@~tvKuEFRVK2 zg<$hqux%ySmJb(#M{+%1oE0jobCy?*imYzkvv19_f5o$ZakSt$l(oFHcm$Vk&9!&M zwYT7^&-Myl-_xc?O^=(iXN8(Tw&%g1;H-S2<$E8SdF!%sZ?@-+6|?#l_Wtq^Vs-g& z|L^Knn}!9C_hD)-HBS~iP1(MecF%%twei?e?~BIMus9#)Pv>su2*I}p*tLFZ_s_cv z_WGAr=g)Mj`;O#i3j0oM?8BES~|-xfoddUO?% z2A_OfsBZbayH(}y7iEjLKqDa2KhNHQ4Revb_3B!lecX{VzOq;Hf&1J%G5@OKEXi}0K+X9W54CcY}ymF+=YBX2@o;Ko+|+3>w#zGu}MfNks!JRN*A_@btD z@gmZi3R$aZU#V%&j}&S;{(xzAmo1UsOnp7Ic5-y(ub)#wHCWoCuLlpW1&^-;k1vfDf~WcJm%gBMbPgdAxBWxM zuR4}4{QCH+|CHcw_|m>$&*SevU;65W`o=GBFWk->3-ujKJuCI6<_Tec>sS5H`tz3y z`@?+ClR-EnAQ`@V?o2Mc(S=o3@qsU>?@!~H!~BM0&?oqUJNNGJ&QCwi5`x8^J9NMERaFf?%3tCwpwa=PeI4)0 z9RouE-T(OBk8{kYSF;+yV#`(Be^2n%@-)xzA;3M0aJ76zt|Qy?(qae2BAZyZRP$$F zSQ-{bzq<1GSANs}+Y|qELa3=lL$B=4tc7j`S2ckGrczKMEj?HK96Ap%-B?oIE`UUupMN7ca$(T1ZKl4`BQ*w(btBxf@p84U4XVyCrLWX>kkA-D}Q0 zE6zOyvK3~E2BmaU_W_{9zoC4n{d0IttKONlAVpfNwo*{Uz)YB9@ zLnlRID3zo_diqC*aV^Ap`hCUFfZA zQloQyKdLk80x~|rIupVrKGmm8kQ)Z~R@u;k@CAm3U{c{QR-^QlJfGH}S0Ywby=qcm zc5yX3Rc3)g&}z(2CNR(gR%e z1ww%V$C@~L;oef77rBK@7#|8*MRSaSq>POwCny>TLsEjQq&oDu7gZ=hlnowbf>KT+ zp9GY`!b>_b9@%d283vs`$aCa`#spcM{8&nJ2p4q1P|yMUHk9Y~e8H?5s!<+eUN=^J zYP}m42;JZG{Z(JKd%3)BmDsy(DHDvQ&&>DCx$wh*xdHyx)7eL}^S8d7U6@_G^;P;= zdgrqSsodnwv>+5|7(e$KC0IF0;}Y{6*T zp#Wy z!xwwI!y~=)X@s9bRTrA1@98}^FgPOWFAcpvFw!ep!k0#eBfTTt;q$%pIfOQVs!OOE zM%4vWNj#oGy*^YS%a_DR-$p&;X=N!JkIN_SB>mR_Lw3(pK)s>Gas0nVaSY${9k%D+ zFw=LKcf*RgYIBDkcFuJ!*B)G|_-6OlyH}lk%a}v3@5<6BljNHU_I-D)5KSrrxoZ#O zbMfWC>4K+w8FNCAH6OmKhaq!l@yLqlpwzd!bF=qScP)^YR5UGKUMYX?ZkgcPvy7EP zmW3!+1$oU=^CR=}p5uk86U&%e@c0$VrwX1hP==7^_6vmZmB$OY(;J;ur+=%{yEQ=M zjRSM}(2&C=l)J(02^Ahe?#mr#CBWafEoe%a3#K^!Cz#RTfj1bcH%{rXlim1#V+LHd Gi2nm~B|}L7 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/mdurl/__pycache__/_url.cpython-312.pyc b/.venv/Lib/site-packages/mdurl/__pycache__/_url.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b7238b664452a4e94bcc49daf21900036120cf8f GIT binary patch literal 687 zcmYk4&x_MQ6vt)#Dh1Xdhz6&rY+9lo6q~c_cAjt`O<9q2-cI2z4#hN=(`Qpt6l+K z+yOX85sGk%GCaiCaxJZ8&d|ZAh908Gd50pxozG6yGbGb`*ZpaOE;idN&xK|>5xIiU z@3V|Y&&wj^qpG~pRWDw=fcPA7G{g}a)&{UIccNMk+{ghUOR`>lL+*yQHso#S!iIcH z)9r4e!G%NNv1WD4oOk4T&LZ zT*a9j#n8-jZ2f+h7>`nmlp3GXOhjdBxk2fxlBKK6B})IB3Zaalao*- zn%^oQ#ZI{jv#6Bm9tGJgrqYGImSREO26>O>7dtc3nKv)LeLDABGtydVWmit4JtJ)> z{7O3V%K9DsZr$GWWvNREH<*H!q11)Rghl} X#`qh$@dI7|?Rt3U!_7Yk9?Qmm$oRFP literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/mdurl/_decode.py b/.venv/Lib/site-packages/mdurl/_decode.py new file mode 100644 index 0000000..9b50a2d --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/_decode.py @@ -0,0 +1,104 @@ +from __future__ import annotations + +from collections.abc import Sequence +import functools +import re + +DECODE_DEFAULT_CHARS = ";/?:@&=+$,#" +DECODE_COMPONENT_CHARS = "" + +decode_cache: dict[str, list[str]] = {} + + +def get_decode_cache(exclude: str) -> Sequence[str]: + if exclude in decode_cache: + return decode_cache[exclude] + + cache: list[str] = [] + decode_cache[exclude] = cache + + for i in range(128): + ch = chr(i) + cache.append(ch) + + for i in range(len(exclude)): + ch_code = ord(exclude[i]) + cache[ch_code] = "%" + ("0" + hex(ch_code)[2:].upper())[-2:] + + return cache + + +# Decode percent-encoded string. +# +def decode(string: str, exclude: str = DECODE_DEFAULT_CHARS) -> str: + cache = get_decode_cache(exclude) + repl_func = functools.partial(repl_func_with_cache, cache=cache) + return re.sub(r"(%[a-f0-9]{2})+", repl_func, string, flags=re.IGNORECASE) + + +def repl_func_with_cache(match: re.Match, cache: Sequence[str]) -> str: + seq = match.group() + result = "" + + i = 0 + l = len(seq) # noqa: E741 + while i < l: + b1 = int(seq[i + 1 : i + 3], 16) + + if b1 < 0x80: + result += cache[b1] + i += 3 # emulate JS for loop statement3 + continue + + if (b1 & 0xE0) == 0xC0 and (i + 3 < l): + # 110xxxxx 10xxxxxx + b2 = int(seq[i + 4 : i + 6], 16) + + if (b2 & 0xC0) == 0x80: + all_bytes = bytes((b1, b2)) + try: + result += all_bytes.decode() + except UnicodeDecodeError: + result += "\ufffd" * 2 + + i += 3 + i += 3 # emulate JS for loop statement3 + continue + + if (b1 & 0xF0) == 0xE0 and (i + 6 < l): + # 1110xxxx 10xxxxxx 10xxxxxx + b2 = int(seq[i + 4 : i + 6], 16) + b3 = int(seq[i + 7 : i + 9], 16) + + if (b2 & 0xC0) == 0x80 and (b3 & 0xC0) == 0x80: + all_bytes = bytes((b1, b2, b3)) + try: + result += all_bytes.decode() + except UnicodeDecodeError: + result += "\ufffd" * 3 + + i += 6 + i += 3 # emulate JS for loop statement3 + continue + + if (b1 & 0xF8) == 0xF0 and (i + 9 < l): + # 111110xx 10xxxxxx 10xxxxxx 10xxxxxx + b2 = int(seq[i + 4 : i + 6], 16) + b3 = int(seq[i + 7 : i + 9], 16) + b4 = int(seq[i + 10 : i + 12], 16) + + if (b2 & 0xC0) == 0x80 and (b3 & 0xC0) == 0x80 and (b4 & 0xC0) == 0x80: + all_bytes = bytes((b1, b2, b3, b4)) + try: + result += all_bytes.decode() + except UnicodeDecodeError: + result += "\ufffd" * 4 + + i += 9 + i += 3 # emulate JS for loop statement3 + continue + + result += "\ufffd" + i += 3 # emulate JS for loop statement3 + + return result diff --git a/.venv/Lib/site-packages/mdurl/_encode.py b/.venv/Lib/site-packages/mdurl/_encode.py new file mode 100644 index 0000000..bc2e5b9 --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/_encode.py @@ -0,0 +1,85 @@ +from __future__ import annotations + +from collections.abc import Sequence +from string import ascii_letters, digits, hexdigits +from urllib.parse import quote as encode_uri_component + +ASCII_LETTERS_AND_DIGITS = ascii_letters + digits + +ENCODE_DEFAULT_CHARS = ";/?:@&=+$,-_.!~*'()#" +ENCODE_COMPONENT_CHARS = "-_.!~*'()" + +encode_cache: dict[str, list[str]] = {} + + +# Create a lookup array where anything but characters in `chars` string +# and alphanumeric chars is percent-encoded. +def get_encode_cache(exclude: str) -> Sequence[str]: + if exclude in encode_cache: + return encode_cache[exclude] + + cache: list[str] = [] + encode_cache[exclude] = cache + + for i in range(128): + ch = chr(i) + + if ch in ASCII_LETTERS_AND_DIGITS: + # always allow unencoded alphanumeric characters + cache.append(ch) + else: + cache.append("%" + ("0" + hex(i)[2:].upper())[-2:]) + + for i in range(len(exclude)): + cache[ord(exclude[i])] = exclude[i] + + return cache + + +# Encode unsafe characters with percent-encoding, skipping already +# encoded sequences. +# +# - string - string to encode +# - exclude - list of characters to ignore (in addition to a-zA-Z0-9) +# - keepEscaped - don't encode '%' in a correct escape sequence (default: true) +def encode( + string: str, exclude: str = ENCODE_DEFAULT_CHARS, *, keep_escaped: bool = True +) -> str: + result = "" + + cache = get_encode_cache(exclude) + + l = len(string) # noqa: E741 + i = 0 + while i < l: + code = ord(string[i]) + + # % + if keep_escaped and code == 0x25 and i + 2 < l: + if all(c in hexdigits for c in string[i + 1 : i + 3]): + result += string[i : i + 3] + i += 2 + i += 1 # JS for loop statement3 + continue + + if code < 128: + result += cache[code] + i += 1 # JS for loop statement3 + continue + + if code >= 0xD800 and code <= 0xDFFF: + if code >= 0xD800 and code <= 0xDBFF and i + 1 < l: + next_code = ord(string[i + 1]) + if next_code >= 0xDC00 and next_code <= 0xDFFF: + result += encode_uri_component(string[i] + string[i + 1]) + i += 1 + i += 1 # JS for loop statement3 + continue + result += "%EF%BF%BD" + i += 1 # JS for loop statement3 + continue + + result += encode_uri_component(string[i]) + i += 1 # JS for loop statement3 + + return result diff --git a/.venv/Lib/site-packages/mdurl/_format.py b/.venv/Lib/site-packages/mdurl/_format.py new file mode 100644 index 0000000..12524ca --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/_format.py @@ -0,0 +1,27 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mdurl._url import URL + + +def format(url: URL) -> str: # noqa: A001 + result = "" + + result += url.protocol or "" + result += "//" if url.slashes else "" + result += url.auth + "@" if url.auth else "" + + if url.hostname and ":" in url.hostname: + # ipv6 address + result += "[" + url.hostname + "]" + else: + result += url.hostname or "" + + result += ":" + url.port if url.port else "" + result += url.pathname or "" + result += url.search or "" + result += url.hash or "" + + return result diff --git a/.venv/Lib/site-packages/mdurl/_parse.py b/.venv/Lib/site-packages/mdurl/_parse.py new file mode 100644 index 0000000..ffeeac7 --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/_parse.py @@ -0,0 +1,304 @@ +# Copyright Joyent, Inc. and other Node contributors. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject to the +# following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +# NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +# USE OR OTHER DEALINGS IN THE SOFTWARE. + + +# Changes from joyent/node: +# +# 1. No leading slash in paths, +# e.g. in `url.parse('http://foo?bar')` pathname is ``, not `/` +# +# 2. Backslashes are not replaced with slashes, +# so `http:\\example.org\` is treated like a relative path +# +# 3. Trailing colon is treated like a part of the path, +# i.e. in `http://example.org:foo` pathname is `:foo` +# +# 4. Nothing is URL-encoded in the resulting object, +# (in joyent/node some chars in auth and paths are encoded) +# +# 5. `url.parse()` does not have `parseQueryString` argument +# +# 6. Removed extraneous result properties: `host`, `path`, `query`, etc., +# which can be constructed using other parts of the url. + +from __future__ import annotations + +from collections import defaultdict +import re + +from mdurl._url import URL + +# Reference: RFC 3986, RFC 1808, RFC 2396 + +# define these here so at least they only have to be +# compiled once on the first module load. +PROTOCOL_PATTERN = re.compile(r"^([a-z0-9.+-]+:)", flags=re.IGNORECASE) +PORT_PATTERN = re.compile(r":[0-9]*$") + +# Special case for a simple path URL +SIMPLE_PATH_PATTERN = re.compile(r"^(//?(?!/)[^?\s]*)(\?[^\s]*)?$") + +# RFC 2396: characters reserved for delimiting URLs. +# We actually just auto-escape these. +DELIMS = ("<", ">", '"', "`", " ", "\r", "\n", "\t") + +# RFC 2396: characters not allowed for various reasons. +UNWISE = ("{", "}", "|", "\\", "^", "`") + DELIMS + +# Allowed by RFCs, but cause of XSS attacks. Always escape these. +AUTO_ESCAPE = ("'",) + UNWISE +# Characters that are never ever allowed in a hostname. +# Note that any invalid chars are also handled, but these +# are the ones that are *expected* to be seen, so we fast-path +# them. +NON_HOST_CHARS = ("%", "/", "?", ";", "#") + AUTO_ESCAPE +HOST_ENDING_CHARS = ("/", "?", "#") +HOSTNAME_MAX_LEN = 255 +HOSTNAME_PART_PATTERN = re.compile(r"^[+a-z0-9A-Z_-]{0,63}$") +HOSTNAME_PART_START = re.compile(r"^([+a-z0-9A-Z_-]{0,63})(.*)$") +# protocols that can allow "unsafe" and "unwise" chars. + +# protocols that never have a hostname. +HOSTLESS_PROTOCOL = defaultdict( + bool, + { + "javascript": True, + "javascript:": True, + }, +) +# protocols that always contain a // bit. +SLASHED_PROTOCOL = defaultdict( + bool, + { + "http": True, + "https": True, + "ftp": True, + "gopher": True, + "file": True, + "http:": True, + "https:": True, + "ftp:": True, + "gopher:": True, + "file:": True, + }, +) + + +class MutableURL: + def __init__(self) -> None: + self.protocol: str | None = None + self.slashes: bool = False + self.auth: str | None = None + self.port: str | None = None + self.hostname: str | None = None + self.hash: str | None = None + self.search: str | None = None + self.pathname: str | None = None + + def parse(self, url: str, slashes_denote_host: bool) -> "MutableURL": + lower_proto = "" + slashes = False + rest = url + + # trim before proceeding. + # This is to support parse stuff like " http://foo.com \n" + rest = rest.strip() + + if not slashes_denote_host and len(url.split("#")) == 1: + # Try fast path regexp + simple_path = SIMPLE_PATH_PATTERN.match(rest) + if simple_path: + self.pathname = simple_path.group(1) + if simple_path.group(2): + self.search = simple_path.group(2) + return self + + proto = "" + proto_match = PROTOCOL_PATTERN.match(rest) + if proto_match: + proto = proto_match.group() + lower_proto = proto.lower() + self.protocol = proto + rest = rest[len(proto) :] + + # figure out if it's got a host + # user@server is *always* interpreted as a hostname, and url + # resolution will treat //foo/bar as host=foo,path=bar because that's + # how the browser resolves relative URLs. + if slashes_denote_host or proto or re.search(r"^//[^@/]+@[^@/]+", rest): + slashes = rest.startswith("//") + if slashes and not (proto and HOSTLESS_PROTOCOL[proto]): + rest = rest[2:] + self.slashes = True + + if not HOSTLESS_PROTOCOL[proto] and ( + slashes or (proto and not SLASHED_PROTOCOL[proto]) + ): + + # there's a hostname. + # the first instance of /, ?, ;, or # ends the host. + # + # If there is an @ in the hostname, then non-host chars *are* allowed + # to the left of the last @ sign, unless some host-ending character + # comes *before* the @-sign. + # URLs are obnoxious. + # + # ex: + # http://a@b@c/ => user:a@b host:c + # http://a@b?@c => user:a host:c path:/?@c + + # v0.12 TODO(isaacs): This is not quite how Chrome does things. + # Review our test case against browsers more comprehensively. + + # find the first instance of any hostEndingChars + host_end = -1 + for i in range(len(HOST_ENDING_CHARS)): + hec = rest.find(HOST_ENDING_CHARS[i]) + if hec != -1 and (host_end == -1 or hec < host_end): + host_end = hec + + # at this point, either we have an explicit point where the + # auth portion cannot go past, or the last @ char is the decider. + if host_end == -1: + # atSign can be anywhere. + at_sign = rest.rfind("@") + else: + # atSign must be in auth portion. + # http://a@b/c@d => host:b auth:a path:/c@d + at_sign = rest.rfind("@", 0, host_end + 1) + + # Now we have a portion which is definitely the auth. + # Pull that off. + if at_sign != -1: + auth = rest[:at_sign] + rest = rest[at_sign + 1 :] + self.auth = auth + + # the host is the remaining to the left of the first non-host char + host_end = -1 + for i in range(len(NON_HOST_CHARS)): + hec = rest.find(NON_HOST_CHARS[i]) + if hec != -1 and (host_end == -1 or hec < host_end): + host_end = hec + # if we still have not hit it, then the entire thing is a host. + if host_end == -1: + host_end = len(rest) + + if host_end > 0 and rest[host_end - 1] == ":": + host_end -= 1 + host = rest[:host_end] + rest = rest[host_end:] + + # pull out port. + self.parse_host(host) + + # we've indicated that there is a hostname, + # so even if it's empty, it has to be present. + self.hostname = self.hostname or "" + + # if hostname begins with [ and ends with ] + # assume that it's an IPv6 address. + ipv6_hostname = self.hostname.startswith("[") and self.hostname.endswith( + "]" + ) + + # validate a little. + if not ipv6_hostname: + hostparts = self.hostname.split(".") + l = len(hostparts) # noqa: E741 + i = 0 + while i < l: + part = hostparts[i] + if not part: + i += 1 # emulate statement3 in JS for loop + continue + if not HOSTNAME_PART_PATTERN.search(part): + newpart = "" + k = len(part) + j = 0 + while j < k: + if ord(part[j]) > 127: + # we replace non-ASCII char with a temporary placeholder + # we need this to make sure size of hostname is not + # broken by replacing non-ASCII by nothing + newpart += "x" + else: + newpart += part[j] + j += 1 # emulate statement3 in JS for loop + + # we test again with ASCII char only + if not HOSTNAME_PART_PATTERN.search(newpart): + valid_parts = hostparts[:i] + not_host = hostparts[i + 1 :] + bit = HOSTNAME_PART_START.search(part) + if bit: + valid_parts.append(bit.group(1)) + not_host.insert(0, bit.group(2)) + if not_host: + rest = ".".join(not_host) + rest + self.hostname = ".".join(valid_parts) + break + i += 1 # emulate statement3 in JS for loop + + if len(self.hostname) > HOSTNAME_MAX_LEN: + self.hostname = "" + + # strip [ and ] from the hostname + # the host field still retains them, though + if ipv6_hostname: + self.hostname = self.hostname[1:-1] + + # chop off from the tail first. + hash = rest.find("#") # noqa: A001 + if hash != -1: + # got a fragment string. + self.hash = rest[hash:] + rest = rest[:hash] + qm = rest.find("?") + if qm != -1: + self.search = rest[qm:] + rest = rest[:qm] + if rest: + self.pathname = rest + if SLASHED_PROTOCOL[lower_proto] and self.hostname and not self.pathname: + self.pathname = "" + + return self + + def parse_host(self, host: str) -> None: + port_match = PORT_PATTERN.search(host) + if port_match: + port = port_match.group() + if port != ":": + self.port = port[1:] + host = host[: -len(port)] + if host: + self.hostname = host + + +def url_parse(url: URL | str, *, slashes_denote_host: bool = False) -> URL: + if isinstance(url, URL): + return url + u = MutableURL() + u.parse(url, slashes_denote_host) + return URL( + u.protocol, u.slashes, u.auth, u.port, u.hostname, u.hash, u.search, u.pathname + ) diff --git a/.venv/Lib/site-packages/mdurl/_url.py b/.venv/Lib/site-packages/mdurl/_url.py new file mode 100644 index 0000000..f866e7a --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/_url.py @@ -0,0 +1,14 @@ +from __future__ import annotations + +from typing import NamedTuple + + +class URL(NamedTuple): + protocol: str | None + slashes: bool + auth: str | None + port: str | None + hostname: str | None + hash: str | None # noqa: A003 + search: str | None + pathname: str | None diff --git a/.venv/Lib/site-packages/mdurl/py.typed b/.venv/Lib/site-packages/mdurl/py.typed new file mode 100644 index 0000000..7632ecf --- /dev/null +++ b/.venv/Lib/site-packages/mdurl/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561 diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/INSTALLER b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/METADATA b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/METADATA new file mode 100644 index 0000000..8671c6d --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/METADATA @@ -0,0 +1,58 @@ +Metadata-Version: 2.4 +Name: Pygments +Version: 2.19.1 +Summary: Pygments is a syntax highlighting package written in Python. +Project-URL: Homepage, https://pygments.org +Project-URL: Documentation, https://pygments.org/docs +Project-URL: Source, https://github.com/pygments/pygments +Project-URL: Bug Tracker, https://github.com/pygments/pygments/issues +Project-URL: Changelog, https://github.com/pygments/pygments/blob/master/CHANGES +Author-email: Georg Brandl +Maintainer: Matthäus G. Chajdas +Maintainer-email: Georg Brandl , Jean Abou Samra +License: BSD-2-Clause +License-File: AUTHORS +License-File: LICENSE +Keywords: syntax highlighting +Classifier: Development Status :: 6 - Mature +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: End Users/Desktop +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Text Processing :: Filters +Classifier: Topic :: Utilities +Requires-Python: >=3.8 +Provides-Extra: plugins +Provides-Extra: windows-terminal +Requires-Dist: colorama>=0.4.6; extra == 'windows-terminal' +Description-Content-Type: text/x-rst + +Pygments +~~~~~~~~ + +Pygments is a syntax highlighting package written in Python. + +It is a generic syntax highlighter suitable for use in code hosting, forums, +wikis or other applications that need to prettify source code. Highlights +are: + +* a wide range of over 500 languages and other text formats is supported +* special attention is paid to details, increasing quality by a fair amount +* support for new languages and formats are added easily +* a number of output formats, presently HTML, LaTeX, RTF, SVG, all image + formats that PIL supports and ANSI sequences +* it is usable as a command-line tool and as a library + +Copyright 2006-2025 by the Pygments team, see ``AUTHORS``. +Licensed under the BSD, see ``LICENSE`` for details. diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/RECORD b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/RECORD new file mode 100644 index 0000000..9992a4a --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/RECORD @@ -0,0 +1,682 @@ +../../Scripts/pygmentize.exe,sha256=c42tTGZ1TWYnMWdLzNMAMNw8YMW-AAm0yHmriBJSBFs,108441 +pygments-2.19.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pygments-2.19.1.dist-info/METADATA,sha256=QGjhRksrfp_I-eQNvdNKViqR538H_0l-x473HqO-rxM,2512 +pygments-2.19.1.dist-info/RECORD,, +pygments-2.19.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87 +pygments-2.19.1.dist-info/entry_points.txt,sha256=uUXw-XhMKBEX4pWcCtpuTTnPhL3h7OEE2jWi51VQsa8,53 +pygments-2.19.1.dist-info/licenses/AUTHORS,sha256=BmDjGKbyFYAq3Icxq4XQxl_yfPzKP10oWX8wZHYZW9k,10824 +pygments-2.19.1.dist-info/licenses/LICENSE,sha256=qdZvHVJt8C4p3Oc0NtNOVuhjL0bCdbvf_HBWnogvnxc,1331 +pygments/__init__.py,sha256=H0XmVJ1Fe9qSEDBU1j1wZLT-Tfu7blFbDiFSfpwU63c,2959 +pygments/__main__.py,sha256=p8AJyoyCOMYGvzWHdnq0_A9qaaVqaj02nIu3xhJp1_4,348 +pygments/__pycache__/__init__.cpython-312.pyc,, +pygments/__pycache__/__main__.cpython-312.pyc,, +pygments/__pycache__/cmdline.cpython-312.pyc,, +pygments/__pycache__/console.cpython-312.pyc,, +pygments/__pycache__/filter.cpython-312.pyc,, +pygments/__pycache__/formatter.cpython-312.pyc,, +pygments/__pycache__/lexer.cpython-312.pyc,, +pygments/__pycache__/modeline.cpython-312.pyc,, +pygments/__pycache__/plugin.cpython-312.pyc,, +pygments/__pycache__/regexopt.cpython-312.pyc,, +pygments/__pycache__/scanner.cpython-312.pyc,, +pygments/__pycache__/sphinxext.cpython-312.pyc,, +pygments/__pycache__/style.cpython-312.pyc,, +pygments/__pycache__/token.cpython-312.pyc,, +pygments/__pycache__/unistring.cpython-312.pyc,, +pygments/__pycache__/util.cpython-312.pyc,, +pygments/cmdline.py,sha256=4pL9Kpn2PUEKPobgrsQgg-vCx2NjsrapKzQ6LxQR7Q0,23536 +pygments/console.py,sha256=AagDWqwea2yBWf10KC9ptBgMpMjxKp8yABAmh-NQOVk,1718 +pygments/filter.py,sha256=YLtpTnZiu07nY3oK9nfR6E9Y1FBHhP5PX8gvkJWcfag,1910 +pygments/filters/__init__.py,sha256=B00KqPCQh5E0XhzaDK74Qa1E4fDSTlD6b0Pvr1v-vEQ,40344 +pygments/filters/__pycache__/__init__.cpython-312.pyc,, +pygments/formatter.py,sha256=H_4J-moKkKfRWUOW9J0u7hhw6n1LiO-2Xu1q2B0sE5w,4366 +pygments/formatters/__init__.py,sha256=7OuvmoYLyoPzoOQV_brHG8GSKYB_wjFSkAQng6x2y9g,5349 +pygments/formatters/__pycache__/__init__.cpython-312.pyc,, +pygments/formatters/__pycache__/_mapping.cpython-312.pyc,, +pygments/formatters/__pycache__/bbcode.cpython-312.pyc,, +pygments/formatters/__pycache__/groff.cpython-312.pyc,, +pygments/formatters/__pycache__/html.cpython-312.pyc,, +pygments/formatters/__pycache__/img.cpython-312.pyc,, +pygments/formatters/__pycache__/irc.cpython-312.pyc,, +pygments/formatters/__pycache__/latex.cpython-312.pyc,, +pygments/formatters/__pycache__/other.cpython-312.pyc,, +pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc,, +pygments/formatters/__pycache__/rtf.cpython-312.pyc,, +pygments/formatters/__pycache__/svg.cpython-312.pyc,, +pygments/formatters/__pycache__/terminal.cpython-312.pyc,, +pygments/formatters/__pycache__/terminal256.cpython-312.pyc,, +pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176 +pygments/formatters/bbcode.py,sha256=s0Ka35OKuIchoSgEAGf6rj0rl2a9ym9L31JVNSRbZFQ,3296 +pygments/formatters/groff.py,sha256=pLcIHj4jJS_lRAVFnyJODKDu1Xlyl9_AEIdOtbl3DT0,5082 +pygments/formatters/html.py,sha256=FrHJ69FUliEyPY0zTfab0C1gPf7LXsKgeRlhwkniqIs,35953 +pygments/formatters/img.py,sha256=aRpFo8mBmWTL3sBUjRCWkeS3rc6FZrSFC4EksDrl53g,23301 +pygments/formatters/irc.py,sha256=R0Js0TYWySlI2yE9sW6tN4d4X-x3k9ZmudsijGPnLmU,4945 +pygments/formatters/latex.py,sha256=BRYtbLeW_YD1kwhhnFInhJIKylurnri8CF1lP069KWE,19258 +pygments/formatters/other.py,sha256=8pYW27sU_7XicLUqOEt2yWSO0h1IEUM3TIv34KODLwo,4986 +pygments/formatters/pangomarkup.py,sha256=pcFvEC7K1Me0EjGeOZth4oCnEY85bfqc77XzZASEPpY,2206 +pygments/formatters/rtf.py,sha256=kcKMCxTXu-2-hpgEftlGJRm7Ss-yA_Sy8OsHH_qzykA,11921 +pygments/formatters/svg.py,sha256=R6A2ME6JsMQWFiyn8wcKwFUOD6vsu-HLwiIztLu-77E,7138 +pygments/formatters/terminal.py,sha256=J_F_dFXwR9LHWvatIDnwqRYJyjVmSo1Zx8K_XDh6SyM,4626 +pygments/formatters/terminal256.py,sha256=7GQFLE5cfmeu53CAzANO74-kBk2BFkXfn5phmZjYkhM,11717 +pygments/lexer.py,sha256=ib-F_0GxHkwGpb6vWP0DeLMLc7EYgjo3hWFKN5IgOq0,35109 +pygments/lexers/__init__.py,sha256=6YhzxGKlWk38P6JpIJUQ1rVvV0DEZjEmdYsdMQ58hSk,12067 +pygments/lexers/__pycache__/__init__.cpython-312.pyc,, +pygments/lexers/__pycache__/_ada_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_asy_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_cl_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_cocoa_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_csound_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_css_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_googlesql_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_julia_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_lasso_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_lilypond_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_lua_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_luau_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_mapping.cpython-312.pyc,, +pygments/lexers/__pycache__/_mql_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_mysql_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_openedge_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_php_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_postgres_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_qlik_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_scheme_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_scilab_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_sourcemod_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_stan_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_stata_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_tsql_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_usd_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_vbscript_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/_vim_builtins.cpython-312.pyc,, +pygments/lexers/__pycache__/actionscript.cpython-312.pyc,, +pygments/lexers/__pycache__/ada.cpython-312.pyc,, +pygments/lexers/__pycache__/agile.cpython-312.pyc,, +pygments/lexers/__pycache__/algebra.cpython-312.pyc,, +pygments/lexers/__pycache__/ambient.cpython-312.pyc,, +pygments/lexers/__pycache__/amdgpu.cpython-312.pyc,, +pygments/lexers/__pycache__/ampl.cpython-312.pyc,, +pygments/lexers/__pycache__/apdlexer.cpython-312.pyc,, +pygments/lexers/__pycache__/apl.cpython-312.pyc,, +pygments/lexers/__pycache__/archetype.cpython-312.pyc,, +pygments/lexers/__pycache__/arrow.cpython-312.pyc,, +pygments/lexers/__pycache__/arturo.cpython-312.pyc,, +pygments/lexers/__pycache__/asc.cpython-312.pyc,, +pygments/lexers/__pycache__/asm.cpython-312.pyc,, +pygments/lexers/__pycache__/asn1.cpython-312.pyc,, +pygments/lexers/__pycache__/automation.cpython-312.pyc,, +pygments/lexers/__pycache__/bare.cpython-312.pyc,, +pygments/lexers/__pycache__/basic.cpython-312.pyc,, +pygments/lexers/__pycache__/bdd.cpython-312.pyc,, +pygments/lexers/__pycache__/berry.cpython-312.pyc,, +pygments/lexers/__pycache__/bibtex.cpython-312.pyc,, +pygments/lexers/__pycache__/blueprint.cpython-312.pyc,, +pygments/lexers/__pycache__/boa.cpython-312.pyc,, +pygments/lexers/__pycache__/bqn.cpython-312.pyc,, +pygments/lexers/__pycache__/business.cpython-312.pyc,, +pygments/lexers/__pycache__/c_cpp.cpython-312.pyc,, +pygments/lexers/__pycache__/c_like.cpython-312.pyc,, +pygments/lexers/__pycache__/capnproto.cpython-312.pyc,, +pygments/lexers/__pycache__/carbon.cpython-312.pyc,, +pygments/lexers/__pycache__/cddl.cpython-312.pyc,, +pygments/lexers/__pycache__/chapel.cpython-312.pyc,, +pygments/lexers/__pycache__/clean.cpython-312.pyc,, +pygments/lexers/__pycache__/codeql.cpython-312.pyc,, +pygments/lexers/__pycache__/comal.cpython-312.pyc,, +pygments/lexers/__pycache__/compiled.cpython-312.pyc,, +pygments/lexers/__pycache__/configs.cpython-312.pyc,, +pygments/lexers/__pycache__/console.cpython-312.pyc,, +pygments/lexers/__pycache__/cplint.cpython-312.pyc,, +pygments/lexers/__pycache__/crystal.cpython-312.pyc,, +pygments/lexers/__pycache__/csound.cpython-312.pyc,, +pygments/lexers/__pycache__/css.cpython-312.pyc,, +pygments/lexers/__pycache__/d.cpython-312.pyc,, +pygments/lexers/__pycache__/dalvik.cpython-312.pyc,, +pygments/lexers/__pycache__/data.cpython-312.pyc,, +pygments/lexers/__pycache__/dax.cpython-312.pyc,, +pygments/lexers/__pycache__/devicetree.cpython-312.pyc,, +pygments/lexers/__pycache__/diff.cpython-312.pyc,, +pygments/lexers/__pycache__/dns.cpython-312.pyc,, +pygments/lexers/__pycache__/dotnet.cpython-312.pyc,, +pygments/lexers/__pycache__/dsls.cpython-312.pyc,, +pygments/lexers/__pycache__/dylan.cpython-312.pyc,, +pygments/lexers/__pycache__/ecl.cpython-312.pyc,, +pygments/lexers/__pycache__/eiffel.cpython-312.pyc,, +pygments/lexers/__pycache__/elm.cpython-312.pyc,, +pygments/lexers/__pycache__/elpi.cpython-312.pyc,, +pygments/lexers/__pycache__/email.cpython-312.pyc,, +pygments/lexers/__pycache__/erlang.cpython-312.pyc,, +pygments/lexers/__pycache__/esoteric.cpython-312.pyc,, +pygments/lexers/__pycache__/ezhil.cpython-312.pyc,, +pygments/lexers/__pycache__/factor.cpython-312.pyc,, +pygments/lexers/__pycache__/fantom.cpython-312.pyc,, +pygments/lexers/__pycache__/felix.cpython-312.pyc,, +pygments/lexers/__pycache__/fift.cpython-312.pyc,, +pygments/lexers/__pycache__/floscript.cpython-312.pyc,, +pygments/lexers/__pycache__/forth.cpython-312.pyc,, +pygments/lexers/__pycache__/fortran.cpython-312.pyc,, +pygments/lexers/__pycache__/foxpro.cpython-312.pyc,, +pygments/lexers/__pycache__/freefem.cpython-312.pyc,, +pygments/lexers/__pycache__/func.cpython-312.pyc,, +pygments/lexers/__pycache__/functional.cpython-312.pyc,, +pygments/lexers/__pycache__/futhark.cpython-312.pyc,, +pygments/lexers/__pycache__/gcodelexer.cpython-312.pyc,, +pygments/lexers/__pycache__/gdscript.cpython-312.pyc,, +pygments/lexers/__pycache__/gleam.cpython-312.pyc,, +pygments/lexers/__pycache__/go.cpython-312.pyc,, +pygments/lexers/__pycache__/grammar_notation.cpython-312.pyc,, +pygments/lexers/__pycache__/graph.cpython-312.pyc,, +pygments/lexers/__pycache__/graphics.cpython-312.pyc,, +pygments/lexers/__pycache__/graphql.cpython-312.pyc,, +pygments/lexers/__pycache__/graphviz.cpython-312.pyc,, +pygments/lexers/__pycache__/gsql.cpython-312.pyc,, +pygments/lexers/__pycache__/hare.cpython-312.pyc,, +pygments/lexers/__pycache__/haskell.cpython-312.pyc,, +pygments/lexers/__pycache__/haxe.cpython-312.pyc,, +pygments/lexers/__pycache__/hdl.cpython-312.pyc,, +pygments/lexers/__pycache__/hexdump.cpython-312.pyc,, +pygments/lexers/__pycache__/html.cpython-312.pyc,, +pygments/lexers/__pycache__/idl.cpython-312.pyc,, +pygments/lexers/__pycache__/igor.cpython-312.pyc,, +pygments/lexers/__pycache__/inferno.cpython-312.pyc,, +pygments/lexers/__pycache__/installers.cpython-312.pyc,, +pygments/lexers/__pycache__/int_fiction.cpython-312.pyc,, +pygments/lexers/__pycache__/iolang.cpython-312.pyc,, +pygments/lexers/__pycache__/j.cpython-312.pyc,, +pygments/lexers/__pycache__/javascript.cpython-312.pyc,, +pygments/lexers/__pycache__/jmespath.cpython-312.pyc,, +pygments/lexers/__pycache__/jslt.cpython-312.pyc,, +pygments/lexers/__pycache__/json5.cpython-312.pyc,, +pygments/lexers/__pycache__/jsonnet.cpython-312.pyc,, +pygments/lexers/__pycache__/jsx.cpython-312.pyc,, +pygments/lexers/__pycache__/julia.cpython-312.pyc,, +pygments/lexers/__pycache__/jvm.cpython-312.pyc,, +pygments/lexers/__pycache__/kuin.cpython-312.pyc,, +pygments/lexers/__pycache__/kusto.cpython-312.pyc,, +pygments/lexers/__pycache__/ldap.cpython-312.pyc,, +pygments/lexers/__pycache__/lean.cpython-312.pyc,, +pygments/lexers/__pycache__/lilypond.cpython-312.pyc,, +pygments/lexers/__pycache__/lisp.cpython-312.pyc,, +pygments/lexers/__pycache__/macaulay2.cpython-312.pyc,, +pygments/lexers/__pycache__/make.cpython-312.pyc,, +pygments/lexers/__pycache__/maple.cpython-312.pyc,, +pygments/lexers/__pycache__/markup.cpython-312.pyc,, +pygments/lexers/__pycache__/math.cpython-312.pyc,, +pygments/lexers/__pycache__/matlab.cpython-312.pyc,, +pygments/lexers/__pycache__/maxima.cpython-312.pyc,, +pygments/lexers/__pycache__/meson.cpython-312.pyc,, +pygments/lexers/__pycache__/mime.cpython-312.pyc,, +pygments/lexers/__pycache__/minecraft.cpython-312.pyc,, +pygments/lexers/__pycache__/mips.cpython-312.pyc,, +pygments/lexers/__pycache__/ml.cpython-312.pyc,, +pygments/lexers/__pycache__/modeling.cpython-312.pyc,, +pygments/lexers/__pycache__/modula2.cpython-312.pyc,, +pygments/lexers/__pycache__/mojo.cpython-312.pyc,, +pygments/lexers/__pycache__/monte.cpython-312.pyc,, +pygments/lexers/__pycache__/mosel.cpython-312.pyc,, +pygments/lexers/__pycache__/ncl.cpython-312.pyc,, +pygments/lexers/__pycache__/nimrod.cpython-312.pyc,, +pygments/lexers/__pycache__/nit.cpython-312.pyc,, +pygments/lexers/__pycache__/nix.cpython-312.pyc,, +pygments/lexers/__pycache__/numbair.cpython-312.pyc,, +pygments/lexers/__pycache__/oberon.cpython-312.pyc,, +pygments/lexers/__pycache__/objective.cpython-312.pyc,, +pygments/lexers/__pycache__/ooc.cpython-312.pyc,, +pygments/lexers/__pycache__/openscad.cpython-312.pyc,, +pygments/lexers/__pycache__/other.cpython-312.pyc,, +pygments/lexers/__pycache__/parasail.cpython-312.pyc,, +pygments/lexers/__pycache__/parsers.cpython-312.pyc,, +pygments/lexers/__pycache__/pascal.cpython-312.pyc,, +pygments/lexers/__pycache__/pawn.cpython-312.pyc,, +pygments/lexers/__pycache__/pddl.cpython-312.pyc,, +pygments/lexers/__pycache__/perl.cpython-312.pyc,, +pygments/lexers/__pycache__/phix.cpython-312.pyc,, +pygments/lexers/__pycache__/php.cpython-312.pyc,, +pygments/lexers/__pycache__/pointless.cpython-312.pyc,, +pygments/lexers/__pycache__/pony.cpython-312.pyc,, +pygments/lexers/__pycache__/praat.cpython-312.pyc,, +pygments/lexers/__pycache__/procfile.cpython-312.pyc,, +pygments/lexers/__pycache__/prolog.cpython-312.pyc,, +pygments/lexers/__pycache__/promql.cpython-312.pyc,, +pygments/lexers/__pycache__/prql.cpython-312.pyc,, +pygments/lexers/__pycache__/ptx.cpython-312.pyc,, +pygments/lexers/__pycache__/python.cpython-312.pyc,, +pygments/lexers/__pycache__/q.cpython-312.pyc,, +pygments/lexers/__pycache__/qlik.cpython-312.pyc,, +pygments/lexers/__pycache__/qvt.cpython-312.pyc,, +pygments/lexers/__pycache__/r.cpython-312.pyc,, +pygments/lexers/__pycache__/rdf.cpython-312.pyc,, +pygments/lexers/__pycache__/rebol.cpython-312.pyc,, +pygments/lexers/__pycache__/rego.cpython-312.pyc,, +pygments/lexers/__pycache__/resource.cpython-312.pyc,, +pygments/lexers/__pycache__/ride.cpython-312.pyc,, +pygments/lexers/__pycache__/rita.cpython-312.pyc,, +pygments/lexers/__pycache__/rnc.cpython-312.pyc,, +pygments/lexers/__pycache__/roboconf.cpython-312.pyc,, +pygments/lexers/__pycache__/robotframework.cpython-312.pyc,, +pygments/lexers/__pycache__/ruby.cpython-312.pyc,, +pygments/lexers/__pycache__/rust.cpython-312.pyc,, +pygments/lexers/__pycache__/sas.cpython-312.pyc,, +pygments/lexers/__pycache__/savi.cpython-312.pyc,, +pygments/lexers/__pycache__/scdoc.cpython-312.pyc,, +pygments/lexers/__pycache__/scripting.cpython-312.pyc,, +pygments/lexers/__pycache__/sgf.cpython-312.pyc,, +pygments/lexers/__pycache__/shell.cpython-312.pyc,, +pygments/lexers/__pycache__/sieve.cpython-312.pyc,, +pygments/lexers/__pycache__/slash.cpython-312.pyc,, +pygments/lexers/__pycache__/smalltalk.cpython-312.pyc,, +pygments/lexers/__pycache__/smithy.cpython-312.pyc,, +pygments/lexers/__pycache__/smv.cpython-312.pyc,, +pygments/lexers/__pycache__/snobol.cpython-312.pyc,, +pygments/lexers/__pycache__/solidity.cpython-312.pyc,, +pygments/lexers/__pycache__/soong.cpython-312.pyc,, +pygments/lexers/__pycache__/sophia.cpython-312.pyc,, +pygments/lexers/__pycache__/special.cpython-312.pyc,, +pygments/lexers/__pycache__/spice.cpython-312.pyc,, +pygments/lexers/__pycache__/sql.cpython-312.pyc,, +pygments/lexers/__pycache__/srcinfo.cpython-312.pyc,, +pygments/lexers/__pycache__/stata.cpython-312.pyc,, +pygments/lexers/__pycache__/supercollider.cpython-312.pyc,, +pygments/lexers/__pycache__/tablegen.cpython-312.pyc,, +pygments/lexers/__pycache__/tact.cpython-312.pyc,, +pygments/lexers/__pycache__/tal.cpython-312.pyc,, +pygments/lexers/__pycache__/tcl.cpython-312.pyc,, +pygments/lexers/__pycache__/teal.cpython-312.pyc,, +pygments/lexers/__pycache__/templates.cpython-312.pyc,, +pygments/lexers/__pycache__/teraterm.cpython-312.pyc,, +pygments/lexers/__pycache__/testing.cpython-312.pyc,, +pygments/lexers/__pycache__/text.cpython-312.pyc,, +pygments/lexers/__pycache__/textedit.cpython-312.pyc,, +pygments/lexers/__pycache__/textfmts.cpython-312.pyc,, +pygments/lexers/__pycache__/theorem.cpython-312.pyc,, +pygments/lexers/__pycache__/thingsdb.cpython-312.pyc,, +pygments/lexers/__pycache__/tlb.cpython-312.pyc,, +pygments/lexers/__pycache__/tls.cpython-312.pyc,, +pygments/lexers/__pycache__/tnt.cpython-312.pyc,, +pygments/lexers/__pycache__/trafficscript.cpython-312.pyc,, +pygments/lexers/__pycache__/typoscript.cpython-312.pyc,, +pygments/lexers/__pycache__/typst.cpython-312.pyc,, +pygments/lexers/__pycache__/ul4.cpython-312.pyc,, +pygments/lexers/__pycache__/unicon.cpython-312.pyc,, +pygments/lexers/__pycache__/urbi.cpython-312.pyc,, +pygments/lexers/__pycache__/usd.cpython-312.pyc,, +pygments/lexers/__pycache__/varnish.cpython-312.pyc,, +pygments/lexers/__pycache__/verification.cpython-312.pyc,, +pygments/lexers/__pycache__/verifpal.cpython-312.pyc,, +pygments/lexers/__pycache__/vip.cpython-312.pyc,, +pygments/lexers/__pycache__/vyper.cpython-312.pyc,, +pygments/lexers/__pycache__/web.cpython-312.pyc,, +pygments/lexers/__pycache__/webassembly.cpython-312.pyc,, +pygments/lexers/__pycache__/webidl.cpython-312.pyc,, +pygments/lexers/__pycache__/webmisc.cpython-312.pyc,, +pygments/lexers/__pycache__/wgsl.cpython-312.pyc,, +pygments/lexers/__pycache__/whiley.cpython-312.pyc,, +pygments/lexers/__pycache__/wowtoc.cpython-312.pyc,, +pygments/lexers/__pycache__/wren.cpython-312.pyc,, +pygments/lexers/__pycache__/x10.cpython-312.pyc,, +pygments/lexers/__pycache__/xorg.cpython-312.pyc,, +pygments/lexers/__pycache__/yang.cpython-312.pyc,, +pygments/lexers/__pycache__/yara.cpython-312.pyc,, +pygments/lexers/__pycache__/zig.cpython-312.pyc,, +pygments/lexers/_ada_builtins.py,sha256=CA_OnShtdc7wWh9oYcRlcrkDAQwYUKl6w7tdSbALQd4,1543 +pygments/lexers/_asy_builtins.py,sha256=cd9M00YH19w5ZL7aqucmC3nwpJGTS04U-01NLy5E2_4,27287 +pygments/lexers/_cl_builtins.py,sha256=kQeUIyZjP4kX0frkICDcKxBYQCLqzIDXa5WV5cevhDo,13994 +pygments/lexers/_cocoa_builtins.py,sha256=Ka1lLJe7JfWtdho4IFIB82X9yBvrbfHCCmEG-peXXhQ,105173 +pygments/lexers/_csound_builtins.py,sha256=qnQYKeI26ZHim316uqy_hDiRiCoHo2RHjD3sYBALyXs,18414 +pygments/lexers/_css_builtins.py,sha256=aD-dhLFXVd1Atn_bZd7gEdQn7Mhe60_VHpvZ340WzDI,12446 +pygments/lexers/_googlesql_builtins.py,sha256=IkrOk-T2v1yzbGzUEEQh5_Cf4uC_cmL_uuhwDpZlTug,16132 +pygments/lexers/_julia_builtins.py,sha256=N2WdSw5zgI2fhDat_i4YeVqurRTC_P8x71ez00SCN6U,11883 +pygments/lexers/_lasso_builtins.py,sha256=8q1gbsrMJeaeUhxIYKhaOxC9j_B-NBpq_XFj2Ze41X0,134510 +pygments/lexers/_lilypond_builtins.py,sha256=XTbGL1z1oKMoqWLEktG33jx5GdGTI9CpeO5NheEi4Y0,108094 +pygments/lexers/_lua_builtins.py,sha256=PhFdZV5-Tzz2j_q4lvG9lr84ELGfL41BhnrSDNNTaG4,8108 +pygments/lexers/_luau_builtins.py,sha256=-IDrU04kUVfjXwSQzMMpXmMYhNsQxZVVZk8cuAA0Lo0,955 +pygments/lexers/_mapping.py,sha256=9fv7xYOUAOr6LzfdFS4MDbPu78o4OQQH-2nsI1bNZf4,70438 +pygments/lexers/_mql_builtins.py,sha256=ybRQjlb7Cul0sDstnzxJl3h0qS6Ieqsr811fqrxyumU,24713 +pygments/lexers/_mysql_builtins.py,sha256=y0kAWZVAs0z2dTFJJV42OZpILgRnd8T3zSlBFv-g_oA,25838 +pygments/lexers/_openedge_builtins.py,sha256=Sz4j9-CPWIaxMa-2fZgY66j7igcu1ob1GR2UtI8zAkg,49398 +pygments/lexers/_php_builtins.py,sha256=Jd4BZpjMDELPi4EVoSxK1-8BFTc63HUwYfm1rLrGj0M,107922 +pygments/lexers/_postgres_builtins.py,sha256=Pqh4z0RBRbnW6rCQtWUdzWCJxNyqpJ7_0HOktxHDxk4,13343 +pygments/lexers/_qlik_builtins.py,sha256=xuJy9c9uZDXv6h8z582P5PrxqkxTZ_nS8gPl9OD9VN8,12595 +pygments/lexers/_scheme_builtins.py,sha256=2hNtJOJmP21lUsikpqMJ2gAmLT3Rwn_KEeqhXwCjgfk,32564 +pygments/lexers/_scilab_builtins.py,sha256=oZYPB1XPdIEz3pII11pFDe6extRRyWGA7pY06X8KZ8w,52411 +pygments/lexers/_sourcemod_builtins.py,sha256=H8AFLsNDdEpymIWOpDwbDJGCP1w-x-1gSlzPDioMF4o,26777 +pygments/lexers/_stan_builtins.py,sha256=dwi1hllM_NsaCv-aXJy7lEi57X5Hh5gSD97aCQyT9KM,13445 +pygments/lexers/_stata_builtins.py,sha256=Hqrr6j77zWU3cGGpBPohwexZci43YA4_sVYE4E1sNow,27227 +pygments/lexers/_tsql_builtins.py,sha256=Pi2RhTXcLE3glI9oxNhyVsOMn-fK_1TRxJ-EsYP5LcI,15460 +pygments/lexers/_usd_builtins.py,sha256=c9hbU1cwqBUCFIhNfu_Dob8ywv1rlPhi9w2OTj3kR8s,1658 +pygments/lexers/_vbscript_builtins.py,sha256=MqJ2ABywD21aSRtWYZRG64CCbGstC1kfsiHGJmZzxiw,4225 +pygments/lexers/_vim_builtins.py,sha256=bA4mH8t1mPPQfEiUCKEqRO1O0rL2DUG0Ux1Bt8ZSu0E,57066 +pygments/lexers/actionscript.py,sha256=JBngCe5UhYT_0dLD2j7PnPO0xRRJhmypEuQ-C5in8pY,11727 +pygments/lexers/ada.py,sha256=58k5ra1vGS4iLpW3h1ItY9ftzF3WevaeAAXzAYTiYkQ,5353 +pygments/lexers/agile.py,sha256=DN-7AVIqtG1MshA94rtSGYI_884hVHgzq405wD0_dl8,896 +pygments/lexers/algebra.py,sha256=yGTu9Tt-cQzAISQYIC5MS5a3z4QmL-tGcXnd_pkWGbk,9952 +pygments/lexers/ambient.py,sha256=UnzKpIlfSm3iitHvMd7XTMSY8TjZYYhKOC3AiARS_cE,2605 +pygments/lexers/amdgpu.py,sha256=S8qjn2UMLhBFm3Yn_c06XAGf8cl5x_ZeluelWG_-JAw,1723 +pygments/lexers/ampl.py,sha256=ZBRfDXm760gR1a1gqItnsHuoO3JdUcTBjJ5tFY9UtPA,4176 +pygments/lexers/apdlexer.py,sha256=Zr5-jgjxC8PKzRlEeclakZXPHci7FHBZghQ6wwiuT7A,30800 +pygments/lexers/apl.py,sha256=PTQMp-bxT5P-DbrEvFha10HBTcsDJ5srL3I1s9ljz58,3404 +pygments/lexers/archetype.py,sha256=pQVlP1Fb5OA8nn7QwmFaaaOSvvpoIsQVw43FVCQCve4,11538 +pygments/lexers/arrow.py,sha256=2PKdbWq3xQLF1KoDbWvSxpjwKRrznnDiArTflRGZzBo,3564 +pygments/lexers/arturo.py,sha256=U5MtRNHJtnBn4ZOeWmW6MKlVRG7SX6KhTRamDqzn9tA,11414 +pygments/lexers/asc.py,sha256=-DgZl9jccBDHPlDmjCsrEqx0-Q7ap7XVdNKtxLNWG1w,1693 +pygments/lexers/asm.py,sha256=xm2Y5mcT-sF3oQvair4SWs9EWTyndoaUoSsDy5v6shI,41967 +pygments/lexers/asn1.py,sha256=BlcloIX2bu6Q7BxGcksuhYFHGsXLVKyB4B9mFd4Pj6E,4262 +pygments/lexers/automation.py,sha256=Q61qon8EwpfakMh_2MS2E2zUUT16rG3UNIKPYjITeTs,19831 +pygments/lexers/bare.py,sha256=tWoei86JJX1k-ADhaXd5TgX6ItDTici9yFWpkTPhnfM,3020 +pygments/lexers/basic.py,sha256=qpVe5h8Fa7NJo1EihN-4R_UZpHO6my2Ssgkb-BktkKs,27989 +pygments/lexers/bdd.py,sha256=yysefcOFAEyk9kJ2y4EXmzJTecgLYUHlWixt_3YzPMU,1641 +pygments/lexers/berry.py,sha256=zxGowFb8HMIyN15-m8nmWnW6bPRR4esKtSEVugc9uXM,3209 +pygments/lexers/bibtex.py,sha256=yuNoPxwrJf9DCGUT17hxfDzbq_HtCLkQkRbBtiTVmeQ,4811 +pygments/lexers/blueprint.py,sha256=NzvWHMxCLDWt8hc6gB5jokltxVJgNa7Jwh4c61ng388,6188 +pygments/lexers/boa.py,sha256=dOot1XWNZThPIio2UyAX67K6EpISjSRCFjotD7dcnwE,3921 +pygments/lexers/bqn.py,sha256=nJiwrPKKbRF-qdai5tfqipwBkkko2P3weiZAjHUMimY,3671 +pygments/lexers/business.py,sha256=lRtekOJfsDkb12AGbuz10-G67OJrVJgCBtihTQ8_aoY,28345 +pygments/lexers/c_cpp.py,sha256=D7ZIswaHASlGBgoTlwnSqTQHf8_JyvvSt2L2q1W-F6g,18059 +pygments/lexers/c_like.py,sha256=FTGp17ds6X2rDZOHup2hH6BEn3gKK4nLm9pydNEhm0E,32021 +pygments/lexers/capnproto.py,sha256=XQJAh1WS-0ulqbTn9TdzR6gEgWLcuBqb4sj3jNsrhsY,2174 +pygments/lexers/carbon.py,sha256=av12YuTGZGpOa1Cmxp3lppx3LfSJUWbvOu0ixmUVll0,3211 +pygments/lexers/cddl.py,sha256=MKa70IwABgjBjYu15_Q9v8rsu2sr1a-i2jkiaPTI6sM,5076 +pygments/lexers/chapel.py,sha256=0n_fL3ehLC4pw4YKnmq9jxIXOJcxGPka1Wr1t1zsXPc,5156 +pygments/lexers/clean.py,sha256=dkDPAwF5BTALPeuKFoRKOSD3RfsKcGWbaRo6_G8LHng,6418 +pygments/lexers/codeql.py,sha256=ebvghn2zbrnETV4buVozMDmRCVKSdGiIN8ycLlHpGsE,2576 +pygments/lexers/comal.py,sha256=TC3NzcJ58ew5jw7qwK0kJ-okTA47psZje0yAIS39HR4,3179 +pygments/lexers/compiled.py,sha256=Slfo1sjWqcPawUwf0dIIZLBCL5pkOIoAX2S8Lxs02Mc,1426 +pygments/lexers/configs.py,sha256=wW8pY0Sa5a10pnAeTLGf48HhixQTVageIyHEf1aYMCc,50913 +pygments/lexers/console.py,sha256=-jAG120dupvV3kG3zC70brLJvSLwTFqMubBQuj_GVnU,4180 +pygments/lexers/cplint.py,sha256=DkbyE5EKydLgf6BRr1FhQrK-IeQPL7Zmjk0DVdlRFnQ,1389 +pygments/lexers/crystal.py,sha256=xU-RnpIkpjrquoxtOuOcP8fcesSJl4xhU7kO9m42LZY,15754 +pygments/lexers/csound.py,sha256=ioSw4Q04wdwjUAbnTZ1qLhUq1vxdWFxhh3QtEl5RAJc,16998 +pygments/lexers/css.py,sha256=JN1RBYsee-jrpHWrSmhN3TKc4TkOBn-_BEGpgTCzcqE,25376 +pygments/lexers/d.py,sha256=piOy0EJeiAwPHugiM3gVv0z7HNh3u2gZQoCUSASRbY4,9920 +pygments/lexers/dalvik.py,sha256=deFg2JPBktJ9mEGb9EgxNkmd6vaMjJFQVzUHo8NKIa8,4606 +pygments/lexers/data.py,sha256=o0x0SmB5ms_CPUPljEEEenOON4IQWn86DkwFjkJYCOg,27026 +pygments/lexers/dax.py,sha256=ASi73qmr7OA7cVZXF2GTYGt01Ly1vY8CgD_Pnpm8k-4,8098 +pygments/lexers/devicetree.py,sha256=RecSQCidt8DRE1QFCPUbwwR0hiRlNtsFihdGldeUn3k,4019 +pygments/lexers/diff.py,sha256=F6vxZ64wm5Nag_97de1H_3F700ZwCVnYjKvtT5jilww,5382 +pygments/lexers/dns.py,sha256=Hh5hJ7MXfrq36KgfyIRwK3X8o1LdR98IKERcV4eZ7HY,3891 +pygments/lexers/dotnet.py,sha256=NDE0kOmpe96GLO-zwNLazmj77E9ORGmKpa4ZMCXDXxQ,39441 +pygments/lexers/dsls.py,sha256=GnHKhGL5GxsRFnqC7-65NTPZLOZdmnllNrGP86x_fQE,36746 +pygments/lexers/dylan.py,sha256=7zZ1EbHWXeVHqTD36AqykKqo3fhuIh4sM-whcxUaH_Y,10409 +pygments/lexers/ecl.py,sha256=vhmpa2LBrHxsPkYcf3kPZ1ItVaLRDTebi186wY0xGZA,6371 +pygments/lexers/eiffel.py,sha256=5ydYIEFcgcMoEj4BlK31hZ0aJb8OX0RdAvuCNdlxwqw,2690 +pygments/lexers/elm.py,sha256=uRCddU8jK5vVkH6Y66y8KOsDJprIfrOgeYq3hv1PxAM,3152 +pygments/lexers/elpi.py,sha256=O9j_WKBPyvNFjCRuPciVpW4etVSnILm_T79BhCPZYmo,6877 +pygments/lexers/email.py,sha256=ZZL6yvwCRl1CEQyysuOu0lbabp5tjMutS7f3efFKGR4,4804 +pygments/lexers/erlang.py,sha256=bU11eVHvooLwmVknzN6Xkb2DMk7HbenqdNlYSzhThDM,19147 +pygments/lexers/esoteric.py,sha256=Jfp8UUKyKYsqLaqXRZT3GSM9dzkF65zduwfnH1GoGhU,10500 +pygments/lexers/ezhil.py,sha256=22r-xjvvBVpExTqCI-HycAwunDb1p5gY4tIfDmM0vDw,3272 +pygments/lexers/factor.py,sha256=urZ4En4uKFCLXdEkXLWg9EYUFGHQTTDCwNXtyq-ngok,19530 +pygments/lexers/fantom.py,sha256=JJ13-NwykD-iIESnuzCefCYeQDO95cHMJA8TasF4gHA,10231 +pygments/lexers/felix.py,sha256=F-v0si4zPtRelqzDQWXI1-tarCE-BvawziODxRU7378,9655 +pygments/lexers/fift.py,sha256=rOCwp3v5ocK5YOWvt7Td3Md--97_8e-7Sonx52uS8mA,1644 +pygments/lexers/floscript.py,sha256=aHh82k52jMuDuzl9LatrcSANJiXTCyjGU3SO53bwbb0,2667 +pygments/lexers/forth.py,sha256=ZMtsHdNbnS_0IdSYlfAlfTSPEr0MEsRo-YZriQNueTQ,7193 +pygments/lexers/fortran.py,sha256=1PE5dTxf4Df6LUeXFcmNtyeXWsC8tSiK5dYwPHIJeeQ,10382 +pygments/lexers/foxpro.py,sha256=CBkW62Fuibz3yfyelZCaEO8GGdFJWsuRhqwtsSeBwLM,26295 +pygments/lexers/freefem.py,sha256=LFBQk-m1-nNCgrl-VDH3QwnVWurvb7W29i06LoT207A,26913 +pygments/lexers/func.py,sha256=OR2rkM7gf9fKvad5WcFQln-_U_pb-RUCM9eQatToF4A,3700 +pygments/lexers/functional.py,sha256=fYT2AGZ642cRkIAId0rnXFBsx1c8LLEDRN_VuCEkUyM,693 +pygments/lexers/futhark.py,sha256=Vf1i4t-tR3zqaktVjhTzFNg_ts_9CcyA4ZDfDizbCmk,3743 +pygments/lexers/gcodelexer.py,sha256=4Xs9ax4-JZGupW_qSnHon39wQGpb-tNA3xorMKg841E,874 +pygments/lexers/gdscript.py,sha256=Ws7JKxy0M0IyZ_1iMfRvJPrizEwmeCNLDoeMIFaM-CU,7566 +pygments/lexers/gleam.py,sha256=XIlTcq6cB743pCqbNYo8PocSkjZyDPR6hHgdaJNJ1Vc,2392 +pygments/lexers/go.py,sha256=4LezefgyuqZWHzLZHieUkKTi-ssY6aHJxx7Z-LFaLK0,3783 +pygments/lexers/grammar_notation.py,sha256=LvzhRQHgwZzq9oceukZS_hwnKK58ee7Z5d0cwXOR734,8043 +pygments/lexers/graph.py,sha256=WFqoPA1c_hHYrV0i_F7-eUw3Co4_HmZY3GJ-TyDr670,4108 +pygments/lexers/graphics.py,sha256=tmF9NNALnvPnax8ywYC3pLOla45YXtp9UA0H-5EiTQY,39145 +pygments/lexers/graphql.py,sha256=O_zcrGrBaDaKTlUoJGRruxqk7CJi-NR92Y0Cs-KkCvw,5601 +pygments/lexers/graphviz.py,sha256=mzdXOMpwz9_V-be1eTAMyhkKCBl6UxCIXuq6C2yrtsw,1934 +pygments/lexers/gsql.py,sha256=VPZk9sb26-DumRkWfEaSTeoc0lx5xt5n-6eDDLezMtc,3990 +pygments/lexers/hare.py,sha256=PGCOuILktJsmtTpCZZKkMFtObfJuBpei8HM8HHuq1Tw,2649 +pygments/lexers/haskell.py,sha256=MYr74-PAC8kGJRX-dZmvZsHTc7a2u6yFS2B19LfDD7g,33262 +pygments/lexers/haxe.py,sha256=WHCy_nrXHnfLITfbdp3Ji3lqQU4HAsTUpXsLCp2_4sk,30974 +pygments/lexers/hdl.py,sha256=MOWxhmAuE4Ei0CKDqqaON7T8tl43geancrNYM136Z0U,22738 +pygments/lexers/hexdump.py,sha256=1lj9oJ-KiZXSVYvTMfGmEAQzNEW08WlMcC2I5aYvHK4,3653 +pygments/lexers/html.py,sha256=MxYTI4EeT7QxoGleCAyQq-8n_Sgly6tD95H5zanCNmk,21977 +pygments/lexers/idl.py,sha256=rcihUAGhfuGEaSW6pgFq6NzplT_pv0DagUoefg4zAmk,15449 +pygments/lexers/igor.py,sha256=wVefbUjb3ftaW3LCKGtX1JgLgiY4EmRor5gVOn8vQA8,31633 +pygments/lexers/inferno.py,sha256=ChE_5y5SLH_75Uv7D2dKWQMk2dlN6z1gY1IDjlJZ8rU,3135 +pygments/lexers/installers.py,sha256=ZHliit4Pxz1tYKOIjKkDXI5djTkpzYUMVIPR1xvUrL8,14435 +pygments/lexers/int_fiction.py,sha256=0ZzIa1sZDUQsltd1oHuS-BoNiOF8zKQfcVuDyK1Ttv8,56544 +pygments/lexers/iolang.py,sha256=L6dNDCLH0kxkIUi00fI4Z14QnRu79UcNDrgv02c5Zw8,1905 +pygments/lexers/j.py,sha256=DqNdwQGFLiZW3mCNLRg81gpmsy4Hgcai_9NP3LbWhNU,4853 +pygments/lexers/javascript.py,sha256=TGKQLSrCprCKfhLLGAq_0EOdvqvJKX9pOdKo7tCRurQ,63243 +pygments/lexers/jmespath.py,sha256=R5yA5LJ2nTIaDwnFIpSNGAThd0sAYFccwawA9xBptlg,2082 +pygments/lexers/jslt.py,sha256=OeYQf8O2_9FCaf9W6Q3a7rPdAFLthePCtVSgCrOTcl8,3700 +pygments/lexers/json5.py,sha256=8JZbc8EiTEZdKaIdQg3hXEh0mHWSzPlwd473a0nUuT0,2502 +pygments/lexers/jsonnet.py,sha256=bx2G6J4tJqGrJV1PyZrIWzWHXcoefCX-4lIxxtbn2gw,5636 +pygments/lexers/jsx.py,sha256=wGsoGSB40qAJrVfXwRPtan7OcK0O87RVsHHk0m6gogk,2693 +pygments/lexers/julia.py,sha256=0ZDJ9X83V5GqJzA6T6p0TTN8WHy2JAjvu-FSBXvfXdc,11710 +pygments/lexers/jvm.py,sha256=Yt1iQ3QodXRY-x_HUOGedhyuBBHn5jYH-I8NzOzHTlE,72667 +pygments/lexers/kuin.py,sha256=3dKKJVJlskgrvMKv2tY9NOsFfDjyo-3MLcJ1lFKdXSg,11405 +pygments/lexers/kusto.py,sha256=kaxkoPpEBDsBTCvCOkZZx7oGfv0jk_UNIRIRbfVAsBE,3477 +pygments/lexers/ldap.py,sha256=77vF4t_19x9V522cxRCM5d3HW8Ne3giYsFsMPVYYBw4,6551 +pygments/lexers/lean.py,sha256=7HWRgxFsxS1N9XKqw0vfKwaxl27s5YiVYtZeRUoTHFo,8570 +pygments/lexers/lilypond.py,sha256=yd2Tuv67um6EyCIr-VwBnlPhTHxMaQsBJ4nGgO5fjIk,9752 +pygments/lexers/lisp.py,sha256=EHUy1g4pzEsYPE-zGj2rAXm3YATE1j9dCQOr5-JPSkU,157668 +pygments/lexers/macaulay2.py,sha256=zkV-vxjQYa0Jj9TGfFP1iMgpTZ4ApQuAAIdJVGWb2is,33366 +pygments/lexers/make.py,sha256=YMI5DBCrxWca-pz9cVXcyfuHLcikPx9R_3pW_98Myqo,7831 +pygments/lexers/maple.py,sha256=Rs0dEmOMD3C1YQPd0mntN-vzReq4XfHegH6xV4lvJWo,7960 +pygments/lexers/markup.py,sha256=zWtxsyIx_1OxQzS6wLe8bEqglePv4RqvJjbia8AvV5c,65088 +pygments/lexers/math.py,sha256=P3ZK1ePd8ZnLdlmHezo2irCA8T2-nlHBoSaBoT5mEVI,695 +pygments/lexers/matlab.py,sha256=F9KO4qowIhfP8oVhCRRzE_1sqg4zmQbsB2NZH193PiM,133027 +pygments/lexers/maxima.py,sha256=a0h9Ggs9JEovTrzbJT-BLVbOqI29yPnaMZlkU5f_FeY,2715 +pygments/lexers/meson.py,sha256=BMrsDo6BH2lzTFw7JDwQ9SDNMTrRkXCNRDVf4aFHdsI,4336 +pygments/lexers/mime.py,sha256=yGrf3h37LK4b6ERBpFiL_qzn3JgOfGR5KLagnbWFl6c,7582 +pygments/lexers/minecraft.py,sha256=Nu88snDDPzM0D-742fFdUriczL-EE911pAd4_I4-pAw,13696 +pygments/lexers/mips.py,sha256=STKiZT67b3QERXXn7XKVxlPBu7vwbPC5EyCpuf3Jfbw,4656 +pygments/lexers/ml.py,sha256=t8sCv4BjvuBq6AihKKUwStEONIgdXCC2RMtO0RopNbM,35390 +pygments/lexers/modeling.py,sha256=M7B58bGB-Zwd1EmPxKqtRvg7TgNCyem3MVUHv0_H2SQ,13683 +pygments/lexers/modula2.py,sha256=NtpXBRoUCeHfflgB39LknSkCwhBHBKv2Er_pinjVsNE,53072 +pygments/lexers/mojo.py,sha256=8JRVoftN1E-W2woG0K-4n8PQXTUM9iY6Sl5sWb2uGNg,24233 +pygments/lexers/monte.py,sha256=baWU6zlXloenw9MO1MtEVGE9i3CfiXAYhqU621MIjRk,6289 +pygments/lexers/mosel.py,sha256=gjRdedhA1jTjoYoM1Gpaoog_I9o7TRbYMHk97N1TXwg,9297 +pygments/lexers/ncl.py,sha256=zJ6ahlitit4S0pBXc7Wu96PB7xOn59MwfR2HdY5_C60,63999 +pygments/lexers/nimrod.py,sha256=Q1NSqEkLC5wWt7xJyKC-vzWw_Iw2SfDNP_pyMFBuIfA,6413 +pygments/lexers/nit.py,sha256=p_hVD8GzMRl3CABVKHtYgnXFUQk0i5F2FbWFA6WXm6s,2725 +pygments/lexers/nix.py,sha256=NOrv20gdq-2A7eZ6c2gElPHv1Xx2pvv20-qOymL9GMg,4421 +pygments/lexers/numbair.py,sha256=fxkp2CXeXWKBMewfi1H4JSYkmm4kU58wZ2Sh9BDYAWQ,1758 +pygments/lexers/oberon.py,sha256=jw403qUUs7zpTHAs5CbLjb8qiuwtxLk0spDIYqGZwAw,4210 +pygments/lexers/objective.py,sha256=Fo1WB3JMj8sNeYnvB84H4_qwhOt4WNJtJWjVEOwrJGk,23297 +pygments/lexers/ooc.py,sha256=kD1XaJZaihDF_s-Vyu1Bx68S_9zFt2rhox7NF8LpOZM,3002 +pygments/lexers/openscad.py,sha256=h9I1k8kiuQmhX5vZm6VDSr2fa5Finy0sN8ZDIE-jx1c,3700 +pygments/lexers/other.py,sha256=WLVyqPsvm9oSXIbZwbfyJloS6HGgoFW5nVTaU1uQpTw,1763 +pygments/lexers/parasail.py,sha256=DWMGhtyQgGTXbIgQl_mID6CKqi-Dhbvs_dTkmvrZXfE,2719 +pygments/lexers/parsers.py,sha256=feNgxroPoWRf0NEsON2mtmKDUfslIQppukw6ndEsQ3M,26596 +pygments/lexers/pascal.py,sha256=N2tRAjlXnTxggAzzk2tOOAVzeC2MBzrXy97_HQl5n44,30989 +pygments/lexers/pawn.py,sha256=LWUYQYsebMMt2d5oxX1HYWvBqbakR1h7Av_z8Vw94Wg,8253 +pygments/lexers/pddl.py,sha256=Mk4_BzlROJCd0xR4KKRRSrbj0F7LLQcBRjmsmtWmrCg,2989 +pygments/lexers/perl.py,sha256=9BXn3tyHMA49NvzbM9E2czSCHjeU7bvaPLUcoZrhz-4,39192 +pygments/lexers/phix.py,sha256=hZqychqo5sFMBDESzDPXg1DYHQe_9sn294UfbjihaFk,23249 +pygments/lexers/php.py,sha256=l4hzQrlm0525i5dSw9Vmjcai3TzbPT6DkjzxPg9l6Zc,13061 +pygments/lexers/pointless.py,sha256=WSDjqQyGrNIGmTCdaMxl4zk7OZTlJAMzeUZ02kfgcTI,1974 +pygments/lexers/pony.py,sha256=EXrMkacqMZblI7v4AvBRQe-3Py8__bx5FOgjCLdfXxQ,3279 +pygments/lexers/praat.py,sha256=4UFK-nbC6WkZBhJgcQqEGqq9CocJkW7AmT_OJQbjWzk,12676 +pygments/lexers/procfile.py,sha256=05W2fyofLTP-FbEdSXD1eles-PPqVNfF6RWXjQdW2us,1155 +pygments/lexers/prolog.py,sha256=9Kc5YNUFqkfWu2sYoyzC3RX65abf1bm7oHr86z1s4kQ,12866 +pygments/lexers/promql.py,sha256=n-0vo-o8-ZasqP3Va4ujs562UfZSLfZF-RzT71yL0Tk,4738 +pygments/lexers/prql.py,sha256=PFReuvhbv4K5aeu6lvDfw4m-3hULkB3r43bKAy948os,8747 +pygments/lexers/ptx.py,sha256=KSHAvbiNVUntKilQ6EPYoLFocmJpRsBy_7fW6_Nrs1Y,4501 +pygments/lexers/python.py,sha256=WZe7fBAHKZ_BxPg8qIU26UGhk8qwUYyENJ3IyPW64mc,53805 +pygments/lexers/q.py,sha256=WQFUh3JrpK2j-VGW_Ytn3uJ5frUNmQIFnLtMVGRA9DI,6936 +pygments/lexers/qlik.py,sha256=2wqwdfIjrAz6RNBsP4MyeLX8Z7QpIGzxtf1CvaOlr_g,3693 +pygments/lexers/qvt.py,sha256=XMBnsWRrvCDf989OuDeb-KpszAkeETiACyaghZeL1ns,6103 +pygments/lexers/r.py,sha256=B6WgrD9SY1UTCV1fQBSlZbezPfpYsARn3FQIHcFYOiM,6474 +pygments/lexers/rdf.py,sha256=qUzxLna9v071bHhZAjdsBi8dKaJNk_h9g1ZRUAYCfoo,16056 +pygments/lexers/rebol.py,sha256=4u3N4kzui55HapopXDu3Kt0jczxDZ4buzwR7Mt4tQiM,18259 +pygments/lexers/rego.py,sha256=Rx5Gphbktr9ojg5DbqlyxHeQqqtF7g8W-oF0rmloDNY,1748 +pygments/lexers/resource.py,sha256=ioEzgWksB5HCjoz85XNkQPSd7n5kL0SZiuPkJP1hunQ,2927 +pygments/lexers/ride.py,sha256=kCWdxuR3PclVi4wiA0uUx4CYEFwuTqoMsKjhSW4X3yg,5035 +pygments/lexers/rita.py,sha256=Mj1QNxx1sWAZYC02kw8piVckaiw9B0MqQtiIiDFH0pA,1127 +pygments/lexers/rnc.py,sha256=g7ZD334PMGUqy_Ij64laSN1vJerwHqVkegfMCa3E-y8,1972 +pygments/lexers/roboconf.py,sha256=HbYuK5CqmQdd63SRY2nle01r7-p7mil0SnoauYDmEOY,2074 +pygments/lexers/robotframework.py,sha256=c4U1B9Q9ITBCTohqJTZOvkfyeVbenN4xhzSWIoZh5eU,18448 +pygments/lexers/ruby.py,sha256=uG617E5abBZcECRCqkhIfc-IbZcRb5cGuUZq_xpax90,22753 +pygments/lexers/rust.py,sha256=ZY-9vtsreBP0NfDd0WCouLSp_9MChAL8U8Abe-m9PB8,8260 +pygments/lexers/sas.py,sha256=C1Uz2s9DU6_s2kL-cB_PAGPtpyK5THlmhNmCumC1l48,9456 +pygments/lexers/savi.py,sha256=jrmruK0GnXktgBTWXW3oN3TXtofn3HBbkMlHnR84cko,4878 +pygments/lexers/scdoc.py,sha256=DXRmFDmYuc7h3gPAAVhfcL1OEbNBK5RdPpJqQzF3ZTk,2524 +pygments/lexers/scripting.py,sha256=jnJv_AFDyDrpzEPGNat5K6xzUBsEAiBr6N2_yLMt8LQ,81724 +pygments/lexers/sgf.py,sha256=w6C513ENaO2YCnqrduK7k03NaMDf-pgygvfzq2NaSRk,1985 +pygments/lexers/shell.py,sha256=dCS1zwkf5KwTog4__MnMC7h3Xmwv4_d3fnEV29tSwXI,36381 +pygments/lexers/sieve.py,sha256=eob-L84yf2jmhdNyYZUlbUJozdcd6GXcHW68lmAe8WE,2514 +pygments/lexers/slash.py,sha256=I-cRepmaxhL1SgYvD1hHX3gNBFI8NPszdU7hn1o5JlA,8484 +pygments/lexers/smalltalk.py,sha256=ue2PmqDK2sw0j75WdseiiENJBdZ1OwysH2Op1QN1r24,7204 +pygments/lexers/smithy.py,sha256=VREWoeuz7ANap_Uiopn7rs0Tnsfc-xBisDJKRGQY_y8,2659 +pygments/lexers/smv.py,sha256=He_VBSMbWONMWZmkrB5RYR0cfHVnMyKIXz68IFYl-a8,2805 +pygments/lexers/snobol.py,sha256=qDzb41xQQWMNmjB2MtZs23pFoFgZ2gbRZhK_Ir03r7I,2778 +pygments/lexers/solidity.py,sha256=Tixfnwku4Yezj6nNm8xVaw7EdV1qgAgdwahdTFP0St8,3163 +pygments/lexers/soong.py,sha256=Vm18vV4g6T8UPgjjY2yTRlSXGDpZowmuqQUBFfm4A9A,2339 +pygments/lexers/sophia.py,sha256=2YtYIT8iwAoW0B7TZuuoG_ZILhJV-2A7oBGat-98naE,3376 +pygments/lexers/special.py,sha256=8JuR2Vex8X-RWnC36S0HXTHWp2qmZclc90-TrLUWyaY,3585 +pygments/lexers/spice.py,sha256=m4nK0q4Sq_OFQez7kGWfki0No4ZV24YrONfHVj1Piqs,2790 +pygments/lexers/sql.py,sha256=2QvawM04xY96nvWadmHgHPDhOFbHGaFAQ_01rbNX_mc,48919 +pygments/lexers/srcinfo.py,sha256=B8vDs-sJogG3mWa5Hp_7JfHHUMyYRwGvKv6cKbFQXLM,1746 +pygments/lexers/stata.py,sha256=Zr9BC52D5O_3BbdW0N-tzoUmy0NTguL2sC-saXRVM-c,6415 +pygments/lexers/supercollider.py,sha256=_H5wDrn0DiGnlhB_cz6Rt_lo2TvqjSm0o6NPTd9R4Ko,3697 +pygments/lexers/tablegen.py,sha256=1JjedXYY18BNiY9JtNGLOtGfiwduNDZpQLBGTeQ6jAw,3987 +pygments/lexers/tact.py,sha256=X_lsxjFUMaC1TmYysXJq9tmAGifRnil83Bt1zA86Xdo,10809 +pygments/lexers/tal.py,sha256=xS9PlaWQOPj8MVr56fUNq31vUQKRWoLTlyWj9ZHm8AM,2904 +pygments/lexers/tcl.py,sha256=lK97ju4nikkt-oGOzIeyFEM98yq4dZSI8uEmYsq0R6c,5512 +pygments/lexers/teal.py,sha256=t3dqy_Arwv8_yExbX_xiFxv1TqJLPv4vh1MVKjKwS4Y,3522 +pygments/lexers/templates.py,sha256=BVdjYeoacIUuFyHTG39j4PxeNCe5E1oUURjH1rITrI4,75731 +pygments/lexers/teraterm.py,sha256=ciwztagW5Drg2gr17Qykrh6GwMsKy7e4xdQshX95GyQ,9718 +pygments/lexers/testing.py,sha256=YZgDgUEaLEYKSKEqpDsUi3Bn-Db_D42IlyiSsr1oX8U,10810 +pygments/lexers/text.py,sha256=nOCQPssIlKdVWU3PKxZiBPkf_KFM2V48IOssSyqhFY8,1068 +pygments/lexers/textedit.py,sha256=ttT4Ph-hIdgFLG6maRy_GskkziTFK0Wcg28yU0s6lek,7760 +pygments/lexers/textfmts.py,sha256=mi9KLEq4mrzDJbEc8G3VM-mSki_Tylkzodu47yH6z84,15524 +pygments/lexers/theorem.py,sha256=51ppBAEdhJmwU_lC916zMyjEoKLXqf89VAE_Lr0PNCc,17855 +pygments/lexers/thingsdb.py,sha256=x_fHNkLA-hIJyeIs6rg_X8n5OLYvFqaSu1FhI3apI5Y,6017 +pygments/lexers/tlb.py,sha256=ue2gqm45BI512lM13O8skAky9zAb7pLMrxZ8pbt5zRU,1450 +pygments/lexers/tls.py,sha256=_uQUVuMRDOhN-XUyGR5DIlVCk1CUZ1fIOSN4_WQYPKk,1540 +pygments/lexers/tnt.py,sha256=pK4LgoKON7u1xF66JYFncAPSbD8DZaeI_WTZ9HqEFlY,10456 +pygments/lexers/trafficscript.py,sha256=X3B8kgxS54ecuok9ic6Hkp-UMn5DvOmCK0p70Tz27Cw,1506 +pygments/lexers/typoscript.py,sha256=mBuePiVZUoAORPKsHwrx6fBWiy3fAIqG-2O67QmMiFI,8332 +pygments/lexers/typst.py,sha256=zIJBEhUXtWp5OiyAmvFA5m8d1EQG-ocwrJ677dvTUAk,7167 +pygments/lexers/ul4.py,sha256=rCaw0J9j3cdql9lX_HTilg65k9-9S118zOA6TAYfxaM,10499 +pygments/lexers/unicon.py,sha256=RAqoCnAAJBYOAGdR8ng0g6FtB39bGemLRlIqv5mcg9E,18625 +pygments/lexers/urbi.py,sha256=ajNP70NJg32jNnFDZsLvr_-4TToSGqRGkFyAPIJLfCU,6082 +pygments/lexers/usd.py,sha256=2eEGouolodYS402P_gtBrn4lLzpg1z8uHwPCKqjUb_k,3304 +pygments/lexers/varnish.py,sha256=dSh0Ku9SrjmlB29Fi_mWdWavN7M0cMKeepR4a34sOyI,7473 +pygments/lexers/verification.py,sha256=Qu433Q_h3EK3uS4bJoLRFZK0kIVwzX5AFKsa4Z-qnxA,3934 +pygments/lexers/verifpal.py,sha256=buyOOzCo_dGnoC40h0tthylHVVpgDt8qXu4olLvYy_4,2661 +pygments/lexers/vip.py,sha256=2lEV4cLV9p4E37wctBL7zkZ4ZU4p3HVsiLJFzB1bie0,5711 +pygments/lexers/vyper.py,sha256=Zq6sQIUBk6mBdpgOVgu3A6swGoBne0kDlRyjZznm2BY,5615 +pygments/lexers/web.py,sha256=4W9a7vcskrGJnxt4KmoE3SZydWB1qLq7lP2XS85J_m8,913 +pygments/lexers/webassembly.py,sha256=zgcMouzLawcbeFr6w_SOvGoUR68ZtqnnsbOcWEVleLk,5698 +pygments/lexers/webidl.py,sha256=ODtVmw4gVzI8HQWxuEckP6KMwm8WP2G2lSZEjagDXts,10516 +pygments/lexers/webmisc.py,sha256=-_-INDVdk47e2jlj-9bFcuLtntqVorBqIjlnwPfZFdI,40564 +pygments/lexers/wgsl.py,sha256=9igd9dzixGIgNewruv9mPnFms-c9BahkZcCCrZygv84,11880 +pygments/lexers/whiley.py,sha256=lMr750lA4MZsB4xqzVsIRtVMJIC3_dArhFYTHvOPwvA,4017 +pygments/lexers/wowtoc.py,sha256=8xxvf0xGeYtf4PE7KtkHZ_ly9xY_XXHrpCitdKE42Ro,4076 +pygments/lexers/wren.py,sha256=goGXnAMKKa13LLL40ybT3aMGPrk3gCRwZQFYAkKB_w0,3229 +pygments/lexers/x10.py,sha256=Q-AmgdF2E-N7mtOPpZ07CsxrTVnikyqC4uRRv6H75sk,1943 +pygments/lexers/xorg.py,sha256=9ttrBd3_Y2nXANsqtMposSgblYmMYqWXQ-Iz5RH9RsU,925 +pygments/lexers/yang.py,sha256=13CWbSaNr9giOHz4o0SXSklh0bfWt0ah14jJGpTvcn0,4499 +pygments/lexers/yara.py,sha256=jUSv78KTDfguCoAoAZKbYzQERkkyxBBWv5dInVrkDxo,2427 +pygments/lexers/zig.py,sha256=f-80MVOSp1KnczAMokQLVM-_wAEOD16EcGFnaCNlsN0,3976 +pygments/modeline.py,sha256=K5eSkR8GS1r5OkXXTHOcV0aM_6xpk9eWNEIAW-OOJ2g,1005 +pygments/plugin.py,sha256=tPx0rJCTIZ9ioRgLNYG4pifCbAwTRUZddvLw-NfAk2w,1891 +pygments/regexopt.py,sha256=wXaP9Gjp_hKAdnICqoDkRxAOQJSc4v3X6mcxx3z-TNs,3072 +pygments/scanner.py,sha256=nNcETRR1tRuiTaHmHSTTECVYFPcLf6mDZu1e4u91A9E,3092 +pygments/sphinxext.py,sha256=VEe_oHNgLoEGMHc2ROfbee2mF2PPREFyE6_m_JN5FvQ,7898 +pygments/style.py,sha256=Cpw9dCAyW3_JAwFRXOJXmtKb5ZwO2_5KSmlq6q4fZw4,6408 +pygments/styles/__init__.py,sha256=f9KCQXN4uKbe8aI8-L3qTC-_XPfT563FwTg6VTGVfwI,2006 +pygments/styles/__pycache__/__init__.cpython-312.pyc,, +pygments/styles/__pycache__/_mapping.cpython-312.pyc,, +pygments/styles/__pycache__/abap.cpython-312.pyc,, +pygments/styles/__pycache__/algol.cpython-312.pyc,, +pygments/styles/__pycache__/algol_nu.cpython-312.pyc,, +pygments/styles/__pycache__/arduino.cpython-312.pyc,, +pygments/styles/__pycache__/autumn.cpython-312.pyc,, +pygments/styles/__pycache__/borland.cpython-312.pyc,, +pygments/styles/__pycache__/bw.cpython-312.pyc,, +pygments/styles/__pycache__/coffee.cpython-312.pyc,, +pygments/styles/__pycache__/colorful.cpython-312.pyc,, +pygments/styles/__pycache__/default.cpython-312.pyc,, +pygments/styles/__pycache__/dracula.cpython-312.pyc,, +pygments/styles/__pycache__/emacs.cpython-312.pyc,, +pygments/styles/__pycache__/friendly.cpython-312.pyc,, +pygments/styles/__pycache__/friendly_grayscale.cpython-312.pyc,, +pygments/styles/__pycache__/fruity.cpython-312.pyc,, +pygments/styles/__pycache__/gh_dark.cpython-312.pyc,, +pygments/styles/__pycache__/gruvbox.cpython-312.pyc,, +pygments/styles/__pycache__/igor.cpython-312.pyc,, +pygments/styles/__pycache__/inkpot.cpython-312.pyc,, +pygments/styles/__pycache__/lightbulb.cpython-312.pyc,, +pygments/styles/__pycache__/lilypond.cpython-312.pyc,, +pygments/styles/__pycache__/lovelace.cpython-312.pyc,, +pygments/styles/__pycache__/manni.cpython-312.pyc,, +pygments/styles/__pycache__/material.cpython-312.pyc,, +pygments/styles/__pycache__/monokai.cpython-312.pyc,, +pygments/styles/__pycache__/murphy.cpython-312.pyc,, +pygments/styles/__pycache__/native.cpython-312.pyc,, +pygments/styles/__pycache__/nord.cpython-312.pyc,, +pygments/styles/__pycache__/onedark.cpython-312.pyc,, +pygments/styles/__pycache__/paraiso_dark.cpython-312.pyc,, +pygments/styles/__pycache__/paraiso_light.cpython-312.pyc,, +pygments/styles/__pycache__/pastie.cpython-312.pyc,, +pygments/styles/__pycache__/perldoc.cpython-312.pyc,, +pygments/styles/__pycache__/rainbow_dash.cpython-312.pyc,, +pygments/styles/__pycache__/rrt.cpython-312.pyc,, +pygments/styles/__pycache__/sas.cpython-312.pyc,, +pygments/styles/__pycache__/solarized.cpython-312.pyc,, +pygments/styles/__pycache__/staroffice.cpython-312.pyc,, +pygments/styles/__pycache__/stata_dark.cpython-312.pyc,, +pygments/styles/__pycache__/stata_light.cpython-312.pyc,, +pygments/styles/__pycache__/tango.cpython-312.pyc,, +pygments/styles/__pycache__/trac.cpython-312.pyc,, +pygments/styles/__pycache__/vim.cpython-312.pyc,, +pygments/styles/__pycache__/vs.cpython-312.pyc,, +pygments/styles/__pycache__/xcode.cpython-312.pyc,, +pygments/styles/__pycache__/zenburn.cpython-312.pyc,, +pygments/styles/_mapping.py,sha256=6lovFUE29tz6EsV3XYY4hgozJ7q1JL7cfO3UOlgnS8w,3312 +pygments/styles/abap.py,sha256=64Uwr8uPdEdcT-tE-Y2VveTXfH3SkqH9qdMgY49YHQI,749 +pygments/styles/algol.py,sha256=fCuk8ITTehvbJSufiaKlgnFsKbl-xFxxR82xhltc-cQ,2262 +pygments/styles/algol_nu.py,sha256=Gv9WfHJvYegGcUk1zcufQgsdXPNjCUNk8sAHyrSGGh4,2283 +pygments/styles/arduino.py,sha256=NoUB8xk7M1HGPoLfuySOLU0sVwoTuLcZqllXl2EO_iE,4557 +pygments/styles/autumn.py,sha256=fLLfjHXjxCl6crBAxEsBLH372ALMkFacA2bG6KFbJi4,2195 +pygments/styles/borland.py,sha256=_0ySKp4KGCSgtYjPe8uzD6gQhlmAIR4T43i-FoRYNOM,1611 +pygments/styles/bw.py,sha256=vhk8Xoj64fLPdA9IQU6mUVsYMel255jR-FDU7BjIHtI,1406 +pygments/styles/coffee.py,sha256=NqLt-fc7LONma1BGggbceVRY9uDE70WBuZXqK4zwaco,2308 +pygments/styles/colorful.py,sha256=mYcSbehtH7itH_QV9NqJp4Wna1X4lrwl2wkVXS2u-5A,2832 +pygments/styles/default.py,sha256=RTgG2zKWWUxPTDCFxhTnyZI_WZBIVgu5XsUpNvFisCA,2588 +pygments/styles/dracula.py,sha256=vRJmixBoSKV9o8NVQhXGViQqchhIYugfikLmvX0DoBw,2182 +pygments/styles/emacs.py,sha256=TiOG9oc83qToMCRMnJrXtWYqnzAqYycRz_50OoCKtxc,2535 +pygments/styles/friendly.py,sha256=oAi-l9anQTs9STDmUzXGDlOegatEOH4hpD0j6o6dZGM,2604 +pygments/styles/friendly_grayscale.py,sha256=a7Cqkzt6-uTiXvj6GoYBXzRvX5_zviCjjRB04Kf_-Q0,2828 +pygments/styles/fruity.py,sha256=GfSUTG0stlJr5Ow_saCaxbI2IB4-34Dp2TuRTpfUJBs,1324 +pygments/styles/gh_dark.py,sha256=ruNX3d4rf22rx-8HnwvGbNbXRQpXCNcHU1HNq6N4uNg,3590 +pygments/styles/gruvbox.py,sha256=KrFoHEoVnZW6XM9udyXncPomeGyZgIDsNWOH3kCrxFQ,3387 +pygments/styles/igor.py,sha256=fYYPhM0dRCvcDTMVrMVO5oFKnYm-8YVlsuVBoczFLtY,737 +pygments/styles/inkpot.py,sha256=jggSeX9NV15eOL2oJaVmZ6vmV7LWRzXJQRUqcWEqGRs,2404 +pygments/styles/lightbulb.py,sha256=Y8u1qdvlHfBqI2jJex55SkvVatVo_FjEUzE6h-X7m-0,3172 +pygments/styles/lilypond.py,sha256=Y6fp_sEL-zESmxAaMxzjtrKk90cuDC_DalNdC8wj0nw,2066 +pygments/styles/lovelace.py,sha256=cA9uhmbnzY04MccsiYSgMY7fvb4WMRbegWBUrGvXh1M,3178 +pygments/styles/manni.py,sha256=g9FyO7plTwfMm2cU4iiKgdlkMlvQLG6l2Lwkgz5ITS4,2443 +pygments/styles/material.py,sha256=LDmgomAbgtJDZhbv446_zIwgYh50UAqEEtgYNUns1rQ,4201 +pygments/styles/monokai.py,sha256=lrxTJpkBarV9gTLkBQryZ6oNSjekAVheJueKJP5iEYA,5184 +pygments/styles/murphy.py,sha256=-AKZiLkpiWej-otjHMsYCE-I-_IzCOLJY-_GBdKRZRw,2805 +pygments/styles/native.py,sha256=l6tezGSQTB8p_SyOXJ0PWI7KzCeEdtsPmVc4Yn4_CwU,2043 +pygments/styles/nord.py,sha256=GDt3WAaqaWsiCeqpIBPxd8TEUX708fGfwaA7S0w0oy0,5391 +pygments/styles/onedark.py,sha256=k80cZEppCEF-HLoxy_FEA0QmQDZze68nHVMNGyUVa28,1719 +pygments/styles/paraiso_dark.py,sha256=Jkrg4nUKIVNF8U4fPNV_Smq_g9NFbb9eiUrjYpVgQZg,5662 +pygments/styles/paraiso_light.py,sha256=MxN964ZEpze3wF0ss-igaa2I7E684MHe-Zq0rWPH3wo,5668 +pygments/styles/pastie.py,sha256=ZvAs9UpBNYFC-5PFrCRGYnm3FoPKb-eKR-ozbWZP-4g,2525 +pygments/styles/perldoc.py,sha256=HSxB93e4UpQkZspReQ34FeJbZ-59ksGvdaH-hToehi8,2230 +pygments/styles/rainbow_dash.py,sha256=4ugL18Or7aNtaLfPfCLFRiFy0Gu2RA4a9G2LQUE9SrM,2390 +pygments/styles/rrt.py,sha256=fgzfpC0PC_SCcLOMCNEIQTjPUMOncRe7SR10GfSRbXY,1006 +pygments/styles/sas.py,sha256=yzoXmbfQ2ND1WWq93b4vVGYkQSZHPqb4ymes9YYRT3w,1440 +pygments/styles/solarized.py,sha256=qupILFZn02WspnAF5SPYb-W8guo9xnUtjb1HeLw3XgE,4247 +pygments/styles/staroffice.py,sha256=CLbBeMoxay21Xyu3Af2p4xUXyG1_6ydCbvs5RJKYe5w,831 +pygments/styles/stata_dark.py,sha256=vX8SwHV__sG92F4CKribG08MJfSVq98dgs7gEA_n9yc,1257 +pygments/styles/stata_light.py,sha256=uV3GE-ylvffQ0yN3py1YAVqBB5wflIKZbceyK1Lqvrc,1289 +pygments/styles/tango.py,sha256=O2wcM4hHuU1Yt071M9CK7JPtiiSCqyxtT9tbiQICV28,7137 +pygments/styles/trac.py,sha256=9kMv1ZZyMKACWlx2fQVjRP0I2pgcRYCNrd7iGGZg9qk,1981 +pygments/styles/vim.py,sha256=J7_TqvrGkTX_XuTHW0In5wqPLAUPRWyr1122XueZWmM,2019 +pygments/styles/vs.py,sha256=s7YnzbIPuFU3LIke27mc4lAQSn2R3vbbHc1baMGSU_U,1130 +pygments/styles/xcode.py,sha256=PbQdzgGaA4a9LAU1i58alY9kM4IFlQX5jHQwOYmf_Rk,1504 +pygments/styles/zenburn.py,sha256=suZEKzBTCYdhf2cxNwcY7UATJK1tq5eYhGdBcXdf6MU,2203 +pygments/token.py,sha256=WbdWGhYm_Vosb0DDxW9lHNPgITXfWTsQmHt6cy9RbcM,6226 +pygments/unistring.py,sha256=al-_rBemRuGvinsrM6atNsHTmJ6DUbw24q2O2Ru1cBc,63208 +pygments/util.py,sha256=oRtSpiAo5jM9ulntkvVbgXUdiAW57jnuYGB7t9fYuhc,10031 diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/WHEEL b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/WHEEL new file mode 100644 index 0000000..12228d4 --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.27.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/entry_points.txt b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/entry_points.txt new file mode 100644 index 0000000..15498e3 --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +pygmentize = pygments.cmdline:main diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS new file mode 100644 index 0000000..811c66a --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/AUTHORS @@ -0,0 +1,291 @@ +Pygments is written and maintained by Georg Brandl . + +Major developers are Tim Hatch and Armin Ronacher +. + +Other contributors, listed alphabetically, are: + +* Sam Aaron -- Ioke lexer +* Jean Abou Samra -- LilyPond lexer +* João Abecasis -- JSLT lexer +* Ali Afshar -- image formatter +* Thomas Aglassinger -- Easytrieve, JCL, Rexx, Transact-SQL and VBScript + lexers +* Maxence Ahlouche -- PostgreSQL Explain lexer +* Muthiah Annamalai -- Ezhil lexer +* Nikolay Antipov -- OpenSCAD lexer +* Kumar Appaiah -- Debian control lexer +* Andreas Amann -- AppleScript lexer +* Timothy Armstrong -- Dart lexer fixes +* Jeffrey Arnold -- R/S, Rd, BUGS, Jags, and Stan lexers +* Eiríkr Åsheim -- Uxntal lexer +* Jeremy Ashkenas -- CoffeeScript lexer +* José Joaquín Atria -- Praat lexer +* Stefan Matthias Aust -- Smalltalk lexer +* Lucas Bajolet -- Nit lexer +* Ben Bangert -- Mako lexers +* Max Battcher -- Darcs patch lexer +* Thomas Baruchel -- APL lexer +* Tim Baumann -- (Literate) Agda lexer +* Paul Baumgart, 280 North, Inc. -- Objective-J lexer +* Michael Bayer -- Myghty lexers +* Thomas Beale -- Archetype lexers +* John Benediktsson -- Factor lexer +* David Benjamin, Google LLC -- TLS lexer +* Trevor Bergeron -- mIRC formatter +* Vincent Bernat -- LessCSS lexer +* Christopher Bertels -- Fancy lexer +* Sébastien Bigaret -- QVT Operational lexer +* Jarrett Billingsley -- MiniD lexer +* Adam Blinkinsop -- Haskell, Redcode lexers +* Stéphane Blondon -- Procfile, SGF and Sieve lexers +* Frits van Bommel -- assembler lexers +* Pierre Bourdon -- bugfixes +* Martijn Braam -- Kernel log lexer, BARE lexer +* JD Browne, Google LLC -- GoogleSQL lexer +* Matthias Bussonnier -- ANSI style handling for terminal-256 formatter +* chebee7i -- Python traceback lexer improvements +* Hiram Chirino -- Scaml and Jade lexers +* Mauricio Caceres -- SAS and Stata lexers. +* Michael Camilleri, John Gabriele, sogaiu -- Janet lexer +* Daren Chandisingh -- Gleam lexer +* Ian Cooper -- VGL lexer +* David Corbett -- Inform, Jasmin, JSGF, Snowball, and TADS 3 lexers +* Leaf Corcoran -- MoonScript lexer +* Fraser Cormack -- TableGen lexer +* Gabriel Corona -- ASN.1 lexer +* Christopher Creutzig -- MuPAD lexer +* Daniël W. Crompton -- Pike lexer +* Pete Curry -- bugfixes +* Bryan Davis -- EBNF lexer +* Bruno Deferrari -- Shen lexer +* Walter Dörwald -- UL4 lexer +* Luke Drummond -- Meson lexer +* Giedrius Dubinskas -- HTML formatter improvements +* Owen Durni -- Haxe lexer +* Alexander Dutton, Oxford University Computing Services -- SPARQL lexer +* James Edwards -- Terraform lexer +* Nick Efford -- Python 3 lexer +* Sven Efftinge -- Xtend lexer +* Artem Egorkine -- terminal256 formatter +* Matthew Fernandez -- CAmkES lexer +* Paweł Fertyk -- GDScript lexer, HTML formatter improvements +* Michael Ficarra -- CPSA lexer +* James H. Fisher -- PostScript lexer +* Amanda Fitch, Google LLC -- GoogleSQL lexer +* William S. Fulton -- SWIG lexer +* Carlos Galdino -- Elixir and Elixir Console lexers +* Michael Galloy -- IDL lexer +* Naveen Garg -- Autohotkey lexer +* Simon Garnotel -- FreeFem++ lexer +* Laurent Gautier -- R/S lexer +* Alex Gaynor -- PyPy log lexer +* Richard Gerkin -- Igor Pro lexer +* Alain Gilbert -- TypeScript lexer +* Alex Gilding -- BlitzBasic lexer +* GitHub, Inc -- DASM16, Augeas, TOML, and Slash lexers +* Bertrand Goetzmann -- Groovy lexer +* Krzysiek Goj -- Scala lexer +* Rostyslav Golda -- FloScript lexer +* Andrey Golovizin -- BibTeX lexers +* Matt Good -- Genshi, Cheetah lexers +* Michał Górny -- vim modeline support +* Alex Gosse -- TrafficScript lexer +* Patrick Gotthardt -- PHP namespaces support +* Hubert Gruniaux -- C and C++ lexer improvements +* Olivier Guibe -- Asymptote lexer +* Phil Hagelberg -- Fennel lexer +* Florian Hahn -- Boogie lexer +* Martin Harriman -- SNOBOL lexer +* Matthew Harrison -- SVG formatter +* Steven Hazel -- Tcl lexer +* Dan Michael Heggø -- Turtle lexer +* Aslak Hellesøy -- Gherkin lexer +* Greg Hendershott -- Racket lexer +* Justin Hendrick -- ParaSail lexer +* Jordi Gutiérrez Hermoso -- Octave lexer +* David Hess, Fish Software, Inc. -- Objective-J lexer +* Ken Hilton -- Typographic Number Theory and Arrow lexers +* Varun Hiremath -- Debian control lexer +* Rob Hoelz -- Perl 6 lexer +* Doug Hogan -- Mscgen lexer +* Ben Hollis -- Mason lexer +* Max Horn -- GAP lexer +* Fred Hornsey -- OMG IDL Lexer +* Alastair Houghton -- Lexer inheritance facility +* Tim Howard -- BlitzMax lexer +* Dustin Howett -- Logos lexer +* Ivan Inozemtsev -- Fantom lexer +* Hiroaki Itoh -- Shell console rewrite, Lexers for PowerShell session, + MSDOS session, BC, WDiff +* Brian R. Jackson -- Tea lexer +* Christian Jann -- ShellSession lexer +* Jonas Camillus Jeppesen -- Line numbers and line highlighting for + RTF-formatter +* Dennis Kaarsemaker -- sources.list lexer +* Dmitri Kabak -- Inferno Limbo lexer +* Igor Kalnitsky -- vhdl lexer +* Colin Kennedy - USD lexer +* Alexander Kit -- MaskJS lexer +* Pekka Klärck -- Robot Framework lexer +* Gerwin Klein -- Isabelle lexer +* Eric Knibbe -- Lasso lexer +* Stepan Koltsov -- Clay lexer +* Oliver Kopp - Friendly grayscale style +* Adam Koprowski -- Opa lexer +* Benjamin Kowarsch -- Modula-2 lexer +* Domen Kožar -- Nix lexer +* Oleh Krekel -- Emacs Lisp lexer +* Alexander Kriegisch -- Kconfig and AspectJ lexers +* Marek Kubica -- Scheme lexer +* Jochen Kupperschmidt -- Markdown processor +* Gerd Kurzbach -- Modelica lexer +* Jon Larimer, Google Inc. -- Smali lexer +* Olov Lassus -- Dart lexer +* Matt Layman -- TAP lexer +* Dan Lazin, Google LLC -- GoogleSQL lexer +* Kristian Lyngstøl -- Varnish lexers +* Sylvestre Ledru -- Scilab lexer +* Chee Sing Lee -- Flatline lexer +* Mark Lee -- Vala lexer +* Thomas Linder Puls -- Visual Prolog lexer +* Pete Lomax -- Phix lexer +* Valentin Lorentz -- C++ lexer improvements +* Ben Mabey -- Gherkin lexer +* Angus MacArthur -- QML lexer +* Louis Mandel -- X10 lexer +* Louis Marchand -- Eiffel lexer +* Simone Margaritelli -- Hybris lexer +* Tim Martin - World of Warcraft TOC lexer +* Kirk McDonald -- D lexer +* Gordon McGregor -- SystemVerilog lexer +* Stephen McKamey -- Duel/JBST lexer +* Brian McKenna -- F# lexer +* Charles McLaughlin -- Puppet lexer +* Kurt McKee -- Tera Term macro lexer, PostgreSQL updates, MySQL overhaul, JSON lexer +* Joe Eli McIlvain -- Savi lexer +* Lukas Meuser -- BBCode formatter, Lua lexer +* Cat Miller -- Pig lexer +* Paul Miller -- LiveScript lexer +* Hong Minhee -- HTTP lexer +* Michael Mior -- Awk lexer +* Bruce Mitchener -- Dylan lexer rewrite +* Reuben Morais -- SourcePawn lexer +* Jon Morton -- Rust lexer +* Paulo Moura -- Logtalk lexer +* Mher Movsisyan -- DTD lexer +* Dejan Muhamedagic -- Crmsh lexer +* Adrien Nayrat -- PostgreSQL Explain lexer +* Ana Nelson -- Ragel, ANTLR, R console lexers +* David Neto, Google LLC -- WebGPU Shading Language lexer +* Kurt Neufeld -- Markdown lexer +* Nam T. Nguyen -- Monokai style +* Jesper Noehr -- HTML formatter "anchorlinenos" +* Mike Nolta -- Julia lexer +* Avery Nortonsmith -- Pointless lexer +* Jonas Obrist -- BBCode lexer +* Edward O'Callaghan -- Cryptol lexer +* David Oliva -- Rebol lexer +* Pat Pannuto -- nesC lexer +* Jon Parise -- Protocol buffers and Thrift lexers +* Benjamin Peterson -- Test suite refactoring +* Ronny Pfannschmidt -- BBCode lexer +* Dominik Picheta -- Nimrod lexer +* Andrew Pinkham -- RTF Formatter Refactoring +* Clément Prévost -- UrbiScript lexer +* Tanner Prynn -- cmdline -x option and loading lexers from files +* Oleh Prypin -- Crystal lexer (based on Ruby lexer) +* Nick Psaris -- K and Q lexers +* Xidorn Quan -- Web IDL lexer +* Elias Rabel -- Fortran fixed form lexer +* raichoo -- Idris lexer +* Daniel Ramirez -- GDScript lexer +* Kashif Rasul -- CUDA lexer +* Nathan Reed -- HLSL lexer +* Justin Reidy -- MXML lexer +* Jonathon Reinhart, Google LLC -- Soong lexer +* Norman Richards -- JSON lexer +* Corey Richardson -- Rust lexer updates +* Fabrizio Riguzzi -- cplint leder +* Lubomir Rintel -- GoodData MAQL and CL lexers +* Andre Roberge -- Tango style +* Georg Rollinger -- HSAIL lexer +* Michiel Roos -- TypoScript lexer +* Konrad Rudolph -- LaTeX formatter enhancements +* Mario Ruggier -- Evoque lexers +* Miikka Salminen -- Lovelace style, Hexdump lexer, lexer enhancements +* Stou Sandalski -- NumPy, FORTRAN, tcsh and XSLT lexers +* Matteo Sasso -- Common Lisp lexer +* Joe Schafer -- Ada lexer +* Max Schillinger -- TiddlyWiki5 lexer +* Andrew Schmidt -- X++ lexer +* Ken Schutte -- Matlab lexers +* René Schwaiger -- Rainbow Dash style +* Sebastian Schweizer -- Whiley lexer +* Tassilo Schweyer -- Io, MOOCode lexers +* Pablo Seminario -- PromQL lexer +* Ted Shaw -- AutoIt lexer +* Joerg Sieker -- ABAP lexer +* Robert Simmons -- Standard ML lexer +* Kirill Simonov -- YAML lexer +* Corbin Simpson -- Monte lexer +* Ville Skyttä -- ASCII armored lexer +* Alexander Smishlajev -- Visual FoxPro lexer +* Steve Spigarelli -- XQuery lexer +* Jerome St-Louis -- eC lexer +* Camil Staps -- Clean and NuSMV lexers; Solarized style +* James Strachan -- Kotlin lexer +* Tom Stuart -- Treetop lexer +* Colin Sullivan -- SuperCollider lexer +* Ben Swift -- Extempore lexer +* tatt61880 -- Kuin lexer +* Edoardo Tenani -- Arduino lexer +* Tiberius Teng -- default style overhaul +* Jeremy Thurgood -- Erlang, Squid config lexers +* Brian Tiffin -- OpenCOBOL lexer +* Bob Tolbert -- Hy lexer +* Doug Torrance -- Macaulay2 lexer +* Matthias Trute -- Forth lexer +* Tuoa Spi T4 -- Bdd lexer +* Erick Tryzelaar -- Felix lexer +* Alexander Udalov -- Kotlin lexer improvements +* Thomas Van Doren -- Chapel lexer +* Dave Van Ee -- Uxntal lexer updates +* Daniele Varrazzo -- PostgreSQL lexers +* Abe Voelker -- OpenEdge ABL lexer +* Pepijn de Vos -- HTML formatter CTags support +* Matthias Vallentin -- Bro lexer +* Benoît Vinot -- AMPL lexer +* Linh Vu Hong -- RSL lexer +* Taavi Väänänen -- Debian control lexer +* Immanuel Washington -- Smithy lexer +* Nathan Weizenbaum -- Haml and Sass lexers +* Nathan Whetsell -- Csound lexers +* Dietmar Winkler -- Modelica lexer +* Nils Winter -- Smalltalk lexer +* Davy Wybiral -- Clojure lexer +* Whitney Young -- ObjectiveC lexer +* Diego Zamboni -- CFengine3 lexer +* Enrique Zamudio -- Ceylon lexer +* Alex Zimin -- Nemerle lexer +* Rob Zimmerman -- Kal lexer +* Evgenii Zheltonozhskii -- Maple lexer +* Vincent Zurczak -- Roboconf lexer +* Hubert Gruniaux -- C and C++ lexer improvements +* Thomas Symalla -- AMDGPU Lexer +* 15b3 -- Image Formatter improvements +* Fabian Neumann -- CDDL lexer +* Thomas Duboucher -- CDDL lexer +* Philipp Imhof -- Pango Markup formatter +* Thomas Voss -- Sed lexer +* Martin Fischer -- WCAG contrast testing +* Marc Auberer -- Spice lexer +* Amr Hesham -- Carbon lexer +* diskdance -- Wikitext lexer +* vanillajonathan -- PRQL lexer +* Nikolay Antipov -- OpenSCAD lexer +* Markus Meyer, Nextron Systems -- YARA lexer +* Hannes Römer -- Mojo lexer +* Jan Frederik Schaefer -- PDDL lexer + +Many thanks for all contributions! diff --git a/.venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE new file mode 100644 index 0000000..446a1a8 --- /dev/null +++ b/.venv/Lib/site-packages/pygments-2.19.1.dist-info/licenses/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2006-2022 by the respective authors (see AUTHORS file). +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/pygments/__init__.py b/.venv/Lib/site-packages/pygments/__init__.py new file mode 100644 index 0000000..d33a156 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/__init__.py @@ -0,0 +1,82 @@ +""" + Pygments + ~~~~~~~~ + + Pygments is a syntax highlighting package written in Python. + + It is a generic syntax highlighter for general use in all kinds of software + such as forum systems, wikis or other applications that need to prettify + source code. Highlights are: + + * a wide range of common languages and markup formats is supported + * special attention is paid to details, increasing quality by a fair amount + * support for new languages and formats are added easily + * a number of output formats, presently HTML, LaTeX, RTF, SVG, all image + formats that PIL supports, and ANSI sequences + * it is usable as a command-line tool and as a library + * ... and it highlights even Brainfuck! + + The `Pygments master branch`_ is installable with ``easy_install Pygments==dev``. + + .. _Pygments master branch: + https://github.com/pygments/pygments/archive/master.zip#egg=Pygments-dev + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" +from io import StringIO, BytesIO + +__version__ = '2.19.1' +__docformat__ = 'restructuredtext' + +__all__ = ['lex', 'format', 'highlight'] + + +def lex(code, lexer): + """ + Lex `code` with the `lexer` (must be a `Lexer` instance) + and return an iterable of tokens. Currently, this only calls + `lexer.get_tokens()`. + """ + try: + return lexer.get_tokens(code) + except TypeError: + # Heuristic to catch a common mistake. + from pygments.lexer import RegexLexer + if isinstance(lexer, type) and issubclass(lexer, RegexLexer): + raise TypeError('lex() argument must be a lexer instance, ' + 'not a class') + raise + + +def format(tokens, formatter, outfile=None): # pylint: disable=redefined-builtin + """ + Format ``tokens`` (an iterable of tokens) with the formatter ``formatter`` + (a `Formatter` instance). + + If ``outfile`` is given and a valid file object (an object with a + ``write`` method), the result will be written to it, otherwise it + is returned as a string. + """ + try: + if not outfile: + realoutfile = getattr(formatter, 'encoding', None) and BytesIO() or StringIO() + formatter.format(tokens, realoutfile) + return realoutfile.getvalue() + else: + formatter.format(tokens, outfile) + except TypeError: + # Heuristic to catch a common mistake. + from pygments.formatter import Formatter + if isinstance(formatter, type) and issubclass(formatter, Formatter): + raise TypeError('format() argument must be a formatter instance, ' + 'not a class') + raise + + +def highlight(code, lexer, formatter, outfile=None): + """ + This is the most high-level highlighting function. It combines `lex` and + `format` in one function. + """ + return format(lex(code, lexer), formatter, outfile) diff --git a/.venv/Lib/site-packages/pygments/__main__.py b/.venv/Lib/site-packages/pygments/__main__.py new file mode 100644 index 0000000..4890a6c --- /dev/null +++ b/.venv/Lib/site-packages/pygments/__main__.py @@ -0,0 +1,17 @@ +""" + pygments.__main__ + ~~~~~~~~~~~~~~~~~ + + Main entry point for ``python -m pygments``. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import sys +import pygments.cmdline + +try: + sys.exit(pygments.cmdline.main(sys.argv)) +except KeyboardInterrupt: + sys.exit(1) diff --git a/.venv/Lib/site-packages/pygments/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a7301deb45f6d0b0c8b3ddeb962081a248ac114 GIT binary patch literal 3478 zcmaJ@O>7&-72YK&i6ZsmO16tAu06Kv*t8|e7TnrVV*~QP5XBZuB~4iY!NHt?=ju=1sQ)x?7=NXgu~Sf0mLT;Gu_SY|R^0ZnOjtgmgg183Xaqj<@E#&?EcPANu*6E(B&Qmdk`%EFo6SHd?&yP#Guh;}ivTUk z68S}onwG1ba=5Zw4`H~zEx08qvG0YJ=c*Q4YQcqN%SBL)AoNvYFSf6f=kv9%`I9(; zK$zt?2%W5Yanux(A2ybdC&Uwksu`-p^>Ip&goj>>U0Zl-Zk)|o3;f-2c5~s%I4iw# zbzFZNw}H^LCoI_+r+I#ME(smsP-#C5B(jH%rdSm28 z{he=PC#pqOd+?ve|ISBf?iu~Yrg_Um_iN9l@t{3gG7cN6W8vF|n1sfW=0Wdnr%Xfj zCtEj7rInN3AGCLfZ>quW{AQ{%o>%0Bew=i2)?M?iv1Y8Ne_*Vch0Mk;b<*beI;)aE zRG|Yv2qn6TNV%x8V~tQMwgd#TD%R1EMh<{p(3=Uu(3?;|(Li{>PeTo?Q^5*8MUh<$ zh0tsphhlYg$}}AQ%DXtd__pLiE|#pu;w3IuRM1>3k+{x_;1;))T)YB~&dkrU zRmrZvxs}ChxL!coOTn#Ru?UW@F3!12ixR1vXx}_?F>!OU0^+)=QYnHhy*O1jhtZKY z(cCef4`h3Wo(%7PJbd8M@PYf8t>GgNvq%2*G{5@`qqk@1Z`p~b`8^--j~2G`hd$o; z^vGvp+ea@w9eMS+VSelQj$w|TKyUEGv+UsWL9G8u68P@!8Z~}?b|#;`Zd0Vm(?R+a zkgSoOl2=s+>zgK__(6Nex+!wNa%ca8wv}~L(m2`DPcnWx4c_!6qut+4V>6v#+(iFY zhaKHDiH#C*@8vc+JTZ+{3jFKvs?EQ&lks{ReYZ34?Hh?@@NXpPCq96Gdy=tDb2HN! z&nwh6@#FNolz+X}J|s&+{ffR-q0KP`svzD=*;MEgi1y0r=(nMffM{E_BvcqVO1xtik?Mu6>1;WyYRI5}Fk%0zBHRKeC z->4$E3_S%uQQtr}lA;N9iL1ur+GWk95-7grad<2rxWM&Q2+@Ti#|jW-aiazf-mfQO z(BFw`<9l(~FPDQ(O8$o=i+hX?GtbQKP@2e z-<`?M>^FXwAE9>t*$aEqHsvpQNRud)J15cHGrDTfWj+{eCM?-Zfz54AC_(Etni^UQ zbWh-q@YD!!0nt@E;h_TZx)l*skjtTOQ>9sCD8f;KETOcL`tqt0nq!>CpMz+CyN7r8 z=-EOlPCYqZ$Oz)Ppg6^=)a*keDZcK9%F;MBZ_(TsnmfjqIb&et7l%J^KD@j&a_Ii- zCu>{zGY>Oob});mt`~AqU!~#%cBK-f+#m)UnT_(5$|~*)gn+3*y(V@Suh@cHvQmkK zUIT>A{k0(u;77wI%D&MEoY3Rv#cLQN?UfT~o~KRI{732)GxN{WhI#PW(B3=wC%X>a d8T?D`*qy#FdWX!RokM%gp)aR;%(L3uzX7os$NvBT literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/__main__.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/__main__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2489b185b9a4e46f7a70090f0b9ca4a1ee84a0ef GIT binary patch literal 797 zcmZ`$&1(}u6rb5$NgCaff>J>XL-kT<))1+bP=uJYCbZUStk|%y+3b$VCi}(AH0^p2 zy{HHA>Qzr7{trUWo=TCH_1IHy)m)?}XSdzP5BweGz4v?HZ@$QK25{VdGuKfe0Q-@V z;LM3K_{^2Jzyu9oLQ}9|1IAKlh$BD%7kN(Sk;?qP( zBm{wQ1>p2mKrX=lb~VLe{2I^L0Gr|(*nm^glbsCW@PoF4T}Bm6b9Bqqw3vPRH!?AO zheseDO#jeds+H%L>+|slCT6;2Qzdf{ zU1<3rI@Q!jn9?-UGc+v}X+Xp5>8gff+LnvMbi#xZ-n3YlN*q#jicr!?yC04%;-KZ} z#H_gt6SD5Jk6;kBIkL+|b(La5)w=Ge6-;}~^VPa#@_mTc#RjA5f=*d!rH1+xE!aBk zsa4(RVS*}N*He`~cKhm*)l#X&aL(s0y^X1wjCC#f6U7h0^qk|F>o&egvb=e;A$`c7 zLlHvwT}VS|a2~+3-@y2xB*N^TbnaRCW%YUW)uUZ`Vq2crl_$65$#>U3%)X!9k*B{( nxu1Kfi$4JTJ@(#<#i(BPh>r2nuV+dE*b>G|m&L71kiWkG+l$f% literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/cmdline.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/cmdline.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aea84594699a3b5b40a7ed7908dbc729533a6ae4 GIT binary patch literal 26478 zcmd^nS#TRimS7bQ0w7KTAPL^Zo1jSOqz>vb#Y-opwj>|4JT!y?NkBO0Do_+*z^2{a zFyzs+$hLb(O}j(%w0BL7HEVXn#I!oLW7|D55!(?Hu|t@Y370w3a<_ZBJ;w%ZYr<|j zVt3!mLKQ#?k~Owxf3_r6B{E;WeEIU_%j3Pwzcm{3DR_FnvuAkqF^c*%{*WGZI`GLb zO;OVnOZ8JM%_;(PKTW=heg*j|`<3LY>Q}*68BhoF`txXnRRuIbZNE0C>(`Or>Og)_ z->(lE`VB#2zcFa)HwDf8=AfnD5-jL1ATW6WYtYtj3)=hb!NUH+U{QZju(-cC=;(Kl zbWNZnSlVAo!rDMtu)M!KSkYfWe(M62!K(hMAk)tTtNW{iHT^Zg+WuOSmLI4K*7w(w zus+ZbZ0v6gHuX1=--duQ*xcV7+|a*){5A$!g020nL07*Eew&`B`Zuy>cyD4Y@ZQW8 zzSLHHm|}T$iz#bL7FXkp6=fI1?H6GAGi-F%hpj*uwB$FVk`Q)WPEqo^+8i+5ED#Js zqh6jLV7;C&>lI3~e+>+B;otyNJ?IO$144lm8t{ey7_bOMr$e4Vn1|pg?}f;r;}3K0 zkr6NF%o9vQ-pGJE5Euw}F94xJ0sbc8fwSWSA$QO#=*6-~q+kz(-E10w6g%h(c!i=& zF5t)j#*wTQgT9ai?ZNsEWG4fsbV$!pEEr>M9hrtoLyNoRf|{pIOPc7RCt*K{QLu=E@0 zd~sz=3D}MSHdRb@FKls@jsl2W*c7bt4TXsR41DA2cwS6>Ph9F)-aXUvVtFw-rrrZc zFCAA=moBI%ta&XJQAzcvqc|;SG!?+95bjax5<5m+P(DhH(N1-rK(`3=-Vd>wr<_Vb zjs0%~J|h8NM96>09T@eJ&Iw&NFFXLLyr2q?M0i0>eqp4W8zMj9i?QdtX)JU422yY)k0hD=1E=Q)c_+r!GEqDV{ReQw2rSWm9D{ zCl?E<6M63ymLpZ&-%fyk-ZtEy}<;N6ltW8zcAka(t zRVDoToVNmgs_5z)kHz-P+1~eh3GMXZg8~#WL5$qlxaxwv@qkx$k1%O!sU1 z=G*2Q7i-%W%68v0?71by&u*E4-;Jw!Y*hnguub%R0>x0CbU(*1g#?n8%7fTx3iJca zl+HC#6xSJ%^-@gcX$8 z1_oflH88-H!Y{50qf8wU(En#gBcjshKt?G+$&d3w9v@-790x;$YHZjY;W|l*C&2TF zOYVI70a6Ui-vT4tVMswZ{*L7J$5_{r)56n8qjCN@hY;DC@3R|yA9Vqjo617*b(aZvYh zHLLQ=svT%gKQS2-tByikOc7IEpt)k0O61)ohf1Od;aLs7FVMUKa%cyYFx8>`vT8~f zf_U?!Trhx;fx)lKq)H))dK#uTPy-OyxF*931$0C|S=37K;y0%G4wZ$yTt$r|fAfiI z`MXU14E9VMtIy=jiZx_n34dkvB;f$+Mu0kP#4OPg(@J^by1Q^r>z5Ucl#7xnPxD_F z)B0sqlYxRZ0kw43Hp!VsqUS5O6Ndx%e|S3?NjrHm+?RN~M&eCUZPvt^vtkP+Zb|u} zjoP4%@*~AkN-ST3hnCCqF-t6;@QCyP31Uq-1-aV!`_vDzdgrAbX}PoBSAA?b%aMB{ zlwKlHeMf!Dq?G^o`ixUfdmpzK3XE#Vl9g|dYSLR3QAG>GZN(&g6OKbT~24B_i za_YH*@DWtL&|p~54vq!_;vAGzPEf&mo)_o=K^Ykx5ojNG2!WL_zLJrW*TYYwHvNb* zRcWvc_+VXi1|S}WKfW2pbC{-T^og&Y{k>NrgqJoUbNNDb|!6&a}J1l+tx92Y_99gL)Q+?vu_+vmhZmdNtSoK zZR>sOL0D_p4$+CuTL#PJBNva%C~q3dS2dJ#7c5$I#>={kx=XM+Dok|1ptxXdS+LbD zTU(OWmO1x=b<<75=8u$=wP-bu$~R4xy{#*kX$>xE@kau`BCWRicWjL?SX=96Pm)nz zBKG9f$F4lKXmid1!5imo^PV3Ee-wlj(T)Rj%EruYdwtidyXH>5`S`WR7i)JXZAiSW z<6|Yg;~<^t?#)>NSW`8v=Kp&u;CNeCB3Hn_q{SZz{C;4seaBv(=vq5xsGG4*ZJ1Ri zt+h*rI$+Oa*HX!bxz5FsO$(0AFo(Hm*!q!%Dr^8kfIG!6R>`=t8}b8t%{%tGuZX)I z79IH|+-{JWH4_SXwP7Hu4Ort*0hkKF&WHk56BMil>maPmIW>S`h)fM&S`g2RYhtkf z5Yw>AS77%;+&#Et1=X*NDOj?Xz^Vzpg9M*EiO5n*(DOi{%ENy4Pzb|Wj@1do<{HR# zY#yOO>o-7k*F9wSV|$t|4gO+bMFaKROz4sa;w-uh67UpCFIKs5uT`K63gN0n(M=KSS8@5ozn!G zmk)=C63*z_Oo>D(=2EkQiX9D(a6M^cYb& z!kxn6Pvh$$d|{2aKfo92V39(y3dyO1ZRrII>fix4KS0PHf{ZW1AHN6Y0u$7GDs#$c zp6E$wOp_avn(7qMziplGv~?#9n~DB?bWV4xj7e2A!2gdls!CI$Ytr#z->Q<@-b2I2 zKsl4hOI%259k(>r$#7CrFXFgEFWxGv#7&4)1#|WBE03p&OC@BsX~z^IRHJq?QA{1+ zizPw7YRr@SlbRY4-yOQ@mZfm1*g03bSnOI=DoT+o`-_JG3sFrKu)mcUPijkUt*O}^ zTIuds>OsL}>Za1ZaOl}XiNTjW)BY*{O;xq1oj?!C59$J3F@ACzhTs?I7aFFii?m-( z&IGuE7?o=$O6ps%Z$U#&Sjen@ID4iCvx1Q`& zb|9pZL3heJ<)XZ6D=s#~?^bggmijnMGJ&F6iJ~=&Su;%g=}5htrjck%OKyXd zlKFB&3ef1RQG(>ZiFV6T4v|D{9F~-<={)_ld8LUsr8>m4F`YE#oTMTfqtP2~@5ep;bq{N1EmG;Ej=H!ZW{Bm-bn?iZ?}w$| z`iHf~a>vVyF$rtjco#_fUE=S=V1hd0h`H|JwnuhJQMn-`sfe3n=83#Wy96CKXY^gn z?8mCEdsrIRj8guz{Nc)L-NPNv(g+W%ON5{P13BWl?~IdrW89*nBE3?2%n~zRFO)g? z)u=u!Vat5u1;8)Z)LQ?hde@0{h~X!1fHHA%weI=){S4&3 zAePS-VG~Di#zUT%Z4hSnvHaKQ@6hqAu`g!#klaxRXM@$De6qq|!!dYTE&J^)Td1ECp-5^-H((Pal z8M4wGSuJD^8KGBr<$P<>0C(wKq~|G!AC_`uzFc{x_p@bL{Wr&me!W=ged#ehhm^+4 zfVy)M{#Y4XF6C*X;^nb&|GoNqDGU5%DJchR*BW_KBrIbqm0FEx=Tgw7W_}XNds2od zi~^Zm z!v3Z06f4S_KUTymbrj4J%>MHdt(kAEf|Oc`nn0XC0{1Rt(xp(m3gUBVMSILH_ZRye z{RLynK&yP6{_>PW!@B-rhyIdDvuAP7PWnqm+pS59RdE$DJC8joE@Q6B&b>yOtJo^3 z<>E}}+mLf8^0buCKOu!O-<-3BYE~;@VQYXVhRC<29BhlM0qmh&Z0%RTUYEg6aQ~;A zxb=}2a>ZxKRYFS7d~@}RI1@ARO~6NO%owu|$h|vM8TlhA=e@B?eL6dLtcv$!<@%0< zDf4CPp?2Q_X`0N$Ng=iY(mEqANxx$Zz~O>?-E+NBYKJ((QrYE$p2vN!!}01^wf~RT zWrLsoD|g1l00;bQVhgT2-%yL`z@6MP!{$sY#cLuzkg&ySByO-8vfbYpxhkjGBePOi zqMIv@)rhmRcrAo1I8Te$MSdv3#cE@9F|*`LNXEGwV*poo=nacPSEY z(tN4Us#*Q|nnk3dC}_P6QchCaKhMx3g(P6mjiWG^s)9X+FXhTO?Ew>}M-k5(L%*sm z5-#uuKo3`#kHz#jAA6LV%)4|#vhM@r!7RvpFxzC!*8x_2Y2q%h_3^^Yh#o7<;?2BjKj>Q4M7{)5WfO!4#>w9TUw z4gV%pmv)F=ZNU40L|Q4&CXf=` z&L>aSNMe4J3e`((nURgJ+Hz7G0>@mEq(tPlyMtrjoP1<+%zXE{0$ow5w(B_5`1K_h zG~NFv{Ug(+|8M%^J$fDUjrF=ek@^S7sS5l4r1H|+8ELs6ojyio;3NMv3tti9yB`eW z^mvwTy`LPJGM%lW6((9B``@Qs<(bhgAf|%rWo? zAO7ptMtP=l*zITCJc9=TJmHY&xfSN%`~a9OS z*KGQt^4t#CG@&mUVv0Yer*Yv@fF2Wnt{kJU(S6q_r%F(`HVO1Ofj%!N(d82-HegAg z5Y6biJwx7*_reIbFWMG#`$7Z0P{_-<_5{Kn@Il_^^6>-VP+&am44jFVv;7><@s;rU z?03{>6VyUcZ?dud%0n~m*@7GHx3>Pb;g_F;h~M*C0Qt7jK~HHMG&sU3-Jx+obsijz z1vN2CIThRpfCy^vgbwjMnmwLK(`Z^tM6~A134IH)^L6n0{RFjQD_Sh-eJwKA{lll0 z8+RrfcP=%yL(HPBcfs7dpzS4w7J)uWEMp&H$=oq`eXeMIXdiNm*!+l%PPE(YgE)ca zbGH`m7-zK>R2!V?>5Gc@=rS{>@A#NOP!B!YVoJ#ZpH^Rw^@EBO@h)pr=At-W! z!=-+-B3Je0_IL+CcrW!Hu1}}@{H(D zPFyWVdH30Xml+%OhTs6s$S62pf~yO|k9a-4L7$fu6x`WpX*#RN9YXg^&g*6Y7y;X( zJJM+c!zdn7!4lk}|0gpH{W=n6&H_en0G#8!EHmbd3^T0(K{0kVTDBH(7`&z#s20I2 z=sJ%dJ^tXS?gx*-sS8~M&SH4*EQX-ovh6H*^(*1bhM-C(tH*qyty_dV&-f680A4Gd z;Slsv2;hNF6TqDw=!+UqHK4H~9EypcbB{*CV2JgCYv~vquMrGh-s2we`a(Ro_JgN( zV3Z#gCFBu7g>Ioje#S*qpdS*wb%>0PAwngf;&=#g5%SZ`vVw;70aA`7c3}>uQ=$b} zg<>S+apcefhtn_OM#BwZ2-o$*1(kS{3-ob;K0&<9(_XD`8bzS{I4gpoek9guf$l_y zA~-!HRy4-<@hSY7mKe6eCgpOXh#C>2-@*Q zBfJ6QY(zlZLAT2n@+2zrv0MP(0ac?7?L8qT7Odc}_ZEM`TG zAt<5O3hI+0gj@U!rawVsuoCDI@_I0e7s`oB8}N+s5jb>4oFp5AP!+#?1Lnv zB1hKHVJt-4#zwfESokhNH+I&Lph@>xK`S)?hua~7D&QRiy2%+n_yKI=;tFJ(J{L`CP0QL6Z~|D;mVvYLEr=a^ZVddD z7A)1TZJ4cCrRa^#@G>{wrfA)UTV~5`6|FuBzFZK54Ii$KH6cE76g7QZQRmmf~sslzyh;dnWWfXhH`w%VqOL^NbRF#8O%_3Fj?o ztKQdJQwHm@p(1Ihc*S$of5pFKaHec_a5J+MUXH#PT`^cDYbM#r(j`N=;OIygQ!Sg{ z?ESOeMa#Bpy|X7LZPTSwr8Ax1tD5Ugs242TR`jMt96;c;q~Dbj_q%3$%3ckpeBcle zl<;10`J{5iQa00h)53rUhob_>wG`Y|QbuN04bJGmB_IbY|J>NS=8755lDQ@);#6Vj z^utpRU(8Ra5-fPWFBI=c>UZP>T``x=Y@4+&nj03h4Y%_sTlH+=>&34Y|7peCfko@a zi6c;=wRpOCs`$GVGY7s~kx;KH)VhXLY1P#YS2oOg<~A>uwq85}{vGu|ZFNK9$c*Z3 zL&d6*vR18HDQm@a)l}7N`P@@)K6CAv8_~s$hZhTuOdL)@!p5nMv#s-GKd$;w)mx>D zn~yG9kCEcU3a(gM=e%zYT^m}oY=?7FdP`#OioGJy{Q>yLc`pYq24^~wrb=kJY_6=B z3NHID`j$%{G}*FmRbe%jq{^x$wW;E=Nma^LG~-O#YE$*D<@&Z{ecQa}#^%NPy;FUY2WQw@ z#pScAsW{+b>Sk2$+sa;5t(0$?cihp&m>eRhJ`Byg_G<|*HS_C>?xpodVFg9rKcuUpMryE%}4o^rF5lg!(7*5)#jw3 z97MGFBkawq3L_HWnv2YzN;(eRcnn@sYB(EbvR!`o#fO1ni|z9G#qnixRnlCwY_3b1 z>!5!mRPUNgR;qU0sQVk`|Iqzhw^(&JjrD!A9R$p{dBssX+m&?eoI3)qDK!#MNGfq; zT_rxrqe`kS8WQTn=&C{mQUTO;FB{4M-^}Txp=H*)XlMb2RZ_KTq3)2#cQppF-A-TY zTU8XSZ?^iWJ-6zcUqAEenfcoJCl~8?t!cAVRju4&+vXp+5y2MgqEkB#V2gF7TdZyV z^qnmR{V~&GP&us;Is?#;%-k~HmUJAv0Tn+8t*M1NtrV5cw9VEn7Byb%6**xpxE#G0 zz5MjWr)SR1)hwD@7dH1M&ApI0>FAh;R_K^g!x_j|YEZDRx~{n9isr40rQ4DP+g2Pc zNyqLv5SHCj>JJ z(QDDgiuOeJr9K2Gc=_b?nW-}i^*fV=JIQGDY;>V;Q&O|(18dV<@r|~h?fc2TCF|jY zCRG9o?~-X%k*7OOzX!*Gv{Z4`a*;Dx@)c)Ch^IH~e+b52$Xz~+#7B!BUj<+=xuQkt|{)@h)n$DEDY^DRnIb|uI z`PP&~MTDP8nY|6D?uZ zF)6DJWexhla&cp_xN*67Q?hu|V)2$q)w{)IaGdnr;_8*Mwt4oaoj*JDlS7MTJ#Rgk zEITyWwPGomshd^Lj?N7&S+=j(N@sS=_Ac34QueaxV^haoJ`RVVU^KK+_QH=~R4PoD z{5>;N+fw-Zj~~@h1#O?*-UodS+^AuIsICV^2cuRcI7{mqzPRn8EESjnYPjMLyD_rz zi`&g4QUTHeuFSQsbY4Atm9&wTcDX#(M*P{%IxXg=9hX7ay1%07{Bou)5}zKdt>)^G}*@ z8oIMewv&Rj#)_29F}>rvJD`gf?pk3$pCp+F=8wSZiu$vavL>h$#ygV?$|SS%Pt;Jk z!d;((>=l;IG|hHi_q^%9=D%s*wNh68e}2DWgOj)Su1+~AnMQ?DopfxPgYZ}iaDigk+ClqNRI1S6+fJn#4B#S`+G;r0K&`k`0SEOD4W>X7 z^-FEXcG!V<-(hk$tKWCh_--|yrIhdQr{Vo8rS9xz<*y87XIqrNYEff&o6b|K{MFua zPo?tLm1+q8y1~qrDSzEo&K4;@C{jcCgGx2qr1_v0>H1)U&ReSdU|YGjQ2CoeHH3dt zp&Qz&{7r*lh*th)t6`8*{ANE5;eVv;gT?B9v@0-NL}R$P3c|mo4FLaJWBHIv`CFG7 z!`tn{CgtypG`Uw>fh~AL-<3L&bL+hp|RZOQhw-CV|csSzd`v=>T-XB z@}C;i74qc#L`7d=ezMBdI zdzJr6>4H_tf7Q{!8tPvwX$)5>FA+B$6AMlfTl0T-JKx3u6LFt$9L#p&hn~b@fds#XPtCzSc z1e<4t)ye$q#AUiu3%YPnbcM; zYa5f=#yQm-yRfY*)wJtI8%*_d2k6gkgUdON7{+DIwy)!9 zd&IWxVP&suya(i72Or7pAh^x4?qSt%L{oEJE0qK`d6hpGoQ}n-%qXWF-%xvj>K!W!eTX7#{SF%+sbG;_*!=4ovf3ke9a~3}s zyO-T}eSb#T-laAV0M3s4z?`H!`%1Zvf2CYssa{`NQd;-Z)N>Sjm^~CQ#dY8@sq>?W zZ{3qQOzmgZCBaXrCw>PGi-X_wi4utO*WMj2uFpE}As;DczjY1QT+8HPPk(8y9C8=af0bP9L-(HxZc;fY zPthKZHs#}X_%W~rff+pOUObpoapTMg908ArH`+z_AC#`51EYDi*$z$UV;op<$t^76 z!9ujZ0TgV}OV&MC514)RELgbUk}NVo)1pC!ShdXZ(Ma(sv#5y>1U4Pcji6BlnC{d^ zyC3O(F#7aKVkH!>;UlI4ENhhax)`SETVSdfXUMVgw8`(N%gHc@28r2m$OqS85sQE8 z5aZ)X+z8s=LXj3iyNC`_$n|w#HpJWCNQz{baDkOi1Lr;6V7lhM3$g~J4GH;R*xzTsg-3^m88BLcbqU%5F0_jEe)$;aA7BP;(nIkz7Tb+9a0MMa|*vI(y)jD*ht7esT^ z-FenS3}tDfEtpn0AV6f_AWYx^DH>fs41i3p2P*95#$7Op{a?TmZWUi?<_rqDp5qT5 z>o^7EMOU)hPHyurZNKd16B{a%H&RqgXg$uH9okE-jBFVhj|_)Hdp%%4eFEt_5jA8}6#X$F#?7Ds9qjL-@JO}JMO3TU zt0Kd|obm7|5lte*X}JTFJ{T++ku-Fx0eR-dT0nK6esC7q9f0z{$72oACzu+%wi4*r zE4lWFEq#JifswDl^l~+%Dq$i2_~}z=19Eid!^2*XP+(_95sA$R65f^7@@Qve!D5}S7EP%!tg^LQs-U#S`DR5mKDp|-Zsw0FH{XzIqs6KQ76f)Q}5Ebzgcxfur zI{1VvI=~*d#}K4Gox<=>23&#g5EGLwgoQl@bPZ_*p?gy71Q*;mE$Bcm8%8uqOQa)P z24-|>Sk-*J>gNxYjIWKquU{_9eVb3VX0nZ43uo^6I&jX{vxQpq5`gz6v z*#iADz_>Pwv|M^`xQWHXMD01av^gGt6sRC|+1szhY_v2jwu6HXUH z?xJM);qYhx1QGf>j=JDvLPQmvb$}@#xNE9G=mr_&fLP=w2o}h~S+B>9kUrp?FA!jS z#5;lrI5$eJbql(pd9AH@wLo<5adA2Ua&h?N@jjO*mg(V<$RVIYCm|F!|7eH|l47M= zVIH6)V-h&Th+HPaRJ554NuZNplLao?X=T_jnHRtZT+}jp2ig>R*~zH&U_45-1en8~`fVO7Jr<_afV5P;;qZ zkzVZlAbz2tCf-RTXUq*WL4%U9r^)LYaxpa`-Wn&F#e{>W!vQZSn)FqF;#34> z2nToR<48mOr( zF*V4v8c|egTuzlZlUv(<+&DC6v{WPq3r}Ari%LM62MuGFMGB)92@cA|2xOvLP|iToBj8b9pyMx3PIx`@wW`i7PVkiL%Qulq!|cH|tK znXrfGdRX%egZyP=47!Xfy6Z&13-X#CnXy;klnB5wV}5$T@bUbp7>&2|x+787p5aJj zgm2%taR^lW=vf!6$2Q6r^vVH}4?J@}{6Fw~sKm_UJxLhG{h!XP{}^WIBO^t<>AasYMGcNz(N}bu8+u^Dbv0_YY7oTzQ$+Stszu zV2*4&3szj#Njha<2o^UZ-~k44!O;jz{=k_SCOY8R2!m%j)sUS7TpY>u!+?S3(Ctbv zAK-Awa>6%~zF8AZ1)?9@0Sxuvs}~``Uo$hRdKlM4iXM0xm}`(* zb_8XRAL7wt5E@H<#9jLtBm-X-+_irU_UPcoPc3CQMo)CD7z>w;bxC90y!|cpO51_k zO4`&#PxPP@O!2bCnY1_;n%fsGyC)8%%#LMqThiRNXx=e#Fr_jqt4flpl9bjkIkc*v zO~+~Q$55Bvrj+Uv=z^v;W&qA0z*aeZ8z!5URi#N4xa$}eikjvf2(cd_$`Hc?1VaX7 z@*J2;OqTY@+NFZhG zP3Kpr53QxZHnTNl?2=RA>L4v;v@ILzlZN_*h8>HBo!}9r(k-islBy!)Nv6uhSRqp7 z{58ocQzsz?((}|nmx)rZ1;{gP#{wZ;tKP9{m6IngfYV>&##>+%HkW~A1tFB`3aCw4 z^>XRfWa-wFcH1XPx@`M`s`!?@aoOILw0AAqdnS&hR0Yeb%A~52u)P^MQix?#Aw!Cg zA67YivU9cw0rtoMd)EQ@F`3Xv^6yxeOjxinom;8igsq;1{^8kfg{Gt zJUU$6G}NF|M$>Dy*Gpe5y=iD6o=m;jo=hL$^?b+fh&iw>W-SgGJ9yZ=r*)*v&IEW` zIg@7R^{sF2xwhwxeGBGx@P~mbbGKX^z8tz3S~OKAl;BR8i2UKM8T!S2w+!aVJeKV=V&m=`9m&Rh%Z**h#;(Oi@N9XDTWCDIXgiWL9Dz#!wZ@mX zPPb3B-_%y3m#L}sFFJpG_(z9tYWKs>gy$9I)%+{@H?_4Su@8YL-Vuf-c9_*(R4r@ zxrw*AP`nP@mDah$4P7XaQ{_1g?}CMz_k!qEjsDewEeDWz(Hd^}W*o!G-OfUJ4rrHT z!zNDRLe;%M-~fQ=PmZ4Df+Yhg-piS}$W6#_LY!W643blgug& zH$}FDL@E%qrAjro6mg*HoqvD}5|>yC$gDU-;*?uxZXAF&yXzuyK=(57@Yw;v|w7r8AaLvw0#X7xXdVN`n-Jhlb9a7#6dev5DW^EOPtYrvu#zHN~ifxo*T>v-!hy%&z4oY|tMy#+4- zk=J2Lz_&Z-eRIIK(+<;Pr0)tOhTfG~^pu?;RN*OO@CjAI+EcVcm3~WI8H?W5Fwvs3 zVkSC)wUn-AqqDLE$4JygoY1xCq^RlRw{8eanlPCbwN&&vlnN7JLS0m&;U%mrMW^L> zRDZc`{1 zFriV7!>9GaWbLfG=IgCWHDBLXx4%C7=Z0SOzJFR@g;)w)=*@TLy`zsXnuH80wFe96jhhrCt=l`AQL7 z|09C?l_Gdv7~v(^TL---`+wA5VP2-Or=H%w?nUw~HvThv&R~UYc$`Hcf8jeX?W%UG zoS&z6XntO}E9(n_XthoOn$JmSVw#%4f~f06j^}i&jg46yl$x9Oj1n*u+I7BWFYW534?_bDaIK^xhD-tC2brFD&7eu!zkD6gn!GIVtK zuaI*f7=lmRgsF(OTTxSUakB36tzKSzr?^}mt+G`|`TU0K$eQB^*O9ur>0#hO;1RA~ zt0)`pVEsT_dAuB7Ev$0?!Dh0O*>Ly2n$1+L^Vo(vwAYC9esZ&P^HH$MRR%Y>!*vUn z`!~2Qn+BPy65in6sQUsB&ptR?KJ)2Y>s*i77-m9#!xf83Y9bah99T+ zhWV9sGu(DNay1nln{IEBult*dd@)|~)LYui_i8PDfRd%A&E~c;uJ{1lDFvt~SLwAR z_4cl6urdW;v4&de9S5tYD|3KSHPreqiqARbz(COlOY^y+f7^+8SCRRtt+RY@ZTiQy zQ>Cfm#A>kK+EL}#m@hn)lf|p6{iUgTTW7Unt#9qaCr4}Dp;}uA*um0to#R(qN|UAW qZ5L`E-u5Eivl=Y7Y_@ckmnw&>eLi+W@gv5L%ESW zo}HO*X1;HJzuz~1?deG&C~v-ZdTBL*&?oXEDpuHNy#b8|@=y+WNzd58IqbzYP|h&W zo5(XakZ0XD^xRxb^~IqtL1Xu0VXs-mnLV|?r3jRAb#aB31kV=yqM%ImUF$9>)%kYd zRf?2|B}Wi{rCg-S48AGxXu+uz1<^}n_52ApC|8-kxFjaX*{DfQjE|o@eq#K@>tvy- zY%hlU6G5GoV}w&m&Ro89{(Ik_%c^ZBioQ!roKBGM%uVa@w=SGLH#>KZ6aofY3&$_= zY--jGy;DBQSjq3!38;Qh)EBsxA0VQ>`jMZpYbLCPi7!It31NGn)$Hjy1M7i4 zxh6jf73}(H8e3ogWMKG4;vf4CY$mpbcJ__kj6aE?!Gj;av~T_G7ED8K=RL{o6n>YX z(Lka-2KU){=h6_0kaw?20SkF>RqDuV-!j;;V=#bAvx*Wq-G(_-P6 zW(IItaRqQ+mJ9RDMB7LjN|p;zEz@IU)hSjeY#ds2&y#bjJ}m;JI%a3po?{ucWHV*k zD@w*}I}>AjAsWquZF_-h+s$O;S;lIba)oBnwoA?mg|Xh5(CZl`lFh^-$c_+1x{BV2Z_~W5No6gqA&QSKzz+mIl zol}nn_diXT{vxe|COH%pxsv>D4MEk(sr%uK>o_{fz-%BcL^+On=NJpvy%;+T6SWdZ zj)khHFP%w6sP%-$Dkzx9+{2~g>*#Usk)7V7+sUKqShJZp8-#w1z_e}usNxhg)D)uF zs2r3lGHI@Cl+dtY`6;Um{J2El26}45tmLy4wnkfVY`vmq%Q-KG41tl|kcj{zUk|x> z)d2b157TN7)Qz860ERlQ2;l+P@MQMx#)eFdAsRGhlxf7N2pt53L%tXa#cGyZg2t{z z+Tc>wPDKPOj_^UyA?51TIpHB>As0gC?Z7Q4Mc1aBlmXc~$NEA8bGA!nWr!6rZ>gYk z%ItILsGbgHtfo_Nuh{;#6~_JJ99@q1V% z;7n|mNw(BRBo#ff=EL)&BFI8eDS2%T&cvIEC5KBTYVNrNlBIy!++*8{$hNIfra+@0 zbqJR1WRwD0?LfD>wMq4DIs02s0e<_2Zi~&_-}}ZM_aEF8zrXhWwTGi8AB>*dK74BX z)aC7wcXs;U-A=#zINAHlzMFlU=7Z$eR$?bP_P;cgF+U2wRt~B!dZd6(7%xtD(L?r& zo-UfohKiz66819e_X5uD-{rmL?zEgtpi<9L-N|Pl26iT@8J6R zXJ*XGv{HsOrRlBaOC$nQr3$Dghe|bCBGh=db~KZxb?%#DUjqvXOfDNwVi@D6MiQH? hp%m_aHr#^~{~;;-%2Nc@r^9>k)a`fvjo?ph{a?;~0IvW5 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/formatter.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/formatter.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..639ba96b9eff14cb812db21170d9440a0b091c43 GIT binary patch literal 4710 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 p@@i)PxS}5Uhw{$fl literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/lexer.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/lexer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8075ecc2a938a0c2e8fa5bf388207d6f102a97d5 GIT binary patch literal 38665 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/plugin.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/plugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c932e389c83167795ff3e2a084765a62fce705d2 GIT binary patch literal 2622 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 J#%EPF{{^>b&@%u4 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/scanner.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/scanner.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..432b27bf6d55b3e401c3b54f3bb24adf47bb136b GIT binary patch literal 4770 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/style.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/style.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..355a729cb11a9a7d515efd3af5f13fbd0f624622 GIT binary patch literal 6695 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/token.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/token.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24fb281827d19e47398df5a5bded3ffad49a2a1f GIT binary patch literal 8203 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/__pycache__/unistring.cpython-312.pyc b/.venv/Lib/site-packages/pygments/__pycache__/unistring.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf51b9023757f22c4b34774f26c2e67e56ae40d6 GIT binary patch literal 32986 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%0AT^p(gvu1pk*-Gv`iHwo|!?q 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

vjhkk>*{~k=)BO-RC*$P=B7;bsx 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 QB1HZduK!OCKMXVf59*c is one of "lexer", "formatter" or "filter".') + special_modes.add_argument( + '-V', action='store_true', + help='Print the package version.') + special_modes.add_argument( + '-h', '--help', action='store_true', + help='Print this help.') + special_modes_group.add_argument( + '-a', metavar='ARG', + help='Formatter-specific additional argument for the -S (print ' + 'style sheet) mode.') + + argns = parser.parse_args(args[1:]) + + try: + return main_inner(parser, argns) + except BrokenPipeError: + # someone closed our stdout, e.g. by quitting a pager. + return 0 + except Exception: + if argns.v: + print(file=sys.stderr) + print('*' * 65, file=sys.stderr) + print('An unhandled exception occurred while highlighting.', + file=sys.stderr) + print('Please report the whole traceback to the issue tracker at', + file=sys.stderr) + print('.', + file=sys.stderr) + print('*' * 65, file=sys.stderr) + print(file=sys.stderr) + raise + import traceback + info = traceback.format_exception(*sys.exc_info()) + msg = info[-1].strip() + if len(info) >= 3: + # extract relevant file and position info + msg += '\n (f{})'.format(info[-2].split('\n')[0].strip()[1:]) + print(file=sys.stderr) + print('*** Error while highlighting:', file=sys.stderr) + print(msg, file=sys.stderr) + print('*** If this is a bug you want to report, please rerun with -v.', + file=sys.stderr) + return 1 diff --git a/.venv/Lib/site-packages/pygments/console.py b/.venv/Lib/site-packages/pygments/console.py new file mode 100644 index 0000000..ee1ac27 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/console.py @@ -0,0 +1,70 @@ +""" + pygments.console + ~~~~~~~~~~~~~~~~ + + Format colored console output. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +esc = "\x1b[" + +codes = {} +codes[""] = "" +codes["reset"] = esc + "39;49;00m" + +codes["bold"] = esc + "01m" +codes["faint"] = esc + "02m" +codes["standout"] = esc + "03m" +codes["underline"] = esc + "04m" +codes["blink"] = esc + "05m" +codes["overline"] = esc + "06m" + +dark_colors = ["black", "red", "green", "yellow", "blue", + "magenta", "cyan", "gray"] +light_colors = ["brightblack", "brightred", "brightgreen", "brightyellow", "brightblue", + "brightmagenta", "brightcyan", "white"] + +x = 30 +for dark, light in zip(dark_colors, light_colors): + codes[dark] = esc + "%im" % x + codes[light] = esc + "%im" % (60 + x) + x += 1 + +del dark, light, x + +codes["white"] = codes["bold"] + + +def reset_color(): + return codes["reset"] + + +def colorize(color_key, text): + return codes[color_key] + text + codes["reset"] + + +def ansiformat(attr, text): + """ + Format ``text`` with a color and/or some attributes:: + + color normal color + *color* bold color + _color_ underlined color + +color+ blinking color + """ + result = [] + if attr[:1] == attr[-1:] == '+': + result.append(codes['blink']) + attr = attr[1:-1] + if attr[:1] == attr[-1:] == '*': + result.append(codes['bold']) + attr = attr[1:-1] + if attr[:1] == attr[-1:] == '_': + result.append(codes['underline']) + attr = attr[1:-1] + result.append(codes[attr]) + result.append(text) + result.append(codes['reset']) + return ''.join(result) diff --git a/.venv/Lib/site-packages/pygments/filter.py b/.venv/Lib/site-packages/pygments/filter.py new file mode 100644 index 0000000..5efff43 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/filter.py @@ -0,0 +1,70 @@ +""" + pygments.filter + ~~~~~~~~~~~~~~~ + + Module that implements the default filter. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + + +def apply_filters(stream, filters, lexer=None): + """ + Use this method to apply an iterable of filters to + a stream. If lexer is given it's forwarded to the + filter, otherwise the filter receives `None`. + """ + def _apply(filter_, stream): + yield from filter_.filter(lexer, stream) + for filter_ in filters: + stream = _apply(filter_, stream) + return stream + + +def simplefilter(f): + """ + Decorator that converts a function into a filter:: + + @simplefilter + def lowercase(self, lexer, stream, options): + for ttype, value in stream: + yield ttype, value.lower() + """ + return type(f.__name__, (FunctionFilter,), { + '__module__': getattr(f, '__module__'), + '__doc__': f.__doc__, + 'function': f, + }) + + +class Filter: + """ + Default filter. Subclass this class or use the `simplefilter` + decorator to create own filters. + """ + + def __init__(self, **options): + self.options = options + + def filter(self, lexer, stream): + raise NotImplementedError() + + +class FunctionFilter(Filter): + """ + Abstract class used by `simplefilter` to create simple + function filters on the fly. The `simplefilter` decorator + automatically creates subclasses of this class for + functions passed to it. + """ + function = None + + def __init__(self, **options): + if not hasattr(self, 'function'): + raise TypeError(f'{self.__class__.__name__!r} used without bound function') + Filter.__init__(self, **options) + + def filter(self, lexer, stream): + # pylint: disable=not-callable + yield from self.function(lexer, stream, self.options) diff --git a/.venv/Lib/site-packages/pygments/filters/__init__.py b/.venv/Lib/site-packages/pygments/filters/__init__.py new file mode 100644 index 0000000..2fed761 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/filters/__init__.py @@ -0,0 +1,940 @@ +""" + pygments.filters + ~~~~~~~~~~~~~~~~ + + Module containing filter lookup functions and default + filters. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re + +from pygments.token import String, Comment, Keyword, Name, Error, Whitespace, \ + string_to_tokentype +from pygments.filter import Filter +from pygments.util import get_list_opt, get_int_opt, get_bool_opt, \ + get_choice_opt, ClassNotFound, OptionError +from pygments.plugin import find_plugin_filters + + +def find_filter_class(filtername): + """Lookup a filter by name. Return None if not found.""" + if filtername in FILTERS: + return FILTERS[filtername] + for name, cls in find_plugin_filters(): + if name == filtername: + return cls + return None + + +def get_filter_by_name(filtername, **options): + """Return an instantiated filter. + + Options are passed to the filter initializer if wanted. + Raise a ClassNotFound if not found. + """ + cls = find_filter_class(filtername) + if cls: + return cls(**options) + else: + raise ClassNotFound(f'filter {filtername!r} not found') + + +def get_all_filters(): + """Return a generator of all filter names.""" + yield from FILTERS + for name, _ in find_plugin_filters(): + yield name + + +def _replace_special(ttype, value, regex, specialttype, + replacefunc=lambda x: x): + last = 0 + for match in regex.finditer(value): + start, end = match.start(), match.end() + if start != last: + yield ttype, value[last:start] + yield specialttype, replacefunc(value[start:end]) + last = end + if last != len(value): + yield ttype, value[last:] + + +class CodeTagFilter(Filter): + """Highlight special code tags in comments and docstrings. + + Options accepted: + + `codetags` : list of strings + A list of strings that are flagged as code tags. The default is to + highlight ``XXX``, ``TODO``, ``FIXME``, ``BUG`` and ``NOTE``. + + .. versionchanged:: 2.13 + Now recognizes ``FIXME`` by default. + """ + + def __init__(self, **options): + Filter.__init__(self, **options) + tags = get_list_opt(options, 'codetags', + ['XXX', 'TODO', 'FIXME', 'BUG', 'NOTE']) + self.tag_re = re.compile(r'\b({})\b'.format('|'.join([ + re.escape(tag) for tag in tags if tag + ]))) + + def filter(self, lexer, stream): + regex = self.tag_re + for ttype, value in stream: + if ttype in String.Doc or \ + ttype in Comment and \ + ttype not in Comment.Preproc: + yield from _replace_special(ttype, value, regex, Comment.Special) + else: + yield ttype, value + + +class SymbolFilter(Filter): + """Convert mathematical symbols such as \\ in Isabelle + or \\longrightarrow in LaTeX into Unicode characters. + + This is mostly useful for HTML or console output when you want to + approximate the source rendering you'd see in an IDE. + + Options accepted: + + `lang` : string + The symbol language. Must be one of ``'isabelle'`` or + ``'latex'``. The default is ``'isabelle'``. + """ + + latex_symbols = { + '\\alpha' : '\U000003b1', + '\\beta' : '\U000003b2', + '\\gamma' : '\U000003b3', + '\\delta' : '\U000003b4', + '\\varepsilon' : '\U000003b5', + '\\zeta' : '\U000003b6', + '\\eta' : '\U000003b7', + '\\vartheta' : '\U000003b8', + '\\iota' : '\U000003b9', + '\\kappa' : '\U000003ba', + '\\lambda' : '\U000003bb', + '\\mu' : '\U000003bc', + '\\nu' : '\U000003bd', + '\\xi' : '\U000003be', + '\\pi' : '\U000003c0', + '\\varrho' : '\U000003c1', + '\\sigma' : '\U000003c3', + '\\tau' : '\U000003c4', + '\\upsilon' : '\U000003c5', + '\\varphi' : '\U000003c6', + '\\chi' : '\U000003c7', + '\\psi' : '\U000003c8', + '\\omega' : '\U000003c9', + '\\Gamma' : '\U00000393', + '\\Delta' : '\U00000394', + '\\Theta' : '\U00000398', + '\\Lambda' : '\U0000039b', + '\\Xi' : '\U0000039e', + '\\Pi' : '\U000003a0', + '\\Sigma' : '\U000003a3', + '\\Upsilon' : '\U000003a5', + '\\Phi' : '\U000003a6', + '\\Psi' : '\U000003a8', + '\\Omega' : '\U000003a9', + '\\leftarrow' : '\U00002190', + '\\longleftarrow' : '\U000027f5', + '\\rightarrow' : '\U00002192', + '\\longrightarrow' : '\U000027f6', + '\\Leftarrow' : '\U000021d0', + '\\Longleftarrow' : '\U000027f8', + '\\Rightarrow' : '\U000021d2', + '\\Longrightarrow' : '\U000027f9', + '\\leftrightarrow' : '\U00002194', + '\\longleftrightarrow' : '\U000027f7', + '\\Leftrightarrow' : '\U000021d4', + '\\Longleftrightarrow' : '\U000027fa', + '\\mapsto' : '\U000021a6', + '\\longmapsto' : '\U000027fc', + '\\relbar' : '\U00002500', + '\\Relbar' : '\U00002550', + '\\hookleftarrow' : '\U000021a9', + '\\hookrightarrow' : '\U000021aa', + '\\leftharpoondown' : '\U000021bd', + '\\rightharpoondown' : '\U000021c1', + '\\leftharpoonup' : '\U000021bc', + '\\rightharpoonup' : '\U000021c0', + '\\rightleftharpoons' : '\U000021cc', + '\\leadsto' : '\U0000219d', + '\\downharpoonleft' : '\U000021c3', + '\\downharpoonright' : '\U000021c2', + '\\upharpoonleft' : '\U000021bf', + '\\upharpoonright' : '\U000021be', + '\\restriction' : '\U000021be', + '\\uparrow' : '\U00002191', + '\\Uparrow' : '\U000021d1', + '\\downarrow' : '\U00002193', + '\\Downarrow' : '\U000021d3', + '\\updownarrow' : '\U00002195', + '\\Updownarrow' : '\U000021d5', + '\\langle' : '\U000027e8', + '\\rangle' : '\U000027e9', + '\\lceil' : '\U00002308', + '\\rceil' : '\U00002309', + '\\lfloor' : '\U0000230a', + '\\rfloor' : '\U0000230b', + '\\flqq' : '\U000000ab', + '\\frqq' : '\U000000bb', + '\\bot' : '\U000022a5', + '\\top' : '\U000022a4', + '\\wedge' : '\U00002227', + '\\bigwedge' : '\U000022c0', + '\\vee' : '\U00002228', + '\\bigvee' : '\U000022c1', + '\\forall' : '\U00002200', + '\\exists' : '\U00002203', + '\\nexists' : '\U00002204', + '\\neg' : '\U000000ac', + '\\Box' : '\U000025a1', + '\\Diamond' : '\U000025c7', + '\\vdash' : '\U000022a2', + '\\models' : '\U000022a8', + '\\dashv' : '\U000022a3', + '\\surd' : '\U0000221a', + '\\le' : '\U00002264', + '\\ge' : '\U00002265', + '\\ll' : '\U0000226a', + '\\gg' : '\U0000226b', + '\\lesssim' : '\U00002272', + '\\gtrsim' : '\U00002273', + '\\lessapprox' : '\U00002a85', + '\\gtrapprox' : '\U00002a86', + '\\in' : '\U00002208', + '\\notin' : '\U00002209', + '\\subset' : '\U00002282', + '\\supset' : '\U00002283', + '\\subseteq' : '\U00002286', + '\\supseteq' : '\U00002287', + '\\sqsubset' : '\U0000228f', + '\\sqsupset' : '\U00002290', + '\\sqsubseteq' : '\U00002291', + '\\sqsupseteq' : '\U00002292', + '\\cap' : '\U00002229', + '\\bigcap' : '\U000022c2', + '\\cup' : '\U0000222a', + '\\bigcup' : '\U000022c3', + '\\sqcup' : '\U00002294', + '\\bigsqcup' : '\U00002a06', + '\\sqcap' : '\U00002293', + '\\Bigsqcap' : '\U00002a05', + '\\setminus' : '\U00002216', + '\\propto' : '\U0000221d', + '\\uplus' : '\U0000228e', + '\\bigplus' : '\U00002a04', + '\\sim' : '\U0000223c', + '\\doteq' : '\U00002250', + '\\simeq' : '\U00002243', + '\\approx' : '\U00002248', + '\\asymp' : '\U0000224d', + '\\cong' : '\U00002245', + '\\equiv' : '\U00002261', + '\\Join' : '\U000022c8', + '\\bowtie' : '\U00002a1d', + '\\prec' : '\U0000227a', + '\\succ' : '\U0000227b', + '\\preceq' : '\U0000227c', + '\\succeq' : '\U0000227d', + '\\parallel' : '\U00002225', + '\\mid' : '\U000000a6', + '\\pm' : '\U000000b1', + '\\mp' : '\U00002213', + '\\times' : '\U000000d7', + '\\div' : '\U000000f7', + '\\cdot' : '\U000022c5', + '\\star' : '\U000022c6', + '\\circ' : '\U00002218', + '\\dagger' : '\U00002020', + '\\ddagger' : '\U00002021', + '\\lhd' : '\U000022b2', + '\\rhd' : '\U000022b3', + '\\unlhd' : '\U000022b4', + '\\unrhd' : '\U000022b5', + '\\triangleleft' : '\U000025c3', + '\\triangleright' : '\U000025b9', + '\\triangle' : '\U000025b3', + '\\triangleq' : '\U0000225c', + '\\oplus' : '\U00002295', + '\\bigoplus' : '\U00002a01', + '\\otimes' : '\U00002297', + '\\bigotimes' : '\U00002a02', + '\\odot' : '\U00002299', + '\\bigodot' : '\U00002a00', + '\\ominus' : '\U00002296', + '\\oslash' : '\U00002298', + '\\dots' : '\U00002026', + '\\cdots' : '\U000022ef', + '\\sum' : '\U00002211', + '\\prod' : '\U0000220f', + '\\coprod' : '\U00002210', + '\\infty' : '\U0000221e', + '\\int' : '\U0000222b', + '\\oint' : '\U0000222e', + '\\clubsuit' : '\U00002663', + '\\diamondsuit' : '\U00002662', + '\\heartsuit' : '\U00002661', + '\\spadesuit' : '\U00002660', + '\\aleph' : '\U00002135', + '\\emptyset' : '\U00002205', + '\\nabla' : '\U00002207', + '\\partial' : '\U00002202', + '\\flat' : '\U0000266d', + '\\natural' : '\U0000266e', + '\\sharp' : '\U0000266f', + '\\angle' : '\U00002220', + '\\copyright' : '\U000000a9', + '\\textregistered' : '\U000000ae', + '\\textonequarter' : '\U000000bc', + '\\textonehalf' : '\U000000bd', + '\\textthreequarters' : '\U000000be', + '\\textordfeminine' : '\U000000aa', + '\\textordmasculine' : '\U000000ba', + '\\euro' : '\U000020ac', + '\\pounds' : '\U000000a3', + '\\yen' : '\U000000a5', + '\\textcent' : '\U000000a2', + '\\textcurrency' : '\U000000a4', + '\\textdegree' : '\U000000b0', + } + + isabelle_symbols = { + '\\' : '\U0001d7ec', + '\\' : '\U0001d7ed', + '\\' : '\U0001d7ee', + '\\' : '\U0001d7ef', + '\\' : '\U0001d7f0', + '\\' : '\U0001d7f1', + '\\' : '\U0001d7f2', + '\\' : '\U0001d7f3', + '\\' : '\U0001d7f4', + '\\' : '\U0001d7f5', + '\\' : '\U0001d49c', + '\\' : '\U0000212c', + '\\' : '\U0001d49e', + '\\' : '\U0001d49f', + '\\' : '\U00002130', + '\\' : '\U00002131', + '\\' : '\U0001d4a2', + '\\' : '\U0000210b', + '\\' : '\U00002110', + '\\' : '\U0001d4a5', + '\\' : '\U0001d4a6', + '\\' : '\U00002112', + '\\' : '\U00002133', + '\\' : '\U0001d4a9', + '\\' : '\U0001d4aa', + '\\

' : '\U0001d4ab', + '\\' : '\U0001d4ac', + '\\' : '\U0000211b', + '\\' : '\U0001d4ae', + '\\' : '\U0001d4af', + '\\' : '\U0001d4b0', + '\\' : '\U0001d4b1', + '\\' : '\U0001d4b2', + '\\' : '\U0001d4b3', + '\\' : '\U0001d4b4', + '\\' : '\U0001d4b5', + '\\' : '\U0001d5ba', + '\\' : '\U0001d5bb', + '\\' : '\U0001d5bc', + '\\' : '\U0001d5bd', + '\\' : '\U0001d5be', + '\\' : '\U0001d5bf', + '\\' : '\U0001d5c0', + '\\' : '\U0001d5c1', + '\\' : '\U0001d5c2', + '\\' : '\U0001d5c3', + '\\' : '\U0001d5c4', + '\\' : '\U0001d5c5', + '\\' : '\U0001d5c6', + '\\' : '\U0001d5c7', + '\\' : '\U0001d5c8', + '\\

' : '\U0001d5c9', + '\\' : '\U0001d5ca', + '\\' : '\U0001d5cb', + '\\' : '\U0001d5cc', + '\\' : '\U0001d5cd', + '\\' : '\U0001d5ce', + '\\' : '\U0001d5cf', + '\\' : '\U0001d5d0', + '\\' : '\U0001d5d1', + '\\' : '\U0001d5d2', + '\\' : '\U0001d5d3', + '\\' : '\U0001d504', + '\\' : '\U0001d505', + '\\' : '\U0000212d', + '\\

' : '\U0001d507', + '\\' : '\U0001d508', + '\\' : '\U0001d509', + '\\' : '\U0001d50a', + '\\' : '\U0000210c', + '\\' : '\U00002111', + '\\' : '\U0001d50d', + '\\' : '\U0001d50e', + '\\' : '\U0001d50f', + '\\' : '\U0001d510', + '\\' : '\U0001d511', + '\\' : '\U0001d512', + '\\' : '\U0001d513', + '\\' : '\U0001d514', + '\\' : '\U0000211c', + '\\' : '\U0001d516', + '\\' : '\U0001d517', + '\\' : '\U0001d518', + '\\' : '\U0001d519', + '\\' : '\U0001d51a', + '\\' : '\U0001d51b', + '\\' : '\U0001d51c', + '\\' : '\U00002128', + '\\' : '\U0001d51e', + '\\' : '\U0001d51f', + '\\' : '\U0001d520', + '\\
' : '\U0001d521', + '\\' : '\U0001d522', + '\\' : '\U0001d523', + '\\' : '\U0001d524', + '\\' : '\U0001d525', + '\\' : '\U0001d526', + '\\' : '\U0001d527', + '\\' : '\U0001d528', + '\\' : '\U0001d529', + '\\' : '\U0001d52a', + '\\' : '\U0001d52b', + '\\' : '\U0001d52c', + '\\' : '\U0001d52d', + '\\' : '\U0001d52e', + '\\' : '\U0001d52f', + '\\' : '\U0001d530', + '\\' : '\U0001d531', + '\\' : '\U0001d532', + '\\' : '\U0001d533', + '\\' : '\U0001d534', + '\\' : '\U0001d535', + '\\' : '\U0001d536', + '\\' : '\U0001d537', + '\\' : '\U000003b1', + '\\' : '\U000003b2', + '\\' : '\U000003b3', + '\\' : '\U000003b4', + '\\' : '\U000003b5', + '\\' : '\U000003b6', + '\\' : '\U000003b7', + '\\' : '\U000003b8', + '\\' : '\U000003b9', + '\\' : '\U000003ba', + '\\' : '\U000003bb', + '\\' : '\U000003bc', + '\\' : '\U000003bd', + '\\' : '\U000003be', + '\\' : '\U000003c0', + '\\' : '\U000003c1', + '\\' : '\U000003c3', + '\\' : '\U000003c4', + '\\' : '\U000003c5', + '\\' : '\U000003c6', + '\\' : '\U000003c7', + '\\' : '\U000003c8', + '\\' : '\U000003c9', + '\\' : '\U00000393', + '\\' : '\U00000394', + '\\' : '\U00000398', + '\\' : '\U0000039b', + '\\' : '\U0000039e', + '\\' : '\U000003a0', + '\\' : '\U000003a3', + '\\' : '\U000003a5', + '\\' : '\U000003a6', + '\\' : '\U000003a8', + '\\' : '\U000003a9', + '\\' : '\U0001d539', + '\\' : '\U00002102', + '\\' : '\U00002115', + '\\' : '\U0000211a', + '\\' : '\U0000211d', + '\\' : '\U00002124', + '\\' : '\U00002190', + '\\' : '\U000027f5', + '\\' : '\U00002192', + '\\' : '\U000027f6', + '\\' : '\U000021d0', + '\\' : '\U000027f8', + '\\' : '\U000021d2', + '\\' : '\U000027f9', + '\\' : '\U00002194', + '\\' : '\U000027f7', + '\\' : '\U000021d4', + '\\' : '\U000027fa', + '\\' : '\U000021a6', + '\\' : '\U000027fc', + '\\' : '\U00002500', + '\\' : '\U00002550', + '\\' : '\U000021a9', + '\\' : '\U000021aa', + '\\' : '\U000021bd', + '\\' : '\U000021c1', + '\\' : '\U000021bc', + '\\' : '\U000021c0', + '\\' : '\U000021cc', + '\\' : '\U0000219d', + '\\' : '\U000021c3', + '\\' : '\U000021c2', + '\\' : '\U000021bf', + '\\' : '\U000021be', + '\\' : '\U000021be', + '\\' : '\U00002237', + '\\' : '\U00002191', + '\\' : '\U000021d1', + '\\' : '\U00002193', + '\\' : '\U000021d3', + '\\' : '\U00002195', + '\\' : '\U000021d5', + '\\' : '\U000027e8', + '\\' : '\U000027e9', + '\\' : '\U00002308', + '\\' : '\U00002309', + '\\' : '\U0000230a', + '\\' : '\U0000230b', + '\\' : '\U00002987', + '\\' : '\U00002988', + '\\' : '\U000027e6', + '\\' : '\U000027e7', + '\\' : '\U00002983', + '\\' : '\U00002984', + '\\' : '\U000000ab', + '\\' : '\U000000bb', + '\\' : '\U000022a5', + '\\' : '\U000022a4', + '\\' : '\U00002227', + '\\' : '\U000022c0', + '\\' : '\U00002228', + '\\' : '\U000022c1', + '\\' : '\U00002200', + '\\' : '\U00002203', + '\\' : '\U00002204', + '\\' : '\U000000ac', + '\\' : '\U000025a1', + '\\' : '\U000025c7', + '\\' : '\U000022a2', + '\\' : '\U000022a8', + '\\' : '\U000022a9', + '\\' : '\U000022ab', + '\\' : '\U000022a3', + '\\' : '\U0000221a', + '\\' : '\U00002264', + '\\' : '\U00002265', + '\\' : '\U0000226a', + '\\' : '\U0000226b', + '\\' : '\U00002272', + '\\' : '\U00002273', + '\\' : '\U00002a85', + '\\' : '\U00002a86', + '\\' : '\U00002208', + '\\' : '\U00002209', + '\\' : '\U00002282', + '\\' : '\U00002283', + '\\' : '\U00002286', + '\\' : '\U00002287', + '\\' : '\U0000228f', + '\\' : '\U00002290', + '\\' : '\U00002291', + '\\' : '\U00002292', + '\\' : '\U00002229', + '\\' : '\U000022c2', + '\\' : '\U0000222a', + '\\' : '\U000022c3', + '\\' : '\U00002294', + '\\' : '\U00002a06', + '\\' : '\U00002293', + '\\' : '\U00002a05', + '\\' : '\U00002216', + '\\' : '\U0000221d', + '\\' : '\U0000228e', + '\\' : '\U00002a04', + '\\' : '\U00002260', + '\\' : '\U0000223c', + '\\' : '\U00002250', + '\\' : '\U00002243', + '\\' : '\U00002248', + '\\' : '\U0000224d', + '\\' : '\U00002245', + '\\' : '\U00002323', + '\\' : '\U00002261', + '\\' : '\U00002322', + '\\' : '\U000022c8', + '\\' : '\U00002a1d', + '\\' : '\U0000227a', + '\\' : '\U0000227b', + '\\' : '\U0000227c', + '\\' : '\U0000227d', + '\\' : '\U00002225', + '\\' : '\U000000a6', + '\\' : '\U000000b1', + '\\' : '\U00002213', + '\\' : '\U000000d7', + '\\
' : '\U000000f7', + '\\' : '\U000022c5', + '\\' : '\U000022c6', + '\\' : '\U00002219', + '\\' : '\U00002218', + '\\' : '\U00002020', + '\\' : '\U00002021', + '\\' : '\U000022b2', + '\\' : '\U000022b3', + '\\' : '\U000022b4', + '\\' : '\U000022b5', + '\\' : '\U000025c3', + '\\' : '\U000025b9', + '\\' : '\U000025b3', + '\\' : '\U0000225c', + '\\' : '\U00002295', + '\\' : '\U00002a01', + '\\' : '\U00002297', + '\\' : '\U00002a02', + '\\' : '\U00002299', + '\\' : '\U00002a00', + '\\' : '\U00002296', + '\\' : '\U00002298', + '\\' : '\U00002026', + '\\' : '\U000022ef', + '\\' : '\U00002211', + '\\' : '\U0000220f', + '\\' : '\U00002210', + '\\' : '\U0000221e', + '\\' : '\U0000222b', + '\\' : '\U0000222e', + '\\' : '\U00002663', + '\\' : '\U00002662', + '\\' : '\U00002661', + '\\' : '\U00002660', + '\\' : '\U00002135', + '\\' : '\U00002205', + '\\' : '\U00002207', + '\\' : '\U00002202', + '\\' : '\U0000266d', + '\\' : '\U0000266e', + '\\' : '\U0000266f', + '\\' : '\U00002220', + '\\' : '\U000000a9', + '\\' : '\U000000ae', + '\\' : '\U000000ad', + '\\' : '\U000000af', + '\\' : '\U000000bc', + '\\' : '\U000000bd', + '\\' : '\U000000be', + '\\' : '\U000000aa', + '\\' : '\U000000ba', + '\\
' : '\U000000a7', + '\\' : '\U000000b6', + '\\' : '\U000000a1', + '\\' : '\U000000bf', + '\\' : '\U000020ac', + '\\' : '\U000000a3', + '\\' : '\U000000a5', + '\\' : '\U000000a2', + '\\' : '\U000000a4', + '\\' : '\U000000b0', + '\\' : '\U00002a3f', + '\\' : '\U00002127', + '\\' : '\U000025ca', + '\\' : '\U00002118', + '\\' : '\U00002240', + '\\' : '\U000022c4', + '\\' : '\U000000b4', + '\\' : '\U00000131', + '\\' : '\U000000a8', + '\\' : '\U000000b8', + '\\' : '\U000002dd', + '\\' : '\U000003f5', + '\\' : '\U000023ce', + '\\' : '\U00002039', + '\\' : '\U0000203a', + '\\' : '\U00002302', + '\\<^sub>' : '\U000021e9', + '\\<^sup>' : '\U000021e7', + '\\<^bold>' : '\U00002759', + '\\<^bsub>' : '\U000021d8', + '\\<^esub>' : '\U000021d9', + '\\<^bsup>' : '\U000021d7', + '\\<^esup>' : '\U000021d6', + } + + lang_map = {'isabelle' : isabelle_symbols, 'latex' : latex_symbols} + + def __init__(self, **options): + Filter.__init__(self, **options) + lang = get_choice_opt(options, 'lang', + ['isabelle', 'latex'], 'isabelle') + self.symbols = self.lang_map[lang] + + def filter(self, lexer, stream): + for ttype, value in stream: + if value in self.symbols: + yield ttype, self.symbols[value] + else: + yield ttype, value + + +class KeywordCaseFilter(Filter): + """Convert keywords to lowercase or uppercase or capitalize them, which + means first letter uppercase, rest lowercase. + + This can be useful e.g. if you highlight Pascal code and want to adapt the + code to your styleguide. + + Options accepted: + + `case` : string + The casing to convert keywords to. Must be one of ``'lower'``, + ``'upper'`` or ``'capitalize'``. The default is ``'lower'``. + """ + + def __init__(self, **options): + Filter.__init__(self, **options) + case = get_choice_opt(options, 'case', + ['lower', 'upper', 'capitalize'], 'lower') + self.convert = getattr(str, case) + + def filter(self, lexer, stream): + for ttype, value in stream: + if ttype in Keyword: + yield ttype, self.convert(value) + else: + yield ttype, value + + +class NameHighlightFilter(Filter): + """Highlight a normal Name (and Name.*) token with a different token type. + + Example:: + + filter = NameHighlightFilter( + names=['foo', 'bar', 'baz'], + tokentype=Name.Function, + ) + + This would highlight the names "foo", "bar" and "baz" + as functions. `Name.Function` is the default token type. + + Options accepted: + + `names` : list of strings + A list of names that should be given the different token type. + There is no default. + `tokentype` : TokenType or string + A token type or a string containing a token type name that is + used for highlighting the strings in `names`. The default is + `Name.Function`. + """ + + def __init__(self, **options): + Filter.__init__(self, **options) + self.names = set(get_list_opt(options, 'names', [])) + tokentype = options.get('tokentype') + if tokentype: + self.tokentype = string_to_tokentype(tokentype) + else: + self.tokentype = Name.Function + + def filter(self, lexer, stream): + for ttype, value in stream: + if ttype in Name and value in self.names: + yield self.tokentype, value + else: + yield ttype, value + + +class ErrorToken(Exception): + pass + + +class RaiseOnErrorTokenFilter(Filter): + """Raise an exception when the lexer generates an error token. + + Options accepted: + + `excclass` : Exception class + The exception class to raise. + The default is `pygments.filters.ErrorToken`. + + .. versionadded:: 0.8 + """ + + def __init__(self, **options): + Filter.__init__(self, **options) + self.exception = options.get('excclass', ErrorToken) + try: + # issubclass() will raise TypeError if first argument is not a class + if not issubclass(self.exception, Exception): + raise TypeError + except TypeError: + raise OptionError('excclass option is not an exception class') + + def filter(self, lexer, stream): + for ttype, value in stream: + if ttype is Error: + raise self.exception(value) + yield ttype, value + + +class VisibleWhitespaceFilter(Filter): + """Convert tabs, newlines and/or spaces to visible characters. + + Options accepted: + + `spaces` : string or bool + If this is a one-character string, spaces will be replaces by this string. + If it is another true value, spaces will be replaced by ``·`` (unicode + MIDDLE DOT). If it is a false value, spaces will not be replaced. The + default is ``False``. + `tabs` : string or bool + The same as for `spaces`, but the default replacement character is ``»`` + (unicode RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK). The default value + is ``False``. Note: this will not work if the `tabsize` option for the + lexer is nonzero, as tabs will already have been expanded then. + `tabsize` : int + If tabs are to be replaced by this filter (see the `tabs` option), this + is the total number of characters that a tab should be expanded to. + The default is ``8``. + `newlines` : string or bool + The same as for `spaces`, but the default replacement character is ``¶`` + (unicode PILCROW SIGN). The default value is ``False``. + `wstokentype` : bool + If true, give whitespace the special `Whitespace` token type. This allows + styling the visible whitespace differently (e.g. greyed out), but it can + disrupt background colors. The default is ``True``. + + .. versionadded:: 0.8 + """ + + def __init__(self, **options): + Filter.__init__(self, **options) + for name, default in [('spaces', '·'), + ('tabs', '»'), + ('newlines', '¶')]: + opt = options.get(name, False) + if isinstance(opt, str) and len(opt) == 1: + setattr(self, name, opt) + else: + setattr(self, name, (opt and default or '')) + tabsize = get_int_opt(options, 'tabsize', 8) + if self.tabs: + self.tabs += ' ' * (tabsize - 1) + if self.newlines: + self.newlines += '\n' + self.wstt = get_bool_opt(options, 'wstokentype', True) + + def filter(self, lexer, stream): + if self.wstt: + spaces = self.spaces or ' ' + tabs = self.tabs or '\t' + newlines = self.newlines or '\n' + regex = re.compile(r'\s') + + def replacefunc(wschar): + if wschar == ' ': + return spaces + elif wschar == '\t': + return tabs + elif wschar == '\n': + return newlines + return wschar + + for ttype, value in stream: + yield from _replace_special(ttype, value, regex, Whitespace, + replacefunc) + else: + spaces, tabs, newlines = self.spaces, self.tabs, self.newlines + # simpler processing + for ttype, value in stream: + if spaces: + value = value.replace(' ', spaces) + if tabs: + value = value.replace('\t', tabs) + if newlines: + value = value.replace('\n', newlines) + yield ttype, value + + +class GobbleFilter(Filter): + """Gobbles source code lines (eats initial characters). + + This filter drops the first ``n`` characters off every line of code. This + may be useful when the source code fed to the lexer is indented by a fixed + amount of space that isn't desired in the output. + + Options accepted: + + `n` : int + The number of characters to gobble. + + .. versionadded:: 1.2 + """ + def __init__(self, **options): + Filter.__init__(self, **options) + self.n = get_int_opt(options, 'n', 0) + + def gobble(self, value, left): + if left < len(value): + return value[left:], 0 + else: + return '', left - len(value) + + def filter(self, lexer, stream): + n = self.n + left = n # How many characters left to gobble. + for ttype, value in stream: + # Remove ``left`` tokens from first line, ``n`` from all others. + parts = value.split('\n') + (parts[0], left) = self.gobble(parts[0], left) + for i in range(1, len(parts)): + (parts[i], left) = self.gobble(parts[i], n) + value = '\n'.join(parts) + + if value != '': + yield ttype, value + + +class TokenMergeFilter(Filter): + """Merges consecutive tokens with the same token type in the output + stream of a lexer. + + .. versionadded:: 1.2 + """ + def __init__(self, **options): + Filter.__init__(self, **options) + + def filter(self, lexer, stream): + current_type = None + current_value = None + for ttype, value in stream: + if ttype is current_type: + current_value += value + else: + if current_type is not None: + yield current_type, current_value + current_type = ttype + current_value = value + if current_type is not None: + yield current_type, current_value + + +FILTERS = { + 'codetagify': CodeTagFilter, + 'keywordcase': KeywordCaseFilter, + 'highlight': NameHighlightFilter, + 'raiseonerror': RaiseOnErrorTokenFilter, + 'whitespace': VisibleWhitespaceFilter, + 'gobble': GobbleFilter, + 'tokenmerge': TokenMergeFilter, + 'symbols': SymbolFilter, +} diff --git a/.venv/Lib/site-packages/pygments/filters/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/pygments/filters/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..286ef9395df1c3611ead29d4d633f3f3b8587f18 GIT binary patch literal 37877 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�kqRzxn<5olVyz+-T%uQz z3NF#7NClVZSEPaqgn}#Cr-Dn@fFc!K;!Z^>xWr~fD!9auA{AWXE=4N1#E2plTwhaweR;$B56xWsNnD!6P{`xU9+5(`~=eGL{VQo*Hbi6RwT;z~s-xIiel z5|#=sUDqg5!6lX{Qo$uwC{n>Cu2-ajORQ9+f=k?}NClU;Nl_GB;1)$uaDiJDso>J{ zHbpA9#9BovxJ0ia6hoUIBz`cr8aOv8uNClU;Uy%wfu~53yPpRM%ixjEg z5=#`R;1X9VQo$vbDpJ8Eu2H0d3xt9z*{6a_*9t`{xWx5}RB(xvid1lk8x^VG5;rMQ z!6j}{q=HM_sz?QwxJ{7?F0odT3NF#BNClVZQ>21R^ea-q9eWDbSCI;C9x$Lt1(&Wn z6{+A7n-!_xjz3ic1y{091(#uWDN?~51B@tA!DZMsMJl-T+^$Fkm#!U(RB*=u_bO7s z9S!VOq=HM_uSf-#SePQo5Cs=lq$mn5utbpxE>E;lkqRyoS*l0{7dg7PMv)3GUCR`y z;1Vkoso(;k;L3Ta;4WsbHfih>KQRiuK; zuwF$fxJ!JP!$t4IZR8n9cD3NFL$SEPc=u!X7zQNd-{ zB1I~=3|pc|1(&!|kqYiiV5uS%T)M7Nq=HM=GDRx5yb2YHRB(Bs^@>z*CjcuIso(;k z;7azX;4+b$6sh3yL|YW8;7$i_RiuJD1Gr6*3NFLeDpJ8^Sg#@#To2HvNClUd+pkCk zmoYagQo&`+0YxgfjCrRb6%>M)A@%#qB^QvR1LqpjWXT$Yl5wErWi=27`@?O$GysJAf>Wor*z&&5A7s zLyD~icPWN}%uz%UYspIX+Z1;LnW}chJq9}zJBhgZdlkEYtXJKN`_%KL{ff(YGYZ$j z3>|-gEaxJ{VsoonqPPOc5oe|1D&tzJxZ2=uYydL9jfzbM z1BzIzRkE;CF=$+y6)6n6ues&>Ua20Iixfm7hRSFsB? z71*t~56IHkuedBzvtOvQ4a3y5Y&>sKtOhbwTNP`7%-}Y~?FMTV>wvu6Ud4Lj z>Ql6UlaYPDVuSJAsMusMptu9bMDA1!0(stM#TMflQfvjv^;HZ5SymCnsBvvm+-<_P zEABDaq1Xvz7WOK30oj>%EA9ibH1;bl!~7A?TR1}7FOZpM{(iQ)<%s>-F6imQMq zjf74HKw&6^ZA19`c(C{`QK zTNP`7a(xxIo3OQtbwFMeuVOurQTY@tAWOrq*Z}11Qlny%hP@O}+yP{&b}9zd^IC6(gGGwPK!z<*Tw!pf;wposimMerU8A_xV42{#l(82#WI3iUerMVTIV%sWx}1`d zy5L{3Q{xL1^O3#}|Mm}ys>tuZvS|Kjvjt9(H{v&ovYbp>lx3%Gki!M(vCB`pKkS1) zE{W3C+L{1-Rvd`R)*)Q_1bg+gHwAo6vgSy$-;4c#8UkUgPl7l7@bYCM=t8WHLhE?E z$?LKButEyfGck*?_!l=W=6)kwbS1GM{yKbYhqYp4RTu6!#4SshP_N}}h0vr6!-z9% z5jKpaR62rwyufSu|C6;>n9t$YUV#gjb3u%F2~$?CNh+kp!>q(2`J0P1`jZx6k>Z0L zixSJOBnl9A!!FDck7SsI`0W>yI&sziUtUboh4?LZ;>D!ILird5&9BS#3SR=l53eTK z3;CN@lUQun>L*o_8%vdJ#zrKv7v7I>Se%?|+$X)Ul#U%vywPYl=Eh6sTUO&+=9jQ2qk;G{CZ}I+3thye`zs# z?vc3clW79x#alH!%C=aMd$!JP2!-Y@^vuN~FnZ{myUlL?;?dqs>>f$q3bS=u!c)HP zHX@5twTIe*R#L}@u1(M6nS~S0TIiXD6U~yXKOl9^k|bf(EPF$?#h$uBr>Wz5SBxdT z<%kweQYl<(^OF{oX5`vCpCmRu5sx?rwmpepktL)b-FYLvJw{>k#KT?yDH`sDf=#NB z!j@1xf!giW*`>x5RPlmV;li;K9kfPPp}E-14;{V6nLT!V>pE|;A0}4Q8qf{!JREtj zgBAkY*#pKPnrYgnJQF%#GmyYC8Iq!!$U+#WLbeWYDNU_hCkbspYt!LmH|*F8qRh z6kn|zZd@2Q@#(3j8c(;sq9%O}p{z zqzlvT?kRq>{F7-jPi{N0jpEg>xw>(d+4#TAp*d;DxcQnx#teDw6)7D0!*DVhFTL`` z*&)BAS6mkj8bod#JcziZAf<%0T(3EjOdhWIv=jUd3-4Z};Oem?rMLUkxYKi9n}25h z`I)y4jGuh0Gw>MY`u%?;Uame_HNmFcU{=_Z|3ToAJ-?8Vl9+HqaANmX5ZXT|v5p^Fpc zd-dK^Udxi5r*2$)r<`)o%k?bY|6xCf9*v=g{48f;Bc3FE)ownSj--uy9K&ty6ScSR ziHDD*MeXgP9&mP`WhZ!!Bb<$mtyoj#hu8Z}O?<%F?%3nr;=q1@=m#_6SE4gNE_rk- zL>=(3Nm%mLm+N5mgi?L^2%?v|8OuZjT1jFf0ug-fAf98H_VtZra&(ky5@vUO#uYAR zXnqBdyuqNp|L?g*t+e~i6!d11I)ojj-yE3aIXUITlvCAjPQEaSo#v>EuGGvm&QJ2D z9k))loM`!S;KzA)el&hYU(Q8rNO;%pKgpSR$>D^LkH$sxpsd-|v8iSGgy zEV@Ql`8X3sVy8o z=D6Bvwc&xCy@qSlTOV2IF<%17wt6>EH{({iGKH{PbuPHm1`>Y7fg zv;kTh6h-`bx%TNIdvRBzrD0oOJ$XAmYoZ2fc0`QmCc_A)+FZPcLxh2-M2C+wp@w?! zVU^z_TQgoODk!!cp1Qj4y^Xv1dH86Q^9?3>Wu?W%YfC)E6;=6A5fgEH8oWVFqYM)* z&YF};OBG8KTU=L1qOnCEW8e;dRGI5o?$<0N_UsWVxV$4k`PG?1UFfODVzwMw;xU`T z;oiuJOT^MZ_P$Y9XVMYRq-R6v%2id1)>V|2SCy8pL^d}rM{WztSHfJsv7)N5sj_M@P2GveRVin~PU`iP??sW{~nOSp8f ziJ5hc@o)oO42+4oBo#mstc~3>k6TsSX^kf|e9<^i+Dr)|G8?sb#>KPSGu-nL&YXfW$DWDVK2Vc zs=>9m9jl9)J+_(RA?+LuaiQEma(2<|&n;yb-`cY-(KXenQlz)_ta>OIthg6ykKf&K z9x#4C7w?pkqP6c%u^#k1nS8`2>>a2iSOFT>k?jWE1m-AB-LL|Ya2w_v>#^r_W0(tm z;Z`#k!V=Si>%Cl`D&&NhNWv!e=KK%!BMw2LAH9P<`@eUeXgRSF;$|~CVk^tx^(AaM zZO`jYa9^8hrNv{yW{!>>RA`3$!c)2&dz{0$Sl9#Da$|Pifj1}| zow&R8xe^<9A~p`2Lw@0L65B8?R)&dzx2W=qj*Cl3X{I$Io>JTg^Qy@YGo)F#>%eVD zns&gvuW)?tZCGHJ&iY808!Yl8)Of26?}WvQUvZF*VP{ABL8tU9PQ=EXo|tn)EGwzS zROM$UZm7f55~&sHe&9ZT_(52N=hHSF_u8Cm4O71jpQ789h3xzXu{Ux3e{dq)}_@)}BltwY{|$`JV$!VjZEUUs>r-`rc)Q`|TAVwxjw^05U+ z7aX@vm0TDzzo+P^wTq+ z%{o76;rZ-^kCxK)9_(`r*RsQ9$E(g~&wRA(qp_Y-6HYIBXY7TsOEEW`dG(DxFUoBE zU%rCNbtwH%#-U83n-2R8YZ#NIc*paqpJ@lq!x_Wh>Kk|0VeDl++$Y1v-F-M6k2TE? z&(f~?p{21};n(f%N$<(%$!u_2sRuJKgY80Z;W52MYIj;vi%soH!~C{=2ZWYw?z@KB z%ybrY=;8A?e9nf?kI#KL<8bETbV=39M5=l-!eg-Ww|%!ISrNl>_GZNUsqVDi%xn5{ z^=2mdOTVT+cW-*aA2xVRvuEr}nMZ8V+9A7rrx;nxsc&LDH}*zGs1JwmNP8}S$E zdJ2Ya_j};L0p0EN23U38a;?^>ddp(0J%HzFk)?}`9?0qAHEgg85&HKB90Pfij#oZ@ z&%l(KePsjVrW}txzI|ZIjJ`FtJiD)AV8XP%k~(G?7q~#w#06?lLr>wfk#YJ@A{p?Ir^?o#c;zPHoCoj{!3e* z-FkM;+xf5Ozf<*{ZSQV7mp!XzMPKppdB5;nuMvHiH)&w%%#&p&%1+Ndz5Bw{+xtpB z%$pFmnsYYg!qnSnH6>w{fnC`9O8CjS*;hA*r^~|GKZ~#mK2&%|(Vfos3YO{Etf8aUJfcWAnkhCIjR3KJ2iWZo#}-veBQHc4mBH%gW0dqx?z zu-LTf+WHW>uC4_)YDs!_sG-4w^-jYb*t1=C&)}IvaWmR_v$uolzIhfcyMIu3Pfk|@ zZy-XVj@ox1TyO)cwaD#(7tfIP_$^WSurzubZm^*3iyokgejw5^H;VhCNC0cya_17B zLH8T^Pp0--s4FLKQ{+Bt_#29lr%}rInyTkbi*J?`4(hnr$y15B%=Zlbd#WeiZ8bkW zn1F(bYQ!JZA|pA_g>qWV*@Dj&p#G#J=`f<7yan6v2^d#TSdB}rF}8+**W(?L*$6O< zhVjwpsmC{+@}0iv!sta9$J4GJ$C+Rz?J|2G^wBPS9%Fu8&iI(Q6G;uHcR8UmJ0_zS zZ$STTxrX;kos;g!q~tLCJfh2YiYgX=lCcn0Sk(h-whele5lhp{)tNUaqiTuw{2dVv zCFqv3a{6cY`Jb5oLDtlPyotxh9v|0NaB6hlz35Cn&KuVkecE^Gx-aZFKVjavym{xc z=Uts^-d(WBF5ijV{zrNX?jHD*n>xaSiP0D%F;X-1XW8Y|osQAnt_lf%UFnuCagq`r zVfh@LwgvE%d>3N56Z%Y7di*-XLm@So((Izaq}WT9d^~oNJmE@_v20+*?2~&>>^*(k+0ke2JX>{P#**{dQ+qb{-PF6e zFZ$8A$;WTf8ugQL*r04+_S~25e)jIuZD-e?+4Iim3$yP&pX=!x*SG8F#1pq-u6O+W zkH=0tR(iDbxc|b~IXxvG=Zrn>dSq|X=#(duoNVn6EFZOevh#bRGhvovzxxUnz&aZ1 zX>6b&%bTzihh5|3O*+u9m~Gy>a56NTFCw^77hlRqNzK2UogE*x=+TFN`xkHQ|CKkV za^=ZQnLpfU2CdF^fe4>6W9g~3C?0m}JOn47@Y;b48uFxBUPX|n(}Q|?>3lIE>Gw8s zc<|~opZ{TZeIs)9-|MbB9O2mrlSR*8+?dQy!}HNJ-hOwd9Leo+-;Z08#PiRtRCG{jaG92ZNrn5< zlifO!7ynV+Iekd0i)HJwUC~-zn%KxV$!uk!Ax79;n&y|JZcezWOtb;^vqXFdq787u zl%DK?iBo$<+Kq1jEkf1^%AIy<-1*$=kBKRxo?T0MQCZ+bIcM#H{5g$eeSzRMVQ7TOjBH+ zOF`=x;Y7no%T8S^gM;|V&%ldY(1fDi#y~?yEX%y*#y7lTnf6N&v21xlh`Dz@i;Rs( zOrmL5H$tZLn%PQZy`}s)+KhP{5F2GbKonmbx*hoZ2?qOdeO%4Lmb(ObAt07x2hq}% zsu~+<+oIJ4^-Tg%A2_KI<}GVDhXyB&lA^%sevN^aFbg8gAtF4T#!MOfPJ^1SbU0FG;jzT2G$zyFgXCC70XDm7!zzv89|76LM1BSX54)UBJg9M| zTpsUmj`&@Q(>W2h2+oPPMQ~31rDN9bTu$c=w7KDzjvFqer8{#kjUC}!=EOTy&b&`^ z9kUi)c8_q*x-xm1b9Uc~D-Im4EOV~O1l@kc!Q+*hF_WCLkEdO6;Be*6>mgr%#eu_> z4LEmZ-=r&uJ@ZP&Wao_I4ObjETv@W#310vnuWWbC(b#afQtlk*T->+&iUWs>H#;U^ hQLDKF`, + the `arg` is then given by the ``-a`` option. + """ + return '' + + def format(self, tokensource, outfile): + """ + This method must format the tokens from the `tokensource` iterable and + write the formatted version to the file object `outfile`. + + Formatter options can control how exactly the tokens are converted. + """ + if self.encoding: + # wrap the outfile in a StreamWriter + outfile = codecs.lookup(self.encoding)[3](outfile) + return self.format_unencoded(tokensource, outfile) + + # Allow writing Formatter[str] or Formatter[bytes]. That's equivalent to + # Formatter. This helps when using third-party type stubs from typeshed. + def __class_getitem__(cls, name): + return cls diff --git a/.venv/Lib/site-packages/pygments/formatters/__init__.py b/.venv/Lib/site-packages/pygments/formatters/__init__.py new file mode 100644 index 0000000..b24931c --- /dev/null +++ b/.venv/Lib/site-packages/pygments/formatters/__init__.py @@ -0,0 +1,157 @@ +""" + pygments.formatters + ~~~~~~~~~~~~~~~~~~~ + + Pygments formatters. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import re +import sys +import types +import fnmatch +from os.path import basename + +from pygments.formatters._mapping import FORMATTERS +from pygments.plugin import find_plugin_formatters +from pygments.util import ClassNotFound + +__all__ = ['get_formatter_by_name', 'get_formatter_for_filename', + 'get_all_formatters', 'load_formatter_from_file'] + list(FORMATTERS) + +_formatter_cache = {} # classes by name +_pattern_cache = {} + + +def _fn_matches(fn, glob): + """Return whether the supplied file name fn matches pattern filename.""" + if glob not in _pattern_cache: + pattern = _pattern_cache[glob] = re.compile(fnmatch.translate(glob)) + return pattern.match(fn) + return _pattern_cache[glob].match(fn) + + +def _load_formatters(module_name): + """Load a formatter (and all others in the module too).""" + mod = __import__(module_name, None, None, ['__all__']) + for formatter_name in mod.__all__: + cls = getattr(mod, formatter_name) + _formatter_cache[cls.name] = cls + + +def get_all_formatters(): + """Return a generator for all formatter classes.""" + # NB: this returns formatter classes, not info like get_all_lexers(). + for info in FORMATTERS.values(): + if info[1] not in _formatter_cache: + _load_formatters(info[0]) + yield _formatter_cache[info[1]] + for _, formatter in find_plugin_formatters(): + yield formatter + + +def find_formatter_class(alias): + """Lookup a formatter by alias. + + Returns None if not found. + """ + for module_name, name, aliases, _, _ in FORMATTERS.values(): + if alias in aliases: + if name not in _formatter_cache: + _load_formatters(module_name) + return _formatter_cache[name] + for _, cls in find_plugin_formatters(): + if alias in cls.aliases: + return cls + + +def get_formatter_by_name(_alias, **options): + """ + Return an instance of a :class:`.Formatter` subclass that has `alias` in its + aliases list. The formatter is given the `options` at its instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if no formatter with that + alias is found. + """ + cls = find_formatter_class(_alias) + if cls is None: + raise ClassNotFound(f"no formatter found for name {_alias!r}") + return cls(**options) + + +def load_formatter_from_file(filename, formattername="CustomFormatter", **options): + """ + Return a `Formatter` subclass instance loaded from the provided file, relative + to the current directory. + + The file is expected to contain a Formatter class named ``formattername`` + (by default, CustomFormatter). Users should be very careful with the input, because + this method is equivalent to running ``eval()`` on the input file. The formatter is + given the `options` at its instantiation. + + :exc:`pygments.util.ClassNotFound` is raised if there are any errors loading + the formatter. + + .. versionadded:: 2.2 + """ + try: + # This empty dict will contain the namespace for the exec'd file + custom_namespace = {} + with open(filename, 'rb') as f: + exec(f.read(), custom_namespace) + # Retrieve the class `formattername` from that namespace + if formattername not in custom_namespace: + raise ClassNotFound(f'no valid {formattername} class found in {filename}') + formatter_class = custom_namespace[formattername] + # And finally instantiate it with the options + return formatter_class(**options) + except OSError as err: + raise ClassNotFound(f'cannot read {filename}: {err}') + except ClassNotFound: + raise + except Exception as err: + raise ClassNotFound(f'error when loading custom formatter: {err}') + + +def get_formatter_for_filename(fn, **options): + """ + Return a :class:`.Formatter` subclass instance that has a filename pattern + matching `fn`. The formatter is given the `options` at its instantiation. + + Will raise :exc:`pygments.util.ClassNotFound` if no formatter for that filename + is found. + """ + fn = basename(fn) + for modname, name, _, filenames, _ in FORMATTERS.values(): + for filename in filenames: + if _fn_matches(fn, filename): + if name not in _formatter_cache: + _load_formatters(modname) + return _formatter_cache[name](**options) + for _name, cls in find_plugin_formatters(): + for filename in cls.filenames: + if _fn_matches(fn, filename): + return cls(**options) + raise ClassNotFound(f"no formatter found for file name {fn!r}") + + +class _automodule(types.ModuleType): + """Automatically import formatters.""" + + def __getattr__(self, name): + info = FORMATTERS.get(name) + if info: + _load_formatters(info[0]) + cls = _formatter_cache[info[1]] + setattr(self, name, cls) + return cls + raise AttributeError(name) + + +oldmod = sys.modules[__name__] +newmod = _automodule(__name__) +newmod.__dict__.update(oldmod.__dict__) +sys.modules[__name__] = newmod +del newmod.newmod, newmod.oldmod, newmod.sys, newmod.types diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/__init__.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4efb4116db64aece56ce23a58c0575d54bbc981b GIT binary patch literal 6880 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/_mapping.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/_mapping.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb31946953dfdc5dd592926008e4cc3b4d44aec4 GIT binary patch literal 4229 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/groff.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/groff.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6667df0a23f18563f1475828e8901a78d5d04817 GIT binary patch literal 7283 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 L!~Z7G7YqAeh1FpU literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/html.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/html.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4897d0a37ab74fcfff0a48486c2f1bd1e7118621 GIT binary patch literal 41320 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/img.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/img.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..235d4ee87c56a791574e3f5252bc1b15bd487c76 GIT binary patch literal 28591 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 literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/irc.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/irc.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5d31249e460d0c05dde4e49bd1109e22d613833 GIT binary patch literal 6033 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 ZSPgwX)Fwv%K6qB_FP;5|03G+w{{k>}!V3TZ literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/latex.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/latex.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b71fa8324674a93b70ca0facc2e3fa46110f643 GIT binary patch literal 20091 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

(sY|bPrte${-y0}HqLFTsKh)pU+71f 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 O*DqH5ilblF`~Lw7pXgx# literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/other.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/other.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ea5dde2edd851ebb6936e60a2854080ff74f39a GIT binary patch literal 6843 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 N?Xv$X0zXU&{{u!xC42w? literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b8997e4b9906e614a94a71aab22a82369f43497 GIT binary patch literal 2960 zcmcImO>7&-6`uVgR}^K*5-saDp2&@4S`KMAwGvAVQAaOVWbC_SOM* zcJ{qD@4b2NdvEs7EiFC-Yg+Iy&{XjozL#i$ge*=qcq@oy7IhEJAWj@ApNEK3C zOyCg_Rq-k3%Bm9k_SC<m*+$y#f2)>ZXlecCknSGU5N?J2RzJJg&2RWyy?w=E2&dsp%y`pl1d1+8t z&W<@;BrgtX)>x8v?Ha(sfAOO~FE&!$y~ zk)bb=q-DmZ6w|tT`vzVy@sy^ROY!SUa)}stLSNM5p%s!@iQi1m#m%%u-pm3^Nf9$% z%X}E}Rn2_(NajP?RVP5$0TO1GB-4tPNG>RbY52jh)9{!lVOm3b&8?53>(SC1FPial z5g!5(CFxWfwJ;uD0LnHZD8>P_c@@B{@-a~rR51mhO`(`al^&p&SM|UwuX=;BA;OmY z(h-1ROJ9P#W5uju%nc<@>M9B08x~F~8492bo+H>G8I>4Bg-wtGJp0kLDhNX%yaFLj z>lsB=i8?xpFNLl!D|x>QU01Cmv4}X$M*@>Pns^WR*9_0$1)y#ttIk`jof??6VWW92 zjco37?h}qfutJHt6ab3qIyNTIuNM%CgH(Yp2r5?);gM{JTQ^7=eKtgIvFX?*_^e6P z;Fxa#4bV1hDGywxL1G$wputn+dXI4BI=89H^&R0h*SY>Gx24Vn8}mGzhGy>Au=xm3 zHh{H?f+ub{$dQt|rW^S{#DoCj`4sznci`;3!ay|djf5#V>WFi?rsjpnTr@96!gEo_ zleQG7e;}n9DIIm1ax~RiIzxb(W7J$UC>gY79XXLmXVO+8;do4I6>7_o*xT{A*bjOf z(Incu7zRzdLF*vjf17r@V+|!#vpEDJ=AU3% zL*L6Mzm-RfMn^^)(Oh! zE16rG%lPHP-!*3ZYPa?E2AqMRCmlO|#feAnufJcCcKxp%oI(9V27m}9X+Ud(URbOt ze$LPj*c4R2naww9jw)Y6BL_7A$Ob4fWJ?8)EdgTcwNO)!&cm?{J9r9pWLeR?6bZvCC_2&|1MUW+3s{aPt3cnhSep+v z8NHO&>~>u}XCw&}NzR&2Yp{U3##&J{N2UvFHA|pw+!s)D#PP8zn!X(Smd*K>a{mu~ zL)DsUKV7mO-~04lx&3^ltN*e8Q~##4FQAStm%Q74ey=r9l6PBirS0^~-taT&Mej(t zZDh;)w~n65aQLgSFUOwUEf4>!95}Z*y(3owz1uTeGdt&>+$j%?eA87PxcV~i-uFGB zC%G3rmp8qYUc4pmpF;iT4!V%PqjGlWi?Pqfp4=^;eW&cl#p#k<@pn9$S)VDL-?>xn z2|ep7_gs1DAFX+x`iuM;tGHXiCfdL<$})il=1U}&bv38awLg*gZBEgu9B(3_>PaAr zl;C)wLnQ~b3zTlXmY2cWk8>-WisQy&2 zzZ`}#X54s-xUoWP<6TNIPzb^?V`Lz}}$KYFsi05Aam+x)vOzFyx2wu$Ae*nbp^g;jt literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/rtf.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/rtf.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca293732d4fe68fb2384413f2fae374967767214 GIT binary patch literal 13751 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 L?;zu&HIDudeM%R> literal 0 HcmV?d00001 diff --git a/.venv/Lib/site-packages/pygments/formatters/__pycache__/terminal.cpython-312.pyc b/.venv/Lib/site-packages/pygments/formatters/__pycache__/terminal.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..95a26c5ed927b52042ca68bbdd172a9a2cdca0ea GIT binary patch literal 5785 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 tags. By default, the content is enclosed in a ``

`` tag, itself wrapped in a ``
`` tag (but see the `nowrap` option). The ``
``'s CSS class can be set by the `cssclass` option."), + 'IRCFormatter': ('pygments.formatters.irc', 'IRC', ('irc', 'IRC'), (), 'Format tokens with IRC color sequences'), + 'ImageFormatter': ('pygments.formatters.img', 'img', ('img', 'IMG', 'png'), ('*.png',), 'Create a PNG image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), + 'JpgImageFormatter': ('pygments.formatters.img', 'img_jpg', ('jpg', 'jpeg'), ('*.jpg',), 'Create a JPEG image from source code. This uses the Python Imaging Library to generate a pixmap from the source code.'), + 'LatexFormatter': ('pygments.formatters.latex', 'LaTeX', ('latex', 'tex'), ('*.tex',), 'Format tokens as LaTeX code. This needs the `fancyvrb` and `color` standard packages.'), + 'NullFormatter': ('pygments.formatters.other', 'Text only', ('text', 'null'), ('*.txt',), 'Output the text unchanged without any formatting.'), + 'PangoMarkupFormatter': ('pygments.formatters.pangomarkup', 'Pango Markup', ('pango', 'pangomarkup'), (), 'Format tokens as Pango Markup code. It can then be rendered to an SVG.'), + 'RawTokenFormatter': ('pygments.formatters.other', 'Raw tokens', ('raw', 'tokens'), ('*.raw',), 'Format tokens as a raw representation for storing token streams.'), + 'RtfFormatter': ('pygments.formatters.rtf', 'RTF', ('rtf',), ('*.rtf',), 'Format tokens as RTF markup. This formatter automatically outputs full RTF documents with color information and other useful stuff. Perfect for Copy and Paste into Microsoft(R) Word(R) documents.'), + 'SvgFormatter': ('pygments.formatters.svg', 'SVG', ('svg',), ('*.svg',), 'Format tokens as an SVG graphics file. This formatter is still experimental. Each line of code is a ```` element with explicit ``x`` and ``y`` coordinates containing ```` elements with the individual token styles.'), + 'Terminal256Formatter': ('pygments.formatters.terminal256', 'Terminal256', ('terminal256', 'console256', '256'), (), 'Format tokens with ANSI color sequences, for output in a 256-color terminal or console. Like in `TerminalFormatter` color sequences are terminated at newlines, so that paging the output works correctly.'), + 'TerminalFormatter': ('pygments.formatters.terminal', 'Terminal', ('terminal', 'console'), (), 'Format tokens with ANSI color sequences, for output in a text console. Color sequences are terminated at newlines, so that paging the output works correctly.'), + 'TerminalTrueColorFormatter': ('pygments.formatters.terminal256', 'TerminalTrueColor', ('terminal16m', 'console16m', '16m'), (), 'Format tokens with ANSI color sequences, for output in a true-color terminal or console. Like in `TerminalFormatter` color sequences are terminated at newlines, so that paging the output works correctly.'), + 'TestcaseFormatter': ('pygments.formatters.other', 'Testcase', ('testcase',), (), 'Format tokens as appropriate for a new testcase.'), +} diff --git a/.venv/Lib/site-packages/pygments/formatters/bbcode.py b/.venv/Lib/site-packages/pygments/formatters/bbcode.py new file mode 100644 index 0000000..339edf9 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/formatters/bbcode.py @@ -0,0 +1,108 @@ +""" + pygments.formatters.bbcode + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + BBcode formatter. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + + +from pygments.formatter import Formatter +from pygments.util import get_bool_opt + +__all__ = ['BBCodeFormatter'] + + +class BBCodeFormatter(Formatter): + """ + Format tokens with BBcodes. These formatting codes are used by many + bulletin boards, so you can highlight your sourcecode with pygments before + posting it there. + + This formatter has no support for background colors and borders, as there + are no common BBcode tags for that. + + Some board systems (e.g. phpBB) don't support colors in their [code] tag, + so you can't use the highlighting together with that tag. + Text in a [code] tag usually is shown with a monospace font (which this + formatter can do with the ``monofont`` option) and no spaces (which you + need for indentation) are removed. + + Additional options accepted: + + `style` + The style to use, can be a string or a Style subclass (default: + ``'default'``). + + `codetag` + If set to true, put the output into ``[code]`` tags (default: + ``false``) + + `monofont` + If set to true, add a tag to show the code with a monospace font + (default: ``false``). + """ + name = 'BBCode' + aliases = ['bbcode', 'bb'] + filenames = [] + + def __init__(self, **options): + Formatter.__init__(self, **options) + self._code = get_bool_opt(options, 'codetag', False) + self._mono = get_bool_opt(options, 'monofont', False) + + self.styles = {} + self._make_styles() + + def _make_styles(self): + for ttype, ndef in self.style: + start = end = '' + if ndef['color']: + start += '[color=#{}]'.format(ndef['color']) + end = '[/color]' + end + if ndef['bold']: + start += '[b]' + end = '[/b]' + end + if ndef['italic']: + start += '[i]' + end = '[/i]' + end + if ndef['underline']: + start += '[u]' + end = '[/u]' + end + # there are no common BBcodes for background-color and border + + self.styles[ttype] = start, end + + def format_unencoded(self, tokensource, outfile): + if self._code: + outfile.write('[code]') + if self._mono: + outfile.write('[font=monospace]') + + lastval = '' + lasttype = None + + for ttype, value in tokensource: + while ttype not in self.styles: + ttype = ttype.parent + if ttype == lasttype: + lastval += value + else: + if lastval: + start, end = self.styles[lasttype] + outfile.write(''.join((start, lastval, end))) + lastval = value + lasttype = ttype + + if lastval: + start, end = self.styles[lasttype] + outfile.write(''.join((start, lastval, end))) + + if self._mono: + outfile.write('[/font]') + if self._code: + outfile.write('[/code]') + if self._code or self._mono: + outfile.write('\n') diff --git a/.venv/Lib/site-packages/pygments/formatters/groff.py b/.venv/Lib/site-packages/pygments/formatters/groff.py new file mode 100644 index 0000000..028fec4 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/formatters/groff.py @@ -0,0 +1,170 @@ +""" + pygments.formatters.groff + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + Formatter for groff output. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import math +from pygments.formatter import Formatter +from pygments.util import get_bool_opt, get_int_opt + +__all__ = ['GroffFormatter'] + + +class GroffFormatter(Formatter): + """ + Format tokens with groff escapes to change their color and font style. + + .. versionadded:: 2.11 + + Additional options accepted: + + `style` + The style to use, can be a string or a Style subclass (default: + ``'default'``). + + `monospaced` + If set to true, monospace font will be used (default: ``true``). + + `linenos` + If set to true, print the line numbers (default: ``false``). + + `wrap` + Wrap lines to the specified number of characters. Disabled if set to 0 + (default: ``0``). + """ + + name = 'groff' + aliases = ['groff','troff','roff'] + filenames = [] + + def __init__(self, **options): + Formatter.__init__(self, **options) + + self.monospaced = get_bool_opt(options, 'monospaced', True) + self.linenos = get_bool_opt(options, 'linenos', False) + self._lineno = 0 + self.wrap = get_int_opt(options, 'wrap', 0) + self._linelen = 0 + + self.styles = {} + self._make_styles() + + + def _make_styles(self): + regular = '\\f[CR]' if self.monospaced else '\\f[R]' + bold = '\\f[CB]' if self.monospaced else '\\f[B]' + italic = '\\f[CI]' if self.monospaced else '\\f[I]' + + for ttype, ndef in self.style: + start = end = '' + if ndef['color']: + start += '\\m[{}]'.format(ndef['color']) + end = '\\m[]' + end + if ndef['bold']: + start += bold + end = regular + end + if ndef['italic']: + start += italic + end = regular + end + if ndef['bgcolor']: + start += '\\M[{}]'.format(ndef['bgcolor']) + end = '\\M[]' + end + + self.styles[ttype] = start, end + + + def _define_colors(self, outfile): + colors = set() + for _, ndef in self.style: + if ndef['color'] is not None: + colors.add(ndef['color']) + + for color in sorted(colors): + outfile.write('.defcolor ' + color + ' rgb #' + color + '\n') + + + def _write_lineno(self, outfile): + self._lineno += 1 + outfile.write("%s% 4d " % (self._lineno != 1 and '\n' or '', self._lineno)) + + + def _wrap_line(self, line): + length = len(line.rstrip('\n')) + space = ' ' if self.linenos else '' + newline = '' + + if length > self.wrap: + for i in range(0, math.floor(length / self.wrap)): + chunk = line[i*self.wrap:i*self.wrap+self.wrap] + newline += (chunk + '\n' + space) + remainder = length % self.wrap + if remainder > 0: + newline += line[-remainder-1:] + self._linelen = remainder + elif self._linelen + length > self.wrap: + newline = ('\n' + space) + line + self._linelen = length + else: + newline = line + self._linelen += length + + return newline + + + def _escape_chars(self, text): + text = text.replace('\\', '\\[u005C]'). \ + replace('.', '\\[char46]'). \ + replace('\'', '\\[u0027]'). \ + replace('`', '\\[u0060]'). \ + replace('~', '\\[u007E]') + copy = text + + for char in copy: + if len(char) != len(char.encode()): + uni = char.encode('unicode_escape') \ + .decode()[1:] \ + .replace('x', 'u00') \ + .upper() + text = text.replace(char, '\\[u' + uni[1:] + ']') + + return text + + + def format_unencoded(self, tokensource, outfile): + self._define_colors(outfile) + + outfile.write('.nf\n\\f[CR]\n') + + if self.linenos: + self._write_lineno(outfile) + + for ttype, value in tokensource: + while ttype not in self.styles: + ttype = ttype.parent + start, end = self.styles[ttype] + + for line in value.splitlines(True): + if self.wrap > 0: + line = self._wrap_line(line) + + if start and end: + text = self._escape_chars(line.rstrip('\n')) + if text != '': + outfile.write(''.join((start, text, end))) + else: + outfile.write(self._escape_chars(line.rstrip('\n'))) + + if line.endswith('\n'): + if self.linenos: + self._write_lineno(outfile) + self._linelen = 0 + else: + outfile.write('\n') + self._linelen = 0 + + outfile.write('\n.fi') diff --git a/.venv/Lib/site-packages/pygments/formatters/html.py b/.venv/Lib/site-packages/pygments/formatters/html.py new file mode 100644 index 0000000..4ef1836 --- /dev/null +++ b/.venv/Lib/site-packages/pygments/formatters/html.py @@ -0,0 +1,995 @@ +""" + pygments.formatters.html + ~~~~~~~~~~~~~~~~~~~~~~~~ + + Formatter for HTML output. + + :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import functools +import os +import sys +import os.path +from io import StringIO + +from pygments.formatter import Formatter +from pygments.token import Token, Text, STANDARD_TYPES +from pygments.util import get_bool_opt, get_int_opt, get_list_opt + +try: + import ctags +except ImportError: + ctags = None + +__all__ = ['HtmlFormatter'] + + +_escape_html_table = { + ord('&'): '&', + ord('<'): '<', + ord('>'): '>', + ord('"'): '"', + ord("'"): ''', +} + + +def escape_html(text, table=_escape_html_table): + """Escape &, <, > as well as single and double quotes for HTML.""" + return text.translate(table) + + +def webify(color): + if color.startswith('calc') or color.startswith('var'): + return color + else: + # Check if the color can be shortened from 6 to 3 characters + color = color.upper() + if (len(color) == 6 and + ( color[0] == color[1] + and color[2] == color[3] + and color[4] == color[5])): + return f'#{color[0]}{color[2]}{color[4]}' + else: + return f'#{color}' + + +def _get_ttype_class(ttype): + fname = STANDARD_TYPES.get(ttype) + if fname: + return fname + aname = '' + while fname is None: + aname = '-' + ttype[-1] + aname + ttype = ttype.parent + fname = STANDARD_TYPES.get(ttype) + return fname + aname + + +CSSFILE_TEMPLATE = '''\ +/* +generated by Pygments +Copyright 2006-2025 by the Pygments team. +Licensed under the BSD license, see LICENSE for details. +*/ +%(styledefs)s +''' + +DOC_HEADER = '''\ + + + + + %(title)s + + + + +

%(title)s

+ +''' + +DOC_HEADER_EXTERNALCSS = '''\ + + + + + %(title)s + + + + +

%(title)s

+ +''' + +DOC_FOOTER = '''\ + + +''' + + +class HtmlFormatter(Formatter): + r""" + Format tokens as HTML 4 ```` tags. By default, the content is enclosed + in a ``
`` tag, itself wrapped in a ``
`` tag (but see the `nowrap` option). + The ``
``'s CSS class can be set by the `cssclass` option. + + If the `linenos` option is set to ``"table"``, the ``
`` is
+    additionally wrapped inside a ```` which has one row and two
+    cells: one containing the line numbers and one containing the code.
+    Example:
+
+    .. sourcecode:: html
+
+        
+
+ + +
+
1
+            2
+
+
def foo(bar):
+              pass
+            
+
+ + (whitespace added to improve clarity). + + A list of lines can be specified using the `hl_lines` option to make these + lines highlighted (as of Pygments 0.11). + + With the `full` option, a complete HTML 4 document is output, including + the style definitions inside a ``$)', _handle_cssblock), + + include('keywords'), + include('inline'), + ], + 'keywords': [ + (words(( + '\\define', '\\end', 'caption', 'created', 'modified', 'tags', + 'title', 'type'), prefix=r'^', suffix=r'\b'), + Keyword), + ], + 'inline': [ + # escape + (r'\\.', Text), + # created or modified date + (r'\d{17}', Number.Integer), + # italics + (r'(\s)(//[^/]+//)((?=\W|\n))', + bygroups(Text, Generic.Emph, Text)), + # superscript + (r'(\s)(\^\^[^\^]+\^\^)', bygroups(Text, Generic.Emph)), + # subscript + (r'(\s)(,,[^,]+,,)', bygroups(Text, Generic.Emph)), + # underscore + (r'(\s)(__[^_]+__)', bygroups(Text, Generic.Strong)), + # bold + (r"(\s)(''[^']+'')((?=\W|\n))", + bygroups(Text, Generic.Strong, Text)), + # strikethrough + (r'(\s)(~~[^~]+~~)((?=\W|\n))', + bygroups(Text, Generic.Deleted, Text)), + # TiddlyWiki variables + (r'<<[^>]+>>', Name.Tag), + (r'\$\$[^$]+\$\$', Name.Tag), + (r'\$\([^)]+\)\$', Name.Tag), + # TiddlyWiki style or class + (r'^@@.*$', Name.Tag), + # HTML tags + (r']+>', Name.Tag), + # inline code + (r'`[^`]+`', String.Backtick), + # HTML escaped symbols + (r'&\S*?;', String.Regex), + # Wiki links + (r'(\[{2})([^]\|]+)(\]{2})', bygroups(Text, Name.Tag, Text)), + # External links + (r'(\[{2})([^]\|]+)(\|)([^]\|]+)(\]{2})', + bygroups(Text, Name.Tag, Text, Name.Attribute, Text)), + # Transclusion + (r'(\{{2})([^}]+)(\}{2})', bygroups(Text, Name.Tag, Text)), + # URLs + (r'(\b.?.?tps?://[^\s"]+)', bygroups(Name.Attribute)), + + # general text, must come last! + (r'[\w]+', Text), + (r'.', Text) + ], + } + + def __init__(self, **options): + self.handlecodeblocks = get_bool_opt(options, 'handlecodeblocks', True) + RegexLexer.__init__(self, **options) + + +class WikitextLexer(RegexLexer): + """ + For MediaWiki Wikitext. + + Parsing Wikitext is tricky, and results vary between different MediaWiki + installations, so we only highlight common syntaxes (built-in or from + popular extensions), and also assume templates produce no unbalanced + syntaxes. + """ + name = 'Wikitext' + url = 'https://www.mediawiki.org/wiki/Wikitext' + aliases = ['wikitext', 'mediawiki'] + filenames = [] + mimetypes = ['text/x-wiki'] + version_added = '2.15' + flags = re.MULTILINE + + def nowiki_tag_rules(tag_name): + return [ + (rf'(?i)()', bygroups(Punctuation, + Name.Tag, Whitespace, Punctuation), '#pop'), + include('entity'), + include('text'), + ] + + def plaintext_tag_rules(tag_name): + return [ + (rf'(?si)(.*?)()', bygroups(Text, + Punctuation, Name.Tag, Whitespace, Punctuation), '#pop'), + ] + + def delegate_tag_rules(tag_name, lexer, **lexer_kwargs): + return [ + (rf'(?i)()', bygroups(Punctuation, + Name.Tag, Whitespace, Punctuation), '#pop'), + (rf'(?si).+?(?=)', using(lexer, **lexer_kwargs)), + ] + + def text_rules(token): + return [ + (r'\w+', token), + (r'[^\S\n]+', token), + (r'(?s).', token), + ] + + def handle_syntaxhighlight(self, match, ctx): + from pygments.lexers import get_lexer_by_name + + attr_content = match.group() + start = 0 + index = 0 + while True: + index = attr_content.find('>', start) + # Exclude comment end (-->) + if attr_content[index-2:index] != '--': + break + start = index + 1 + + if index == -1: + # No tag end + yield from self.get_tokens_unprocessed(attr_content, stack=['root', 'attr']) + return + attr = attr_content[:index] + yield from self.get_tokens_unprocessed(attr, stack=['root', 'attr']) + yield match.start(3) + index, Punctuation, '>' + + lexer = None + content = attr_content[index+1:] + lang_match = re.findall(r'\blang=("|\'|)(\w+)(\1)', attr) + + if len(lang_match) >= 1: + # Pick the last match in case of multiple matches + lang = lang_match[-1][1] + try: + lexer = get_lexer_by_name(lang) + except ClassNotFound: + pass + + if lexer is None: + yield match.start() + index + 1, Text, content + else: + yield from lexer.get_tokens_unprocessed(content) + + def handle_score(self, match, ctx): + attr_content = match.group() + start = 0 + index = 0 + while True: + index = attr_content.find('>', start) + # Exclude comment end (-->) + if attr_content[index-2:index] != '--': + break + start = index + 1 + + if index == -1: + # No tag end + yield from self.get_tokens_unprocessed(attr_content, stack=['root', 'attr']) + return + attr = attr_content[:index] + content = attr_content[index+1:] + yield from self.get_tokens_unprocessed(attr, stack=['root', 'attr']) + yield match.start(3) + index, Punctuation, '>' + + lang_match = re.findall(r'\blang=("|\'|)(\w+)(\1)', attr) + # Pick the last match in case of multiple matches + lang = lang_match[-1][1] if len(lang_match) >= 1 else 'lilypond' + + if lang == 'lilypond': # Case sensitive + yield from LilyPondLexer().get_tokens_unprocessed(content) + else: # ABC + # FIXME: Use ABC lexer in the future + yield match.start() + index + 1, Text, content + + # a-z removed to prevent linter from complaining, REMEMBER to use (?i) + title_char = r' %!"$&\'()*,\-./0-9:;=?@A-Z\\\^_`~+\u0080-\uFFFF' + nbsp_char = r'(?:\t| |&\#0*160;|&\#[Xx]0*[Aa]0;|[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000])' + link_address = r'(?:[0-9.]+|\[[0-9a-f:.]+\]|[^\x00-\x20"<>\[\]\x7F\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFFFD])' + link_char_class = r'[^\x00-\x20"<>\[\]\x7F\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFFFD]' + double_slashes_i = { + '__FORCETOC__', '__NOCONTENTCONVERT__', '__NOCC__', '__NOEDITSECTION__', '__NOGALLERY__', + '__NOTITLECONVERT__', '__NOTC__', '__NOTOC__', '__TOC__', + } + double_slashes = { + '__EXPECTUNUSEDCATEGORY__', '__HIDDENCAT__', '__INDEX__', '__NEWSECTIONLINK__', + '__NOINDEX__', '__NONEWSECTIONLINK__', '__STATICREDIRECT__', '__NOGLOBAL__', + '__DISAMBIG__', '__EXPECTED_UNCONNECTED_PAGE__', + } + protocols = { + 'bitcoin:', 'ftp://', 'ftps://', 'geo:', 'git://', 'gopher://', 'http://', 'https://', + 'irc://', 'ircs://', 'magnet:', 'mailto:', 'mms://', 'news:', 'nntp://', 'redis://', + 'sftp://', 'sip:', 'sips:', 'sms:', 'ssh://', 'svn://', 'tel:', 'telnet://', 'urn:', + 'worldwind://', 'xmpp:', '//', + } + non_relative_protocols = protocols - {'//'} + html_tags = { + 'abbr', 'b', 'bdi', 'bdo', 'big', 'blockquote', 'br', 'caption', 'center', 'cite', 'code', + 'data', 'dd', 'del', 'dfn', 'div', 'dl', 'dt', 'em', 'font', 'h1', 'h2', 'h3', 'h4', 'h5', + 'h6', 'hr', 'i', 'ins', 'kbd', 'li', 'link', 'mark', 'meta', 'ol', 'p', 'q', 'rb', 'rp', + 'rt', 'rtc', 'ruby', 's', 'samp', 'small', 'span', 'strike', 'strong', 'sub', 'sup', + 'table', 'td', 'th', 'time', 'tr', 'tt', 'u', 'ul', 'var', 'wbr', + } + parser_tags = { + 'graph', 'charinsert', 'rss', 'chem', 'categorytree', 'nowiki', 'inputbox', 'math', + 'hiero', 'score', 'pre', 'ref', 'translate', 'imagemap', 'templatestyles', 'languages', + 'noinclude', 'mapframe', 'section', 'poem', 'syntaxhighlight', 'includeonly', 'tvar', + 'onlyinclude', 'templatedata', 'langconvert', 'timeline', 'dynamicpagelist', 'gallery', + 'maplink', 'ce', 'references', + } + variant_langs = { + # ZhConverter.php + 'zh', 'zh-hans', 'zh-hant', 'zh-cn', 'zh-hk', 'zh-mo', 'zh-my', 'zh-sg', 'zh-tw', + # WuuConverter.php + 'wuu', 'wuu-hans', 'wuu-hant', + # UzConverter.php + 'uz', 'uz-latn', 'uz-cyrl', + # TlyConverter.php + 'tly', 'tly-cyrl', + # TgConverter.php + 'tg', 'tg-latn', + # SrConverter.php + 'sr', 'sr-ec', 'sr-el', + # ShiConverter.php + 'shi', 'shi-tfng', 'shi-latn', + # ShConverter.php + 'sh-latn', 'sh-cyrl', + # KuConverter.php + 'ku', 'ku-arab', 'ku-latn', + # IuConverter.php + 'iu', 'ike-cans', 'ike-latn', + # GanConverter.php + 'gan', 'gan-hans', 'gan-hant', + # EnConverter.php + 'en', 'en-x-piglatin', + # CrhConverter.php + 'crh', 'crh-cyrl', 'crh-latn', + # BanConverter.php + 'ban', 'ban-bali', 'ban-x-dharma', 'ban-x-palmleaf', 'ban-x-pku', + } + magic_vars_i = { + 'ARTICLEPATH', 'INT', 'PAGEID', 'SCRIPTPATH', 'SERVER', 'SERVERNAME', 'STYLEPATH', + } + magic_vars = { + '!', '=', 'BASEPAGENAME', 'BASEPAGENAMEE', 'CASCADINGSOURCES', 'CONTENTLANGUAGE', + 'CONTENTLANG', 'CURRENTDAY', 'CURRENTDAY2', 'CURRENTDAYNAME', 'CURRENTDOW', 'CURRENTHOUR', + 'CURRENTMONTH', 'CURRENTMONTH2', 'CURRENTMONTH1', 'CURRENTMONTHABBREV', 'CURRENTMONTHNAME', + 'CURRENTMONTHNAMEGEN', 'CURRENTTIME', 'CURRENTTIMESTAMP', 'CURRENTVERSION', 'CURRENTWEEK', + 'CURRENTYEAR', 'DIRECTIONMARK', 'DIRMARK', 'FULLPAGENAME', 'FULLPAGENAMEE', 'LOCALDAY', + 'LOCALDAY2', 'LOCALDAYNAME', 'LOCALDOW', 'LOCALHOUR', 'LOCALMONTH', 'LOCALMONTH2', + 'LOCALMONTH1', 'LOCALMONTHABBREV', 'LOCALMONTHNAME', 'LOCALMONTHNAMEGEN', 'LOCALTIME', + 'LOCALTIMESTAMP', 'LOCALWEEK', 'LOCALYEAR', 'NAMESPACE', 'NAMESPACEE', 'NAMESPACENUMBER', + 'NUMBEROFACTIVEUSERS', 'NUMBEROFADMINS', 'NUMBEROFARTICLES', 'NUMBEROFEDITS', + 'NUMBEROFFILES', 'NUMBEROFPAGES', 'NUMBEROFUSERS', 'PAGELANGUAGE', 'PAGENAME', 'PAGENAMEE', + 'REVISIONDAY', 'REVISIONDAY2', 'REVISIONID', 'REVISIONMONTH', 'REVISIONMONTH1', + 'REVISIONSIZE', 'REVISIONTIMESTAMP', 'REVISIONUSER', 'REVISIONYEAR', 'ROOTPAGENAME', + 'ROOTPAGENAMEE', 'SITENAME', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME', 'SUBJECTPAGENAMEE', + 'ARTICLEPAGENAMEE', 'SUBJECTSPACE', 'ARTICLESPACE', 'SUBJECTSPACEE', 'ARTICLESPACEE', + 'SUBPAGENAME', 'SUBPAGENAMEE', 'TALKPAGENAME', 'TALKPAGENAMEE', 'TALKSPACE', 'TALKSPACEE', + } + parser_functions_i = { + 'ANCHORENCODE', 'BIDI', 'CANONICALURL', 'CANONICALURLE', 'FILEPATH', 'FORMATNUM', + 'FULLURL', 'FULLURLE', 'GENDER', 'GRAMMAR', 'INT', r'\#LANGUAGE', 'LC', 'LCFIRST', 'LOCALURL', + 'LOCALURLE', 'NS', 'NSE', 'PADLEFT', 'PADRIGHT', 'PAGEID', 'PLURAL', 'UC', 'UCFIRST', + 'URLENCODE', + } + parser_functions = { + 'BASEPAGENAME', 'BASEPAGENAMEE', 'CASCADINGSOURCES', 'DEFAULTSORT', 'DEFAULTSORTKEY', + 'DEFAULTCATEGORYSORT', 'FULLPAGENAME', 'FULLPAGENAMEE', 'NAMESPACE', 'NAMESPACEE', + 'NAMESPACENUMBER', 'NUMBERINGROUP', 'NUMINGROUP', 'NUMBEROFACTIVEUSERS', 'NUMBEROFADMINS', + 'NUMBEROFARTICLES', 'NUMBEROFEDITS', 'NUMBEROFFILES', 'NUMBEROFPAGES', 'NUMBEROFUSERS', + 'PAGENAME', 'PAGENAMEE', 'PAGESINCATEGORY', 'PAGESINCAT', 'PAGESIZE', 'PROTECTIONEXPIRY', + 'PROTECTIONLEVEL', 'REVISIONDAY', 'REVISIONDAY2', 'REVISIONID', 'REVISIONMONTH', + 'REVISIONMONTH1', 'REVISIONTIMESTAMP', 'REVISIONUSER', 'REVISIONYEAR', 'ROOTPAGENAME', + 'ROOTPAGENAMEE', 'SUBJECTPAGENAME', 'ARTICLEPAGENAME', 'SUBJECTPAGENAMEE', + 'ARTICLEPAGENAMEE', 'SUBJECTSPACE', 'ARTICLESPACE', 'SUBJECTSPACEE', 'ARTICLESPACEE', + 'SUBPAGENAME', 'SUBPAGENAMEE', 'TALKPAGENAME', 'TALKPAGENAMEE', 'TALKSPACE', 'TALKSPACEE', + 'INT', 'DISPLAYTITLE', 'PAGESINNAMESPACE', 'PAGESINNS', + } + + tokens = { + 'root': [ + # Redirects + (r"""(?xi) + (\A\s*?)(\#REDIRECT:?) # may contain a colon + (\s+)(\[\[) (?=[^\]\n]* \]\]$) + """, + bygroups(Whitespace, Keyword, Whitespace, Punctuation), 'redirect-inner'), + # Subheadings + (r'^(={2,6})(.+?)(\1)(\s*$\n)', + bygroups(Generic.Subheading, Generic.Subheading, Generic.Subheading, Whitespace)), + # Headings + (r'^(=.+?=)(\s*$\n)', + bygroups(Generic.Heading, Whitespace)), + # Double-slashed magic words + (words(double_slashes_i, prefix=r'(?i)'), Name.Function.Magic), + (words(double_slashes), Name.Function.Magic), + # Raw URLs + (r'(?i)\b(?:{}){}{}*'.format('|'.join(protocols), + link_address, link_char_class), Name.Label), + # Magic links + (rf'\b(?:RFC|PMID){nbsp_char}+[0-9]+\b', + Name.Function.Magic), + (r"""(?x) + \bISBN {nbsp_char} + (?: 97[89] {nbsp_dash}? )? + (?: [0-9] {nbsp_dash}? ){{9}} # escape format() + [0-9Xx]\b + """.format(nbsp_char=nbsp_char, nbsp_dash=f'(?:-|{nbsp_char})'), Name.Function.Magic), + include('list'), + include('inline'), + include('text'), + ], + 'redirect-inner': [ + (r'(\]\])(\s*?\n)', bygroups(Punctuation, Whitespace), '#pop'), + (r'(\#)([^#]*?)', bygroups(Punctuation, Name.Label)), + (rf'(?i)[{title_char}]+', Name.Tag), + ], + 'list': [ + # Description lists + (r'^;', Keyword, 'dt'), + # Ordered lists, unordered lists and indents + (r'^[#:*]+', Keyword), + # Horizontal rules + (r'^-{4,}', Keyword), + ], + 'inline': [ + # Signatures + (r'~{3,5}', Keyword), + # Entities + include('entity'), + # Bold & italic + (r"('')(''')(?!')", bygroups(Generic.Emph, + Generic.EmphStrong), 'inline-italic-bold'), + (r"'''(?!')", Generic.Strong, 'inline-bold'), + (r"''(?!')", Generic.Emph, 'inline-italic'), + # Comments & parameters & templates + include('replaceable'), + # Media links + ( + r"""(?xi) + (\[\[) + (File|Image) (:) + ((?: [{}] | \{{{{2,3}}[^{{}}]*?\}}{{2,3}} | )*) + (?: (\#) ([{}]*?) )? + """.format(title_char, f'{title_char}#'), + bygroups(Punctuation, Name.Namespace, Punctuation, + using(this, state=['wikilink-name']), Punctuation, Name.Label), + 'medialink-inner' + ), + # Wikilinks + ( + r"""(?xi) + (\[\[)(?!{}) # Should not contain URLs + (?: ([{}]*) (:))? + ((?: [{}] | \{{{{2,3}}[^{{}}]*?\}}{{2,3}} | )*?) + (?: (\#) ([{}]*?) )? + (\]\]) + """.format('|'.join(protocols), title_char.replace('/', ''), + title_char, f'{title_char}#'), + bygroups(Punctuation, Name.Namespace, Punctuation, + using(this, state=['wikilink-name']), Punctuation, Name.Label, Punctuation) + ), + ( + r"""(?xi) + (\[\[)(?!{}) + (?: ([{}]*) (:))? + ((?: [{}] | \{{{{2,3}}[^{{}}]*?\}}{{2,3}} | )*?) + (?: (\#) ([{}]*?) )? + (\|) + """.format('|'.join(protocols), title_char.replace('/', ''), + title_char, f'{title_char}#'), + bygroups(Punctuation, Name.Namespace, Punctuation, + using(this, state=['wikilink-name']), Punctuation, Name.Label, Punctuation), + 'wikilink-inner' + ), + # External links + ( + r"""(?xi) + (\[) + ((?:{}) {} {}*) + (\s*) + """.format('|'.join(protocols), link_address, link_char_class), + bygroups(Punctuation, Name.Label, Whitespace), + 'extlink-inner' + ), + # Tables + (r'^(:*)(\s*?)(\{\|)([^\n]*)$', bygroups(Keyword, + Whitespace, Punctuation, using(this, state=['root', 'attr'])), 'table'), + # HTML tags + (r'(?i)(<)({})\b'.format('|'.join(html_tags)), + bygroups(Punctuation, Name.Tag), 'tag-inner-ordinary'), + (r'(?i)()'.format('|'.join(html_tags)), + bygroups(Punctuation, Name.Tag, Whitespace, Punctuation)), + # + (r'(?i)(<)(nowiki)\b', bygroups(Punctuation, + Name.Tag), ('tag-nowiki', 'tag-inner')), + #
+            (r'(?i)(<)(pre)\b', bygroups(Punctuation,
+             Name.Tag), ('tag-pre', 'tag-inner')),
+            # 
+            (r'(?i)(<)(categorytree)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-categorytree', 'tag-inner')),
+            # 
+            (r'(?i)(<)(hiero)\b', bygroups(Punctuation,
+             Name.Tag), ('tag-hiero', 'tag-inner')),
+            # 
+            (r'(?i)(<)(math)\b', bygroups(Punctuation,
+             Name.Tag), ('tag-math', 'tag-inner')),
+            # 
+            (r'(?i)(<)(chem)\b', bygroups(Punctuation,
+             Name.Tag), ('tag-chem', 'tag-inner')),
+            # 
+            (r'(?i)(<)(ce)\b', bygroups(Punctuation,
+             Name.Tag), ('tag-ce', 'tag-inner')),
+            # 
+            (r'(?i)(<)(charinsert)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-charinsert', 'tag-inner')),
+            # 
+            (r'(?i)(<)(templatedata)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-templatedata', 'tag-inner')),
+            # 
+            (r'(?i)(<)(gallery)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-gallery', 'tag-inner')),
+            # 
+            (r'(?i)(<)(gallery)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-graph', 'tag-inner')),
+            # 
+            (r'(?i)(<)(dynamicpagelist)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-dynamicpagelist', 'tag-inner')),
+            # 
+            (r'(?i)(<)(inputbox)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-inputbox', 'tag-inner')),
+            # 
+            (r'(?i)(<)(rss)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-rss', 'tag-inner')),
+            # 
+            (r'(?i)(<)(imagemap)\b', bygroups(
+                Punctuation, Name.Tag), ('tag-imagemap', 'tag-inner')),
+            # 
+            (r'(?i)()',
+             bygroups(Punctuation, Name.Tag, Whitespace, Punctuation)),
+            (r'(?si)(<)(syntaxhighlight)\b([^>]*?(?.*?)(?=)',
+             bygroups(Punctuation, Name.Tag, handle_syntaxhighlight)),
+            # : Fallback case for self-closing tags
+            (r'(?i)(<)(syntaxhighlight)\b(\s*?)((?:[^>]|-->)*?)(/\s*?(?)*?)(/\s*?(?)*?)(/\s*?(?|\Z)', Comment.Multiline),
+            # Parameters
+            (
+                r"""(?x)
+                (\{{3})
+                    ([^|]*?)
+                    (?=\}{3}|\|)
+                """,
+                bygroups(Punctuation, Name.Variable),
+                'parameter-inner',
+            ),
+            # Magic variables
+            (r'(?i)(\{{\{{)(\s*)({})(\s*)(\}}\}})'.format('|'.join(magic_vars_i)),
+             bygroups(Punctuation, Whitespace, Name.Function, Whitespace, Punctuation)),
+            (r'(\{{\{{)(\s*)({})(\s*)(\}}\}})'.format('|'.join(magic_vars)),
+                bygroups(Punctuation, Whitespace, Name.Function, Whitespace, Punctuation)),
+            # Parser functions & templates
+            (r'\{\{', Punctuation, 'template-begin-space'),
+            #  legacy syntax
+            (r'(?i)(<)(tvar)\b(\|)([^>]*?)(>)', bygroups(Punctuation,
+             Name.Tag, Punctuation, String, Punctuation)),
+            (r'', Punctuation, '#pop'),
+            # 
+            (r'(?i)(<)(tvar)\b', bygroups(Punctuation, Name.Tag), 'tag-inner-ordinary'),
+            (r'(?i)()',
+             bygroups(Punctuation, Name.Tag, Whitespace, Punctuation)),
+        ],
+        'parameter-inner': [
+            (r'\}{3}', Punctuation, '#pop'),
+            (r'\|', Punctuation),
+            include('inline'),
+            include('text'),
+        ],
+        'template-begin-space': [
+            # Templates allow line breaks at the beginning, and due to how MediaWiki handles
+            # comments, an extra state is required to handle things like {{\n\n name}}
+            (r'|\Z)', Comment.Multiline),
+            (r'\s+', Whitespace),
+            # Parser functions
+            (
+                r'(?i)(\#[{}]*?|{})(:)'.format(title_char,
+                                           '|'.join(parser_functions_i)),
+                bygroups(Name.Function, Punctuation), ('#pop', 'template-inner')
+            ),
+            (
+                r'({})(:)'.format('|'.join(parser_functions)),
+                bygroups(Name.Function, Punctuation), ('#pop', 'template-inner')
+            ),
+            # Templates
+            (
+                rf'(?i)([{title_char}]*?)(:)',
+                bygroups(Name.Namespace, Punctuation), ('#pop', 'template-name')
+            ),
+            default(('#pop', 'template-name'),),
+        ],
+        'template-name': [
+            (r'(\s*?)(\|)', bygroups(Text, Punctuation), ('#pop', 'template-inner')),
+            (r'\}\}', Punctuation, '#pop'),
+            (r'\n', Text, '#pop'),
+            include('replaceable'),
+            *text_rules(Name.Tag),
+        ],
+        'template-inner': [
+            (r'\}\}', Punctuation, '#pop'),
+            (r'\|', Punctuation),
+            (
+                r"""(?x)
+                    (?<=\|)
+                    ( (?: (?! \{\{ | \}\} )[^=\|<])*? ) # Exclude templates and tags
+                    (=)
+                """,
+                bygroups(Name.Label, Operator)
+            ),
+            include('inline'),
+            include('text'),
+        ],
+        'table': [
+            # Use [ \t\n\r\0\x0B] instead of \s to follow PHP trim() behavior
+            # Endings
+            (r'^([ \t\n\r\0\x0B]*?)(\|\})',
+             bygroups(Whitespace, Punctuation), '#pop'),
+            # Table rows
+            (r'^([ \t\n\r\0\x0B]*?)(\|-+)(.*)$', bygroups(Whitespace, Punctuation,
+             using(this, state=['root', 'attr']))),
+            # Captions
+            (
+                r"""(?x)
+                ^([ \t\n\r\0\x0B]*?)(\|\+)
+                # Exclude links, template and tags
+                (?: ( (?: (?! \[\[ | \{\{ )[^|\n<] )*? )(\|) )?
+                (.*?)$
+                """,
+                bygroups(Whitespace, Punctuation, using(this, state=[
+                         'root', 'attr']), Punctuation, Generic.Heading),
+            ),
+            # Table data
+            (
+                r"""(?x)
+                ( ^(?:[ \t\n\r\0\x0B]*?)\| | \|\| )
+                (?: ( (?: (?! \[\[ | \{\{ )[^|\n<] )*? )(\|)(?!\|) )?
+                """,
+                bygroups(Punctuation, using(this, state=[
+                         'root', 'attr']), Punctuation),
+            ),
+            # Table headers
+            (
+                r"""(?x)
+                ( ^(?:[ \t\n\r\0\x0B]*?)!  )
+                (?: ( (?: (?! \[\[ | \{\{ )[^|\n<] )*? )(\|)(?!\|) )?
+                """,
+                bygroups(Punctuation, using(this, state=[
+                         'root', 'attr']), Punctuation),
+                'table-header',
+            ),
+            include('list'),
+            include('inline'),
+            include('text'),
+        ],
+        'table-header': [
+            # Requires another state for || handling inside headers
+            (r'\n', Text, '#pop'),
+            (
+                r"""(?x)
+                (!!|\|\|)
+                (?:
+                    ( (?: (?! \[\[ | \{\{ )[^|\n<] )*? )
+                    (\|)(?!\|)
+                )?
+                """,
+                bygroups(Punctuation, using(this, state=[
+                         'root', 'attr']), Punctuation)
+            ),
+            *text_rules(Generic.Subheading),
+        ],
+        'entity': [
+            (r'&\S*?;', Name.Entity),
+        ],
+        'dt': [
+            (r'\n', Text, '#pop'),
+            include('inline'),
+            (r':', Keyword, '#pop'),
+            include('text'),
+        ],
+        'extlink-inner': [
+            (r'\]', Punctuation, '#pop'),
+            include('inline'),
+            include('text'),
+        ],
+        'nowiki-ish': [
+            include('entity'),
+            include('text'),
+        ],
+        'attr': [
+            include('replaceable'),
+            (r'\s+', Whitespace),
+            (r'(=)(\s*)(")', bygroups(Operator, Whitespace, String.Double), 'attr-val-2'),
+            (r"(=)(\s*)(')", bygroups(Operator, Whitespace, String.Single), 'attr-val-1'),
+            (r'(=)(\s*)', bygroups(Operator, Whitespace), 'attr-val-0'),
+            (r'[\w:-]+', Name.Attribute),
+
+        ],
+        'attr-val-0': [
+            (r'\s', Whitespace, '#pop'),
+            include('replaceable'),
+            *text_rules(String),
+        ],
+        'attr-val-1': [
+            (r"'", String.Single, '#pop'),
+            include('replaceable'),
+            *text_rules(String.Single),
+        ],
+        'attr-val-2': [
+            (r'"', String.Double, '#pop'),
+            include('replaceable'),
+            *text_rules(String.Double),
+        ],
+        'tag-inner-ordinary': [
+            (r'/?\s*>', Punctuation, '#pop'),
+            include('tag-attr'),
+        ],
+        'tag-inner': [
+            # Return to root state for self-closing tags
+            (r'/\s*>', Punctuation, '#pop:2'),
+            (r'\s*>', Punctuation, '#pop'),
+            include('tag-attr'),
+        ],
+        # There states below are just like their non-tag variants, the key difference is
+        # they forcibly quit when encountering tag closing markup
+        'tag-attr': [
+            include('replaceable'),
+            (r'\s+', Whitespace),
+            (r'(=)(\s*)(")', bygroups(Operator,
+             Whitespace, String.Double), 'tag-attr-val-2'),
+            (r"(=)(\s*)(')", bygroups(Operator,
+             Whitespace, String.Single), 'tag-attr-val-1'),
+            (r'(=)(\s*)', bygroups(Operator, Whitespace), 'tag-attr-val-0'),
+            (r'[\w:-]+', Name.Attribute),
+
+        ],
+        'tag-attr-val-0': [
+            (r'\s', Whitespace, '#pop'),
+            (r'/?>', Punctuation, '#pop:2'),
+            include('replaceable'),
+            *text_rules(String),
+        ],
+        'tag-attr-val-1': [
+            (r"'", String.Single, '#pop'),
+            (r'/?>', Punctuation, '#pop:2'),
+            include('replaceable'),
+            *text_rules(String.Single),
+        ],
+        'tag-attr-val-2': [
+            (r'"', String.Double, '#pop'),
+            (r'/?>', Punctuation, '#pop:2'),
+            include('replaceable'),
+            *text_rules(String.Double),
+        ],
+        'tag-nowiki': nowiki_tag_rules('nowiki'),
+        'tag-pre': nowiki_tag_rules('pre'),
+        'tag-categorytree': plaintext_tag_rules('categorytree'),
+        'tag-dynamicpagelist': plaintext_tag_rules('dynamicpagelist'),
+        'tag-hiero': plaintext_tag_rules('hiero'),
+        'tag-inputbox': plaintext_tag_rules('inputbox'),
+        'tag-imagemap': plaintext_tag_rules('imagemap'),
+        'tag-charinsert': plaintext_tag_rules('charinsert'),
+        'tag-timeline': plaintext_tag_rules('timeline'),
+        'tag-gallery': plaintext_tag_rules('gallery'),
+        'tag-graph': plaintext_tag_rules('graph'),
+        'tag-rss': plaintext_tag_rules('rss'),
+        'tag-math': delegate_tag_rules('math', TexLexer, state='math'),
+        'tag-chem': delegate_tag_rules('chem', TexLexer, state='math'),
+        'tag-ce': delegate_tag_rules('ce', TexLexer, state='math'),
+        'tag-templatedata': delegate_tag_rules('templatedata', JsonLexer),
+        'text-italic': text_rules(Generic.Emph),
+        'text-bold': text_rules(Generic.Strong),
+        'text-bold-italic': text_rules(Generic.EmphStrong),
+        'text': text_rules(Text),
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/math.py b/.venv/Lib/site-packages/pygments/lexers/math.py
new file mode 100644
index 0000000..b225ffc
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/math.py
@@ -0,0 +1,21 @@
+"""
+    pygments.lexers.math
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Just export lexers that were contained in this module.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+# ruff: noqa: F401
+from pygments.lexers.python import NumPyLexer
+from pygments.lexers.matlab import MatlabLexer, MatlabSessionLexer, \
+    OctaveLexer, ScilabLexer
+from pygments.lexers.julia import JuliaLexer, JuliaConsoleLexer
+from pygments.lexers.r import RConsoleLexer, SLexer, RdLexer
+from pygments.lexers.modeling import BugsLexer, JagsLexer, StanLexer
+from pygments.lexers.idl import IDLLexer
+from pygments.lexers.algebra import MuPADLexer
+
+__all__ = []
diff --git a/.venv/Lib/site-packages/pygments/lexers/matlab.py b/.venv/Lib/site-packages/pygments/lexers/matlab.py
new file mode 100644
index 0000000..8eeffc9
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/matlab.py
@@ -0,0 +1,3307 @@
+"""
+    pygments.lexers.matlab
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Matlab and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import Lexer, RegexLexer, bygroups, default, words, \
+    do_insertions, include
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Generic, Whitespace
+
+from pygments.lexers import _scilab_builtins
+
+__all__ = ['MatlabLexer', 'MatlabSessionLexer', 'OctaveLexer', 'ScilabLexer']
+
+
+class MatlabLexer(RegexLexer):
+    """
+    For Matlab source code.
+    """
+    name = 'Matlab'
+    aliases = ['matlab']
+    filenames = ['*.m']
+    mimetypes = ['text/matlab']
+    url = 'https://www.mathworks.com/products/matlab.html'
+    version_added = '0.10'
+
+    _operators = r'-|==|~=|<=|>=|<|>|&&|&|~|\|\|?|\.\*|\*|\+|\.\^|\^|\.\\|\./|/|\\'
+
+    tokens = {
+        'expressions': [
+            # operators:
+            (_operators, Operator),
+
+            # numbers (must come before punctuation to handle `.5`; cannot use
+            # `\b` due to e.g. `5. + .5`).  The negative lookahead on operators
+            # avoids including the dot in `1./x` (the dot is part of `./`).
+            (rf'(? and then
+            # (equal | open-parenthesis |  | ).
+            (rf'(?:^|(?<=;))(\s*)(\w+)(\s+)(?!=|\(|{_operators}\s|\s)',
+             bygroups(Whitespace, Name, Whitespace), 'commandargs'),
+
+            include('expressions')
+        ],
+        'blockcomment': [
+            (r'^\s*%\}', Comment.Multiline, '#pop'),
+            (r'^.*\n', Comment.Multiline),
+            (r'.', Comment.Multiline),
+        ],
+        'deffunc': [
+            (r'(\s*)(?:(\S+)(\s*)(=)(\s*))?(.+)(\()(.*)(\))(\s*)',
+             bygroups(Whitespace, Text, Whitespace, Punctuation,
+                      Whitespace, Name.Function, Punctuation, Text,
+                      Punctuation, Whitespace), '#pop'),
+            # function with no args
+            (r'(\s*)([a-zA-Z_]\w*)',
+             bygroups(Whitespace, Name.Function), '#pop'),
+        ],
+        'propattrs': [
+            (r'(\w+)(\s*)(=)(\s*)(\d+)',
+             bygroups(Name.Builtin, Whitespace, Punctuation, Whitespace,
+                      Number)),
+            (r'(\w+)(\s*)(=)(\s*)([a-zA-Z]\w*)',
+             bygroups(Name.Builtin, Whitespace, Punctuation, Whitespace,
+                      Keyword)),
+            (r',', Punctuation),
+            (r'\)', Punctuation, '#pop'),
+            (r'\s+', Whitespace),
+            (r'.', Text),
+        ],
+        'defprops': [
+            (r'%\{\s*\n', Comment.Multiline, 'blockcomment'),
+            (r'%.*$', Comment),
+            (r'(?.
+    """
+    name = 'Matlab session'
+    aliases = ['matlabsession']
+    url = 'https://www.mathworks.com/products/matlab.html'
+    version_added = '0.10'
+    _example = "matlabsession/matlabsession_sample.txt"
+
+    def get_tokens_unprocessed(self, text):
+        mlexer = MatlabLexer(**self.options)
+
+        curcode = ''
+        insertions = []
+        continuation = False
+
+        for match in line_re.finditer(text):
+            line = match.group()
+
+            if line.startswith('>> '):
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt, line[:3])]))
+                curcode += line[3:]
+
+            elif line.startswith('>>'):
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt, line[:2])]))
+                curcode += line[2:]
+
+            elif line.startswith('???'):
+
+                idx = len(curcode)
+
+                # without is showing error on same line as before...?
+                # line = "\n" + line
+                token = (0, Generic.Traceback, line)
+                insertions.append((idx, [token]))
+            elif continuation and insertions:
+                # line_start is the length of the most recent prompt symbol
+                line_start = len(insertions[-1][-1][-1])
+                # Set leading spaces with the length of the prompt to be a generic prompt
+                # This keeps code aligned when prompts are removed, say with some Javascript
+                if line.startswith(' '*line_start):
+                    insertions.append(
+                        (len(curcode), [(0, Generic.Prompt, line[:line_start])]))
+                    curcode += line[line_start:]
+                else:
+                    curcode += line
+            else:
+                if curcode:
+                    yield from do_insertions(
+                        insertions, mlexer.get_tokens_unprocessed(curcode))
+                    curcode = ''
+                    insertions = []
+
+                yield match.start(), Generic.Output, line
+
+            # Does not allow continuation if a comment is included after the ellipses.
+            # Continues any line that ends with ..., even comments (lines that start with %)
+            if line.strip().endswith('...'):
+                continuation = True
+            else:
+                continuation = False
+
+        if curcode:  # or item:
+            yield from do_insertions(
+                insertions, mlexer.get_tokens_unprocessed(curcode))
+
+
+class OctaveLexer(RegexLexer):
+    """
+    For GNU Octave source code.
+    """
+    name = 'Octave'
+    url = 'https://www.gnu.org/software/octave/index'
+    aliases = ['octave']
+    filenames = ['*.m']
+    mimetypes = ['text/octave']
+    version_added = '1.5'
+
+    # These lists are generated automatically.
+    # Run the following in bash shell:
+    #
+    # First dump all of the Octave manual into a plain text file:
+    #
+    #   $ info octave --subnodes -o octave-manual
+    #
+    # Now grep through it:
+
+    # for i in \
+    #     "Built-in Function" "Command" "Function File" \
+    #     "Loadable Function" "Mapping Function";
+    # do
+    #     perl -e '@name = qw('"$i"');
+    #              print lc($name[0]),"_kw = [\n"';
+    #
+    #     perl -n -e 'print "\"$1\",\n" if /-- '"$i"': .* (\w*) \(/;' \
+    #         octave-manual | sort | uniq ;
+    #     echo "]" ;
+    #     echo;
+    # done
+
+    # taken from Octave Mercurial changeset 8cc154f45e37 (30-jan-2011)
+
+    builtin_kw = (
+        "addlistener", "addpath", "addproperty", "all",
+        "and", "any", "argnames", "argv", "assignin",
+        "atexit", "autoload",
+        "available_graphics_toolkits", "beep_on_error",
+        "bitand", "bitmax", "bitor", "bitshift", "bitxor",
+        "cat", "cell", "cellstr", "char", "class", "clc",
+        "columns", "command_line_path",
+        "completion_append_char", "completion_matches",
+        "complex", "confirm_recursive_rmdir", "cputime",
+        "crash_dumps_octave_core", "ctranspose", "cumprod",
+        "cumsum", "debug_on_error", "debug_on_interrupt",
+        "debug_on_warning", "default_save_options",
+        "dellistener", "diag", "diff", "disp",
+        "doc_cache_file", "do_string_escapes", "double",
+        "drawnow", "e", "echo_executing_commands", "eps",
+        "eq", "errno", "errno_list", "error", "eval",
+        "evalin", "exec", "exist", "exit", "eye", "false",
+        "fclear", "fclose", "fcntl", "fdisp", "feof",
+        "ferror", "feval", "fflush", "fgetl", "fgets",
+        "fieldnames", "file_in_loadpath", "file_in_path",
+        "filemarker", "filesep", "find_dir_in_path",
+        "fixed_point_format", "fnmatch", "fopen", "fork",
+        "formula", "fprintf", "fputs", "fread", "freport",
+        "frewind", "fscanf", "fseek", "fskipl", "ftell",
+        "functions", "fwrite", "ge", "genpath", "get",
+        "getegid", "getenv", "geteuid", "getgid",
+        "getpgrp", "getpid", "getppid", "getuid", "glob",
+        "gt", "gui_mode", "history_control",
+        "history_file", "history_size",
+        "history_timestamp_format_string", "home",
+        "horzcat", "hypot", "ifelse",
+        "ignore_function_time_stamp", "inferiorto",
+        "info_file", "info_program", "inline", "input",
+        "intmax", "intmin", "ipermute",
+        "is_absolute_filename", "isargout", "isbool",
+        "iscell", "iscellstr", "ischar", "iscomplex",
+        "isempty", "isfield", "isfloat", "isglobal",
+        "ishandle", "isieee", "isindex", "isinteger",
+        "islogical", "ismatrix", "ismethod", "isnull",
+        "isnumeric", "isobject", "isreal",
+        "is_rooted_relative_filename", "issorted",
+        "isstruct", "isvarname", "kbhit", "keyboard",
+        "kill", "lasterr", "lasterror", "lastwarn",
+        "ldivide", "le", "length", "link", "linspace",
+        "logical", "lstat", "lt", "make_absolute_filename",
+        "makeinfo_program", "max_recursion_depth", "merge",
+        "methods", "mfilename", "minus", "mislocked",
+        "mkdir", "mkfifo", "mkstemp", "mldivide", "mlock",
+        "mouse_wheel_zoom", "mpower", "mrdivide", "mtimes",
+        "munlock", "nargin", "nargout",
+        "native_float_format", "ndims", "ne", "nfields",
+        "nnz", "norm", "not", "numel", "nzmax",
+        "octave_config_info", "octave_core_file_limit",
+        "octave_core_file_name",
+        "octave_core_file_options", "ones", "or",
+        "output_max_field_width", "output_precision",
+        "page_output_immediately", "page_screen_output",
+        "path", "pathsep", "pause", "pclose", "permute",
+        "pi", "pipe", "plus", "popen", "power",
+        "print_empty_dimensions", "printf",
+        "print_struct_array_contents", "prod",
+        "program_invocation_name", "program_name",
+        "putenv", "puts", "pwd", "quit", "rats", "rdivide",
+        "readdir", "readlink", "read_readline_init_file",
+        "realmax", "realmin", "rehash", "rename",
+        "repelems", "re_read_readline_init_file", "reset",
+        "reshape", "resize", "restoredefaultpath",
+        "rethrow", "rmdir", "rmfield", "rmpath", "rows",
+        "save_header_format_string", "save_precision",
+        "saving_history", "scanf", "set", "setenv",
+        "shell_cmd", "sighup_dumps_octave_core",
+        "sigterm_dumps_octave_core", "silent_functions",
+        "single", "size", "size_equal", "sizemax",
+        "sizeof", "sleep", "source", "sparse_auto_mutate",
+        "split_long_rows", "sprintf", "squeeze", "sscanf",
+        "stat", "stderr", "stdin", "stdout", "strcmp",
+        "strcmpi", "string_fill_char", "strncmp",
+        "strncmpi", "struct", "struct_levels_to_print",
+        "strvcat", "subsasgn", "subsref", "sum", "sumsq",
+        "superiorto", "suppress_verbose_help_message",
+        "symlink", "system", "tic", "tilde_expand",
+        "times", "tmpfile", "tmpnam", "toc", "toupper",
+        "transpose", "true", "typeinfo", "umask", "uminus",
+        "uname", "undo_string_escapes", "unlink", "uplus",
+        "upper", "usage", "usleep", "vec", "vectorize",
+        "vertcat", "waitpid", "warning", "warranty",
+        "whos_line_format", "yes_or_no", "zeros",
+        "inf", "Inf", "nan", "NaN")
+
+    command_kw = ("close", "load", "who", "whos")
+
+    function_kw = (
+        "accumarray", "accumdim", "acosd", "acotd",
+        "acscd", "addtodate", "allchild", "ancestor",
+        "anova", "arch_fit", "arch_rnd", "arch_test",
+        "area", "arma_rnd", "arrayfun", "ascii", "asctime",
+        "asecd", "asind", "assert", "atand",
+        "autoreg_matrix", "autumn", "axes", "axis", "bar",
+        "barh", "bartlett", "bartlett_test", "beep",
+        "betacdf", "betainv", "betapdf", "betarnd",
+        "bicgstab", "bicubic", "binary", "binocdf",
+        "binoinv", "binopdf", "binornd", "bitcmp",
+        "bitget", "bitset", "blackman", "blanks",
+        "blkdiag", "bone", "box", "brighten", "calendar",
+        "cast", "cauchy_cdf", "cauchy_inv", "cauchy_pdf",
+        "cauchy_rnd", "caxis", "celldisp", "center", "cgs",
+        "chisquare_test_homogeneity",
+        "chisquare_test_independence", "circshift", "cla",
+        "clabel", "clf", "clock", "cloglog", "closereq",
+        "colon", "colorbar", "colormap", "colperm",
+        "comet", "common_size", "commutation_matrix",
+        "compan", "compare_versions", "compass",
+        "computer", "cond", "condest", "contour",
+        "contourc", "contourf", "contrast", "conv",
+        "convhull", "cool", "copper", "copyfile", "cor",
+        "corrcoef", "cor_test", "cosd", "cotd", "cov",
+        "cplxpair", "cross", "cscd", "cstrcat", "csvread",
+        "csvwrite", "ctime", "cumtrapz", "curl", "cut",
+        "cylinder", "date", "datenum", "datestr",
+        "datetick", "datevec", "dblquad", "deal",
+        "deblank", "deconv", "delaunay", "delaunayn",
+        "delete", "demo", "detrend", "diffpara", "diffuse",
+        "dir", "discrete_cdf", "discrete_inv",
+        "discrete_pdf", "discrete_rnd", "display",
+        "divergence", "dlmwrite", "dos", "dsearch",
+        "dsearchn", "duplication_matrix", "durbinlevinson",
+        "ellipsoid", "empirical_cdf", "empirical_inv",
+        "empirical_pdf", "empirical_rnd", "eomday",
+        "errorbar", "etime", "etreeplot", "example",
+        "expcdf", "expinv", "expm", "exppdf", "exprnd",
+        "ezcontour", "ezcontourf", "ezmesh", "ezmeshc",
+        "ezplot", "ezpolar", "ezsurf", "ezsurfc", "factor",
+        "factorial", "fail", "fcdf", "feather", "fftconv",
+        "fftfilt", "fftshift", "figure", "fileattrib",
+        "fileparts", "fill", "findall", "findobj",
+        "findstr", "finv", "flag", "flipdim", "fliplr",
+        "flipud", "fpdf", "fplot", "fractdiff", "freqz",
+        "freqz_plot", "frnd", "fsolve",
+        "f_test_regression", "ftp", "fullfile", "fzero",
+        "gamcdf", "gaminv", "gampdf", "gamrnd", "gca",
+        "gcbf", "gcbo", "gcf", "genvarname", "geocdf",
+        "geoinv", "geopdf", "geornd", "getfield", "ginput",
+        "glpk", "gls", "gplot", "gradient",
+        "graphics_toolkit", "gray", "grid", "griddata",
+        "griddatan", "gtext", "gunzip", "gzip", "hadamard",
+        "hamming", "hankel", "hanning", "hggroup",
+        "hidden", "hilb", "hist", "histc", "hold", "hot",
+        "hotelling_test", "housh", "hsv", "hurst",
+        "hygecdf", "hygeinv", "hygepdf", "hygernd",
+        "idivide", "ifftshift", "image", "imagesc",
+        "imfinfo", "imread", "imshow", "imwrite", "index",
+        "info", "inpolygon", "inputname", "interpft",
+        "interpn", "intersect", "invhilb", "iqr", "isa",
+        "isdefinite", "isdir", "is_duplicate_entry",
+        "isequal", "isequalwithequalnans", "isfigure",
+        "ishermitian", "ishghandle", "is_leap_year",
+        "isletter", "ismac", "ismember", "ispc", "isprime",
+        "isprop", "isscalar", "issquare", "isstrprop",
+        "issymmetric", "isunix", "is_valid_file_id",
+        "isvector", "jet", "kendall",
+        "kolmogorov_smirnov_cdf",
+        "kolmogorov_smirnov_test", "kruskal_wallis_test",
+        "krylov", "kurtosis", "laplace_cdf", "laplace_inv",
+        "laplace_pdf", "laplace_rnd", "legend", "legendre",
+        "license", "line", "linkprop", "list_primes",
+        "loadaudio", "loadobj", "logistic_cdf",
+        "logistic_inv", "logistic_pdf", "logistic_rnd",
+        "logit", "loglog", "loglogerr", "logm", "logncdf",
+        "logninv", "lognpdf", "lognrnd", "logspace",
+        "lookfor", "ls_command", "lsqnonneg", "magic",
+        "mahalanobis", "manova", "matlabroot",
+        "mcnemar_test", "mean", "meansq", "median", "menu",
+        "mesh", "meshc", "meshgrid", "meshz", "mexext",
+        "mget", "mkpp", "mode", "moment", "movefile",
+        "mpoles", "mput", "namelengthmax", "nargchk",
+        "nargoutchk", "nbincdf", "nbininv", "nbinpdf",
+        "nbinrnd", "nchoosek", "ndgrid", "newplot", "news",
+        "nonzeros", "normcdf", "normest", "norminv",
+        "normpdf", "normrnd", "now", "nthroot", "null",
+        "ocean", "ols", "onenormest", "optimget",
+        "optimset", "orderfields", "orient", "orth",
+        "pack", "pareto", "parseparams", "pascal", "patch",
+        "pathdef", "pcg", "pchip", "pcolor", "pcr",
+        "peaks", "periodogram", "perl", "perms", "pie",
+        "pink", "planerot", "playaudio", "plot",
+        "plotmatrix", "plotyy", "poisscdf", "poissinv",
+        "poisspdf", "poissrnd", "polar", "poly",
+        "polyaffine", "polyarea", "polyderiv", "polyfit",
+        "polygcd", "polyint", "polyout", "polyreduce",
+        "polyval", "polyvalm", "postpad", "powerset",
+        "ppder", "ppint", "ppjumps", "ppplot", "ppval",
+        "pqpnonneg", "prepad", "primes", "print",
+        "print_usage", "prism", "probit", "qp", "qqplot",
+        "quadcc", "quadgk", "quadl", "quadv", "quiver",
+        "qzhess", "rainbow", "randi", "range", "rank",
+        "ranks", "rat", "reallog", "realpow", "realsqrt",
+        "record", "rectangle_lw", "rectangle_sw",
+        "rectint", "refresh", "refreshdata",
+        "regexptranslate", "repmat", "residue", "ribbon",
+        "rindex", "roots", "rose", "rosser", "rotdim",
+        "rref", "run", "run_count", "rundemos", "run_test",
+        "runtests", "saveas", "saveaudio", "saveobj",
+        "savepath", "scatter", "secd", "semilogx",
+        "semilogxerr", "semilogy", "semilogyerr",
+        "setaudio", "setdiff", "setfield", "setxor",
+        "shading", "shift", "shiftdim", "sign_test",
+        "sinc", "sind", "sinetone", "sinewave", "skewness",
+        "slice", "sombrero", "sortrows", "spaugment",
+        "spconvert", "spdiags", "spearman", "spectral_adf",
+        "spectral_xdf", "specular", "speed", "spencer",
+        "speye", "spfun", "sphere", "spinmap", "spline",
+        "spones", "sprand", "sprandn", "sprandsym",
+        "spring", "spstats", "spy", "sqp", "stairs",
+        "statistics", "std", "stdnormal_cdf",
+        "stdnormal_inv", "stdnormal_pdf", "stdnormal_rnd",
+        "stem", "stft", "strcat", "strchr", "strjust",
+        "strmatch", "strread", "strsplit", "strtok",
+        "strtrim", "strtrunc", "structfun", "studentize",
+        "subplot", "subsindex", "subspace", "substr",
+        "substruct", "summer", "surf", "surface", "surfc",
+        "surfl", "surfnorm", "svds", "swapbytes",
+        "sylvester_matrix", "symvar", "synthesis", "table",
+        "tand", "tar", "tcdf", "tempdir", "tempname",
+        "test", "text", "textread", "textscan", "tinv",
+        "title", "toeplitz", "tpdf", "trace", "trapz",
+        "treelayout", "treeplot", "triangle_lw",
+        "triangle_sw", "tril", "trimesh", "triplequad",
+        "triplot", "trisurf", "triu", "trnd", "tsearchn",
+        "t_test", "t_test_regression", "type", "unidcdf",
+        "unidinv", "unidpdf", "unidrnd", "unifcdf",
+        "unifinv", "unifpdf", "unifrnd", "union", "unique",
+        "unix", "unmkpp", "unpack", "untabify", "untar",
+        "unwrap", "unzip", "u_test", "validatestring",
+        "vander", "var", "var_test", "vech", "ver",
+        "version", "view", "voronoi", "voronoin",
+        "waitforbuttonpress", "wavread", "wavwrite",
+        "wblcdf", "wblinv", "wblpdf", "wblrnd", "weekday",
+        "welch_test", "what", "white", "whitebg",
+        "wienrnd", "wilcoxon_test", "wilkinson", "winter",
+        "xlabel", "xlim", "ylabel", "yulewalker", "zip",
+        "zlabel", "z_test")
+
+    loadable_kw = (
+        "airy", "amd", "balance", "besselh", "besseli",
+        "besselj", "besselk", "bessely", "bitpack",
+        "bsxfun", "builtin", "ccolamd", "cellfun",
+        "cellslices", "chol", "choldelete", "cholinsert",
+        "cholinv", "cholshift", "cholupdate", "colamd",
+        "colloc", "convhulln", "convn", "csymamd",
+        "cummax", "cummin", "daspk", "daspk_options",
+        "dasrt", "dasrt_options", "dassl", "dassl_options",
+        "dbclear", "dbdown", "dbstack", "dbstatus",
+        "dbstop", "dbtype", "dbup", "dbwhere", "det",
+        "dlmread", "dmperm", "dot", "eig", "eigs",
+        "endgrent", "endpwent", "etree", "fft", "fftn",
+        "fftw", "filter", "find", "full", "gcd",
+        "getgrent", "getgrgid", "getgrnam", "getpwent",
+        "getpwnam", "getpwuid", "getrusage", "givens",
+        "gmtime", "gnuplot_binary", "hess", "ifft",
+        "ifftn", "inv", "isdebugmode", "issparse", "kron",
+        "localtime", "lookup", "lsode", "lsode_options",
+        "lu", "luinc", "luupdate", "matrix_type", "max",
+        "min", "mktime", "pinv", "qr", "qrdelete",
+        "qrinsert", "qrshift", "qrupdate", "quad",
+        "quad_options", "qz", "rand", "rande", "randg",
+        "randn", "randp", "randperm", "rcond", "regexp",
+        "regexpi", "regexprep", "schur", "setgrent",
+        "setpwent", "sort", "spalloc", "sparse", "spparms",
+        "sprank", "sqrtm", "strfind", "strftime",
+        "strptime", "strrep", "svd", "svd_driver", "syl",
+        "symamd", "symbfact", "symrcm", "time", "tsearch",
+        "typecast", "urlread", "urlwrite")
+
+    mapping_kw = (
+        "abs", "acos", "acosh", "acot", "acoth", "acsc",
+        "acsch", "angle", "arg", "asec", "asech", "asin",
+        "asinh", "atan", "atanh", "beta", "betainc",
+        "betaln", "bincoeff", "cbrt", "ceil", "conj", "cos",
+        "cosh", "cot", "coth", "csc", "csch", "erf", "erfc",
+        "erfcx", "erfinv", "exp", "finite", "fix", "floor",
+        "fmod", "gamma", "gammainc", "gammaln", "imag",
+        "isalnum", "isalpha", "isascii", "iscntrl",
+        "isdigit", "isfinite", "isgraph", "isinf",
+        "islower", "isna", "isnan", "isprint", "ispunct",
+        "isspace", "isupper", "isxdigit", "lcm", "lgamma",
+        "log", "lower", "mod", "real", "rem", "round",
+        "roundb", "sec", "sech", "sign", "sin", "sinh",
+        "sqrt", "tan", "tanh", "toascii", "tolower", "xor")
+
+    builtin_consts = (
+        "EDITOR", "EXEC_PATH", "I", "IMAGE_PATH", "NA",
+        "OCTAVE_HOME", "OCTAVE_VERSION", "PAGER",
+        "PAGER_FLAGS", "SEEK_CUR", "SEEK_END", "SEEK_SET",
+        "SIG", "S_ISBLK", "S_ISCHR", "S_ISDIR", "S_ISFIFO",
+        "S_ISLNK", "S_ISREG", "S_ISSOCK", "WCONTINUE",
+        "WCOREDUMP", "WEXITSTATUS", "WIFCONTINUED",
+        "WIFEXITED", "WIFSIGNALED", "WIFSTOPPED", "WNOHANG",
+        "WSTOPSIG", "WTERMSIG", "WUNTRACED")
+
+    tokens = {
+        'root': [
+            (r'%\{\s*\n', Comment.Multiline, 'percentblockcomment'),
+            (r'#\{\s*\n', Comment.Multiline, 'hashblockcomment'),
+            (r'[%#].*$', Comment),
+            (r'^\s*function\b', Keyword, 'deffunc'),
+
+            # from 'iskeyword' on hg changeset 8cc154f45e37
+            (words((
+                '__FILE__', '__LINE__', 'break', 'case', 'catch', 'classdef',
+                'continue', 'do', 'else', 'elseif', 'end', 'end_try_catch',
+                'end_unwind_protect', 'endclassdef', 'endevents', 'endfor',
+                'endfunction', 'endif', 'endmethods', 'endproperties', 'endswitch',
+                'endwhile', 'events', 'for', 'function', 'get', 'global', 'if',
+                'methods', 'otherwise', 'persistent', 'properties', 'return',
+                'set', 'static', 'switch', 'try', 'until', 'unwind_protect',
+                'unwind_protect_cleanup', 'while'), suffix=r'\b'),
+             Keyword),
+
+            (words(builtin_kw + command_kw + function_kw + loadable_kw + mapping_kw,
+                   suffix=r'\b'),  Name.Builtin),
+
+            (words(builtin_consts, suffix=r'\b'), Name.Constant),
+
+            # operators in Octave but not Matlab:
+            (r'-=|!=|!|/=|--', Operator),
+            # operators:
+            (r'-|==|~=|<|>|<=|>=|&&|&|~|\|\|?', Operator),
+            # operators in Octave but not Matlab requiring escape for re:
+            (r'\*=|\+=|\^=|\/=|\\=|\*\*|\+\+|\.\*\*', Operator),
+            # operators requiring escape for re:
+            (r'\.\*|\*|\+|\.\^|\^|\.\\|\.\/|\/|\\', Operator),
+
+
+            # punctuation:
+            (r'[\[\](){}:@.,]', Punctuation),
+            (r'=|:|;', Punctuation),
+
+            (r'"[^"]*"', String),
+
+            (r'(\d+\.\d*|\d*\.\d+)([eEf][+-]?[0-9]+)?', Number.Float),
+            (r'\d+[eEf][+-]?[0-9]+', Number.Float),
+            (r'\d+', Number.Integer),
+
+            # quote can be transpose, instead of string:
+            # (not great, but handles common cases...)
+            (r'(?<=[\w)\].])\'+', Operator),
+            (r'(?|<=|>=|&&|&|~|\|\|?', Operator),
+            # operators requiring escape for re:
+            (r'\.\*|\*|\+|\.\^|\^|\.\\|\.\/|\/|\\', Operator),
+
+            # punctuation:
+            (r'[\[\](){}@.,=:;]+', Punctuation),
+
+            (r'"[^"]*"', String),
+
+            # quote can be transpose, instead of string:
+            # (not great, but handles common cases...)
+            (r'(?<=[\w)\].])\'+', Operator),
+            (r'(?', r'<', r'|', r'!', r"'")
+
+    operator_words = ('and', 'or', 'not')
+
+    tokens = {
+        'root': [
+            (r'/\*', Comment.Multiline, 'comment'),
+            (r'"(?:[^"\\]|\\.)*"', String),
+            (r'\(|\)|\[|\]|\{|\}', Punctuation),
+            (r'[,;$]', Punctuation),
+            (words (constants), Name.Constant),
+            (words (keywords), Keyword),
+            (words (operators), Operator),
+            (words (operator_words), Operator.Word),
+            (r'''(?x)
+              ((?:[a-zA-Z_#][\w#]*|`[^`]*`)
+              (?:::[a-zA-Z_#][\w#]*|`[^`]*`)*)(\s*)([(])''',
+             bygroups(Name.Function, Text.Whitespace, Punctuation)),
+            (r'''(?x)
+              (?:[a-zA-Z_#%][\w#%]*|`[^`]*`)
+              (?:::[a-zA-Z_#%][\w#%]*|`[^`]*`)*''', Name.Variable),
+            (r'[-+]?(\d*\.\d+([bdefls][-+]?\d+)?|\d+(\.\d*)?[bdefls][-+]?\d+)', Number.Float),
+            (r'[-+]?\d+', Number.Integer),
+            (r'\s+', Text.Whitespace),
+            (r'.', Text)
+        ],
+        'comment': [
+            (r'[^*/]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[*/]', Comment.Multiline)
+        ]
+    }
+
+    def analyse_text (text):
+        strength = 0.0
+        # Input expression terminator.
+        if re.search (r'\$\s*$', text, re.MULTILINE):
+            strength += 0.05
+        # Function definition operator.
+        if ':=' in text:
+            strength += 0.02
+        return strength
diff --git a/.venv/Lib/site-packages/pygments/lexers/meson.py b/.venv/Lib/site-packages/pygments/lexers/meson.py
new file mode 100644
index 0000000..6f2c6da
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/meson.py
@@ -0,0 +1,139 @@
+"""
+    pygments.lexers.meson
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Pygments lexer for the Meson build system
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words, include
+from pygments.token import Comment, Name, Number, Punctuation, Operator, \
+    Keyword, String, Whitespace
+
+__all__ = ['MesonLexer']
+
+
+class MesonLexer(RegexLexer):
+    """Meson language lexer.
+
+    The grammar definition use to transcribe the syntax was retrieved from
+    https://mesonbuild.com/Syntax.html#grammar for version 0.58.
+    Some of those definitions are improperly transcribed, so the Meson++
+    implementation was also checked: https://github.com/dcbaker/meson-plus-plus.
+    """
+
+    # TODO String interpolation @VARNAME@ inner matches
+    # TODO keyword_arg: value inner matches
+
+    name = 'Meson'
+    url = 'https://mesonbuild.com/'
+    aliases = ['meson', 'meson.build']
+    filenames = ['meson.build', 'meson_options.txt']
+    mimetypes = ['text/x-meson']
+    version_added = '2.10'
+
+    tokens = {
+        'root': [
+            (r'#.*?$', Comment),
+            (r"'''.*'''", String.Single),
+            (r'[1-9][0-9]*', Number.Integer),
+            (r'0o[0-7]+', Number.Oct),
+            (r'0x[a-fA-F0-9]+', Number.Hex),
+            include('string'),
+            include('keywords'),
+            include('expr'),
+            (r'[a-zA-Z_][a-zA-Z_0-9]*', Name),
+            (r'\s+', Whitespace),
+        ],
+        'string': [
+            (r"[']{3}([']{0,2}([^\\']|\\(.|\n)))*[']{3}", String),
+            (r"'.*?(?`_.
+    """
+
+    name = "MCFunction"
+    url = "https://minecraft.wiki/w/Commands"
+    aliases = ["mcfunction", "mcf"]
+    filenames = ["*.mcfunction"]
+    mimetypes = ["text/mcfunction"]
+    version_added = '2.12'
+
+    # Used to denotate the start of a block comment, borrowed from Github's mcfunction
+    _block_comment_prefix = "[>!]"
+
+    tokens = {
+        "root": [
+            include("names"),
+            include("comments"),
+            include("literals"),
+            include("whitespace"),
+            include("property"),
+            include("operators"),
+            include("selectors"),
+        ],
+
+        "names": [
+            # The start of a command (either beginning of line OR after the run keyword)
+            #  We don't encode a list of keywords since mods, plugins, or even pre-processors
+            #  may add new commands, so we have a 'close-enough' regex which catches them.
+            (r"^(\s*)([a-z_]+)", bygroups(Whitespace, Name.Builtin)),
+            (r"(?<=run)\s+[a-z_]+", Name.Builtin),
+
+            # UUID
+            (r"\b[0-9a-fA-F]+(?:-[0-9a-fA-F]+){4}\b", Name.Variable),
+            include("resource-name"),
+            # normal command names and scoreboards
+            #  there's no way to know the differences unfortuntely
+            (r"[A-Za-z_][\w.#%$]+", Keyword.Constant),
+            (r"[#%$][\w.#%$]+", Name.Variable.Magic),
+        ],
+
+        "resource-name": [
+            # resource names have to be lowercase
+            (r"#?[a-z_][a-z_.-]*:[a-z0-9_./-]+", Name.Function),
+            # similar to above except optional `:``
+            #  a `/` must be present "somewhere"
+            (r"#?[a-z0-9_\.\-]+\/[a-z0-9_\.\-\/]+", Name.Function),
+        ],
+
+        "whitespace": [
+            (r"\s+", Whitespace),
+        ],
+
+        "comments": [
+            (rf"^\s*(#{_block_comment_prefix})", Comment.Multiline,
+             ("comments.block", "comments.block.emphasized")),
+            (r"#.*$", Comment.Single),
+        ],
+        "comments.block": [
+            (rf"^\s*#{_block_comment_prefix}", Comment.Multiline,
+             "comments.block.emphasized"),
+            (r"^\s*#", Comment.Multiline, "comments.block.normal"),
+            default("#pop"),
+        ],
+        "comments.block.normal": [
+            include("comments.block.special"),
+            (r"\S+", Comment.Multiline),
+            (r"\n", Text, "#pop"),
+            include("whitespace"),
+        ],
+        "comments.block.emphasized": [
+            include("comments.block.special"),
+            (r"\S+", String.Doc),
+            (r"\n", Text, "#pop"),
+            include("whitespace"),
+        ],
+        "comments.block.special": [
+            # Params
+            (r"@\S+", Name.Decorator),
+
+            include("resource-name"),
+
+            # Scoreboard player names
+            (r"[#%$][\w.#%$]+", Name.Variable.Magic),
+        ],
+
+        "operators": [
+            (r"[\-~%^?!+*<>\\/|&=.]", Operator),
+        ],
+
+        "literals": [
+            (r"\.\.", Literal),
+            (r"(true|false)", Keyword.Pseudo),
+
+            # these are like unquoted strings and appear in many places
+            (r"[A-Za-z_]+", Name.Variable.Class),
+
+            (r"[0-7]b", Number.Byte),
+            (r"[+-]?\d*\.?\d+([eE]?[+-]?\d+)?[df]?\b", Number.Float),
+            (r"[+-]?\d+\b", Number.Integer),
+            (r'"', String.Double, "literals.string-double"),
+            (r"'", String.Single, "literals.string-single"),
+        ],
+        "literals.string-double": [
+            (r"\\.", String.Escape),
+            (r'[^\\"\n]+', String.Double),
+            (r'"', String.Double, "#pop"),
+        ],
+        "literals.string-single": [
+            (r"\\.", String.Escape),
+            (r"[^\\'\n]+", String.Single),
+            (r"'", String.Single, "#pop"),
+        ],
+
+        "selectors": [
+            (r"@[a-z]", Name.Variable),
+        ],
+
+
+        ## Generic Property Container
+        # There are several, differing instances where the language accepts
+        #  specific contained keys or contained key, value pairings.
+        #
+        # Property Maps:
+        # - Starts with either `[` or `{`
+        # - Key separated by `:` or `=`
+        # - Deliminated by `,`
+        #
+        # Property Lists:
+        # - Starts with `[`
+        # - Deliminated by `,`
+        #
+        # For simplicity, these patterns match a generic, nestable structure
+        #  which follow a key, value pattern. For normal lists, there's only keys.
+        # This allow some "illegal" structures, but we'll accept those for
+        #  sake of simplicity
+        #
+        # Examples:
+        # - `[facing=up, powered=true]` (blockstate)
+        # - `[name="hello world", nbt={key: 1b}]` (selector + nbt)
+        # - `[{"text": "value"}, "literal"]` (json)
+        ##
+        "property": [
+            # This state gets included in root and also several substates
+            # We do this to shortcut the starting of new properties
+            #  within other properties. Lists can have sublists and compounds
+            #  and values can start a new property (see the `difficult_1.txt`
+            #  snippet).
+            (r"\{", Punctuation, ("property.curly", "property.key")),
+            (r"\[", Punctuation, ("property.square", "property.key")),
+        ],
+        "property.curly": [
+            include("whitespace"),
+            include("property"),
+            (r"\}", Punctuation, "#pop"),
+        ],
+        "property.square": [
+            include("whitespace"),
+            include("property"),
+            (r"\]", Punctuation, "#pop"),
+
+            # lists can have sequences of items
+            (r",", Punctuation),
+        ],
+        "property.key": [
+            include("whitespace"),
+
+            # resource names (for advancements)
+            #  can omit `:` to default `minecraft:`
+            # must check if there is a future equals sign if `:` is in the name
+            (r"#?[a-z_][a-z_\.\-]*\:[a-z0-9_\.\-/]+(?=\s*\=)", Name.Attribute, "property.delimiter"),
+            (r"#?[a-z_][a-z0-9_\.\-/]+", Name.Attribute, "property.delimiter"),
+
+            # unquoted NBT key
+            (r"[A-Za-z_\-\+]+", Name.Attribute, "property.delimiter"),
+
+            # quoted JSON or NBT key
+            (r'"', Name.Attribute, "property.delimiter", "literals.string-double"),
+            (r"'", Name.Attribute, "property.delimiter", "literals.string-single"),
+
+            # index for a list
+            (r"-?\d+", Number.Integer, "property.delimiter"),
+
+            default("#pop"),
+        ],
+        "property.key.string-double": [
+            (r"\\.", String.Escape),
+            (r'[^\\"\n]+', Name.Attribute),
+            (r'"', Name.Attribute, "#pop"),
+        ],
+        "property.key.string-single": [
+            (r"\\.", String.Escape),
+            (r"[^\\'\n]+", Name.Attribute),
+            (r"'", Name.Attribute, "#pop"),
+        ],
+        "property.delimiter": [
+            include("whitespace"),
+
+            (r"[:=]!?", Punctuation, "property.value"),
+            (r",", Punctuation),
+
+            default("#pop"),
+        ],
+        "property.value": [
+            include("whitespace"),
+
+            # unquoted resource names are valid literals here
+            (r"#?[a-z_][a-z_\.\-]*\:[a-z0-9_\.\-/]+", Name.Tag),
+            (r"#?[a-z_][a-z0-9_\.\-/]+", Name.Tag),
+
+            include("literals"),
+            include("property"),
+
+            default("#pop"),
+        ],
+    }
+
+
+class MCSchemaLexer(RegexLexer):
+    """Lexer for Minecraft Add-ons data Schemas, an interface structure standard used in Minecraft
+    """
+
+    name = 'MCSchema'
+    url = 'https://learn.microsoft.com/en-us/minecraft/creator/reference/content/schemasreference/'
+    aliases = ['mcschema']
+    filenames = ['*.mcschema']
+    mimetypes = ['text/mcschema']
+    version_added = '2.14'
+
+    tokens = {
+        'commentsandwhitespace': [
+            (r'\s+', Whitespace),
+            (r'//.*?$', Comment.Single),
+            (r'/\*.*?\*/', Comment.Multiline)
+        ],
+        'slashstartsregex': [
+            include('commentsandwhitespace'),
+            (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
+             r'([gimuysd]+\b|\B)', String.Regex, '#pop'),
+            (r'(?=/)', Text, ('#pop', 'badregex')),
+            default('#pop')
+        ],
+        'badregex': [
+            (r'\n', Whitespace, '#pop')
+        ],
+        'singlestring': [
+            (r'\\.', String.Escape),
+            (r"'", String.Single, '#pop'),
+            (r"[^\\']+", String.Single),
+        ],
+        'doublestring': [
+            (r'\\.', String.Escape),
+            (r'"', String.Double, '#pop'),
+            (r'[^\\"]+', String.Double),
+        ],
+        'root': [
+            (r'^(?=\s|/|', Comment, '#pop'),
+            (r'[^\-]+|-', Comment),
+        ],
+    }
+
+
+class ReasonLexer(RegexLexer):
+    """
+    For the ReasonML language.
+    """
+
+    name = 'ReasonML'
+    url = 'https://reasonml.github.io/'
+    aliases = ['reasonml', 'reason']
+    filenames = ['*.re', '*.rei']
+    mimetypes = ['text/x-reasonml']
+    version_added = '2.6'
+
+    keywords = (
+        'as', 'assert', 'begin', 'class', 'constraint', 'do', 'done', 'downto',
+        'else', 'end', 'exception', 'external', 'false', 'for', 'fun', 'esfun',
+        'function', 'functor', 'if', 'in', 'include', 'inherit', 'initializer', 'lazy',
+        'let', 'switch', 'module', 'pub', 'mutable', 'new', 'nonrec', 'object', 'of',
+        'open', 'pri', 'rec', 'sig', 'struct', 'then', 'to', 'true', 'try',
+        'type', 'val', 'virtual', 'when', 'while', 'with',
+    )
+    keyopts = (
+        '!=', '#', '&', '&&', r'\(', r'\)', r'\*', r'\+', ',', '-',
+        r'-\.', '=>', r'\.', r'\.\.', r'\.\.\.', ':', '::', ':=', ':>', ';', ';;', '<',
+        '<-', '=', '>', '>]', r'>\}', r'\?', r'\?\?', r'\[', r'\[<', r'\[>',
+        r'\[\|', ']', '_', '`', r'\{', r'\{<', r'\|', r'\|\|', r'\|]', r'\}', '~'
+    )
+
+    operators = r'[!$%&*+\./:<=>?@^|~-]'
+    word_operators = ('and', 'asr', 'land', 'lor', 'lsl', 'lsr', 'lxor', 'mod', 'or')
+    prefix_syms = r'[!?~]'
+    infix_syms = r'[=<>@^|&+\*/$%-]'
+    primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array')
+
+    tokens = {
+        'escape-sequence': [
+            (r'\\[\\"\'ntbr]', String.Escape),
+            (r'\\[0-9]{3}', String.Escape),
+            (r'\\x[0-9a-fA-F]{2}', String.Escape),
+        ],
+        'root': [
+            (r'\s+', Text),
+            (r'false|true|\(\)|\[\]', Name.Builtin.Pseudo),
+            (r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'),
+            (r'\b([A-Z][\w\']*)', Name.Class),
+            (r'//.*?\n', Comment.Single),
+            (r'\/\*(?!/)', Comment.Multiline, 'comment'),
+            (r'\b({})\b'.format('|'.join(keywords)), Keyword),
+            (r'({})'.format('|'.join(keyopts[::-1])), Operator.Word),
+            (rf'({infix_syms}|{prefix_syms})?{operators}', Operator),
+            (r'\b({})\b'.format('|'.join(word_operators)), Operator.Word),
+            (r'\b({})\b'.format('|'.join(primitives)), Keyword.Type),
+
+            (r"[^\W\d][\w']*", Name),
+
+            (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float),
+            (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex),
+            (r'0[oO][0-7][0-7_]*', Number.Oct),
+            (r'0[bB][01][01_]*', Number.Bin),
+            (r'\d[\d_]*', Number.Integer),
+
+            (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
+             String.Char),
+            (r"'.'", String.Char),
+            (r"'", Keyword),
+
+            (r'"', String.Double, 'string'),
+
+            (r'[~?][a-z][\w\']*:', Name.Variable),
+        ],
+        'comment': [
+            (r'[^/*]+', Comment.Multiline),
+            (r'\/\*', Comment.Multiline, '#push'),
+            (r'\*\/', Comment.Multiline, '#pop'),
+            (r'\*', Comment.Multiline),
+        ],
+        'string': [
+            (r'[^\\"]+', String.Double),
+            include('escape-sequence'),
+            (r'\\\n', String.Double),
+            (r'"', String.Double, '#pop'),
+        ],
+        'dotted': [
+            (r'\s+', Text),
+            (r'\.', Punctuation),
+            (r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace),
+            (r'[A-Z][\w\']*', Name.Class, '#pop'),
+            (r'[a-z_][\w\']*', Name, '#pop'),
+            default('#pop'),
+        ],
+    }
+
+
+class FStarLexer(RegexLexer):
+    """
+    For the F* language.
+    """
+
+    name = 'FStar'
+    url = 'https://www.fstar-lang.org/'
+    aliases = ['fstar']
+    filenames = ['*.fst', '*.fsti']
+    mimetypes = ['text/x-fstar']
+    version_added = '2.7'
+
+    keywords = (
+        'abstract', 'attributes', 'noeq', 'unopteq', 'and'
+        'begin', 'by', 'default', 'effect', 'else', 'end', 'ensures',
+        'exception', 'exists', 'false', 'forall', 'fun', 'function', 'if',
+        'in', 'include', 'inline', 'inline_for_extraction', 'irreducible',
+        'logic', 'match', 'module', 'mutable', 'new', 'new_effect', 'noextract',
+        'of', 'open', 'opaque', 'private', 'range_of', 'reifiable',
+        'reify', 'reflectable', 'requires', 'set_range_of', 'sub_effect',
+        'synth', 'then', 'total', 'true', 'try', 'type', 'unfold', 'unfoldable',
+        'val', 'when', 'with', 'not'
+    )
+    decl_keywords = ('let', 'rec')
+    assume_keywords = ('assume', 'admit', 'assert', 'calc')
+    keyopts = (
+        r'~', r'-', r'/\\', r'\\/', r'<:', r'<@', r'\(\|', r'\|\)', r'#', r'u#',
+        r'&', r'\(', r'\)', r'\(\)', r',', r'~>', r'->', r'<-', r'<--', r'<==>',
+        r'==>', r'\.', r'\?', r'\?\.', r'\.\[', r'\.\(', r'\.\(\|', r'\.\[\|',
+        r'\{:pattern', r':', r'::', r':=', r';', r';;', r'=', r'%\[', r'!\{',
+        r'\[', r'\[@', r'\[\|', r'\|>', r'\]', r'\|\]', r'\{', r'\|', r'\}', r'\$'
+    )
+
+    operators = r'[!$%&*+\./:<=>?@^|~-]'
+    prefix_syms = r'[!?~]'
+    infix_syms = r'[=<>@^|&+\*/$%-]'
+    primitives = ('unit', 'int', 'float', 'bool', 'string', 'char', 'list', 'array')
+
+    tokens = {
+        'escape-sequence': [
+            (r'\\[\\"\'ntbr]', String.Escape),
+            (r'\\[0-9]{3}', String.Escape),
+            (r'\\x[0-9a-fA-F]{2}', String.Escape),
+        ],
+        'root': [
+            (r'\s+', Text),
+            (r'false|true|False|True|\(\)|\[\]', Name.Builtin.Pseudo),
+            (r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Namespace, 'dotted'),
+            (r'\b([A-Z][\w\']*)', Name.Class),
+            (r'\(\*(?![)])', Comment, 'comment'),
+            (r'\/\/.+$', Comment),
+            (r'\b({})\b'.format('|'.join(keywords)), Keyword),
+            (r'\b({})\b'.format('|'.join(assume_keywords)), Name.Exception),
+            (r'\b({})\b'.format('|'.join(decl_keywords)), Keyword.Declaration),
+            (r'({})'.format('|'.join(keyopts[::-1])), Operator),
+            (rf'({infix_syms}|{prefix_syms})?{operators}', Operator),
+            (r'\b({})\b'.format('|'.join(primitives)), Keyword.Type),
+
+            (r"[^\W\d][\w']*", Name),
+
+            (r'-?\d[\d_]*(.[\d_]*)?([eE][+\-]?\d[\d_]*)', Number.Float),
+            (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex),
+            (r'0[oO][0-7][0-7_]*', Number.Oct),
+            (r'0[bB][01][01_]*', Number.Bin),
+            (r'\d[\d_]*', Number.Integer),
+
+            (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
+             String.Char),
+            (r"'.'", String.Char),
+            (r"'", Keyword),  # a stray quote is another syntax element
+            (r"\`([\w\'.]+)\`", Operator.Word),  # for infix applications
+            (r"\`", Keyword),  # for quoting
+            (r'"', String.Double, 'string'),
+
+            (r'[~?][a-z][\w\']*:', Name.Variable),
+        ],
+        'comment': [
+            (r'[^(*)]+', Comment),
+            (r'\(\*', Comment, '#push'),
+            (r'\*\)', Comment, '#pop'),
+            (r'[(*)]', Comment),
+        ],
+        'string': [
+            (r'[^\\"]+', String.Double),
+            include('escape-sequence'),
+            (r'\\\n', String.Double),
+            (r'"', String.Double, '#pop'),
+        ],
+        'dotted': [
+            (r'\s+', Text),
+            (r'\.', Punctuation),
+            (r'[A-Z][\w\']*(?=\s*\.)', Name.Namespace),
+            (r'[A-Z][\w\']*', Name.Class, '#pop'),
+            (r'[a-z_][\w\']*', Name, '#pop'),
+            default('#pop'),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/modeling.py b/.venv/Lib/site-packages/pygments/lexers/modeling.py
new file mode 100644
index 0000000..d681e7f
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/modeling.py
@@ -0,0 +1,366 @@
+"""
+    pygments.lexers.modeling
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for modeling languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, bygroups, using, default
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Whitespace
+
+from pygments.lexers.html import HtmlLexer
+from pygments.lexers import _stan_builtins
+
+__all__ = ['ModelicaLexer', 'BugsLexer', 'JagsLexer', 'StanLexer']
+
+
+class ModelicaLexer(RegexLexer):
+    """
+    For Modelica source code.
+    """
+    name = 'Modelica'
+    url = 'http://www.modelica.org/'
+    aliases = ['modelica']
+    filenames = ['*.mo']
+    mimetypes = ['text/x-modelica']
+    version_added = '1.1'
+
+    flags = re.DOTALL | re.MULTILINE
+
+    _name = r"(?:'(?:[^\\']|\\.)+'|[a-zA-Z_]\w*)"
+
+    tokens = {
+        'whitespace': [
+            (r'[\s\ufeff]+', Text),
+            (r'//[^\n]*\n?', Comment.Single),
+            (r'/\*.*?\*/', Comment.Multiline)
+        ],
+        'root': [
+            include('whitespace'),
+            (r'"', String.Double, 'string'),
+            (r'[()\[\]{},;]+', Punctuation),
+            (r'\.?[*^/+-]|\.|<>|[<>:=]=?', Operator),
+            (r'\d+(\.?\d*[eE][-+]?\d+|\.\d*)', Number.Float),
+            (r'\d+', Number.Integer),
+            (r'(abs|acos|actualStream|array|asin|assert|AssertionLevel|atan|'
+             r'atan2|backSample|Boolean|cardinality|cat|ceil|change|Clock|'
+             r'Connections|cos|cosh|cross|delay|diagonal|div|edge|exp|'
+             r'ExternalObject|fill|floor|getInstanceName|hold|homotopy|'
+             r'identity|inStream|integer|Integer|interval|inverse|isPresent|'
+             r'linspace|log|log10|matrix|max|min|mod|ndims|noClock|noEvent|'
+             r'ones|outerProduct|pre|previous|product|Real|reinit|rem|rooted|'
+             r'sample|scalar|semiLinear|shiftSample|sign|sin|sinh|size|skew|'
+             r'smooth|spatialDistribution|sqrt|StateSelect|String|subSample|'
+             r'sum|superSample|symmetric|tan|tanh|terminal|terminate|time|'
+             r'transpose|vector|zeros)\b', Name.Builtin),
+            (r'(algorithm|annotation|break|connect|constant|constrainedby|der|'
+             r'discrete|each|else|elseif|elsewhen|encapsulated|enumeration|'
+             r'equation|exit|expandable|extends|external|firstTick|final|flow|for|if|'
+             r'import|impure|in|initial|inner|input|interval|loop|nondiscrete|outer|'
+             r'output|parameter|partial|protected|public|pure|redeclare|'
+             r'replaceable|return|stream|then|when|while)\b',
+             Keyword.Reserved),
+            (r'(and|not|or)\b', Operator.Word),
+            (r'(block|class|connector|end|function|model|operator|package|'
+             r'record|type)\b', Keyword.Reserved, 'class'),
+            (r'(false|true)\b', Keyword.Constant),
+            (r'within\b', Keyword.Reserved, 'package-prefix'),
+            (_name, Name)
+        ],
+        'class': [
+            include('whitespace'),
+            (r'(function|record)\b', Keyword.Reserved),
+            (r'(if|for|when|while)\b', Keyword.Reserved, '#pop'),
+            (_name, Name.Class, '#pop'),
+            default('#pop')
+        ],
+        'package-prefix': [
+            include('whitespace'),
+            (_name, Name.Namespace, '#pop'),
+            default('#pop')
+        ],
+        'string': [
+            (r'"', String.Double, '#pop'),
+            (r'\\[\'"?\\abfnrtv]', String.Escape),
+            (r'(?i)<\s*html\s*>([^\\"]|\\.)+?(<\s*/\s*html\s*>|(?="))',
+             using(HtmlLexer)),
+            (r'<|\\?[^"\\<]+', String.Double)
+        ]
+    }
+
+
+class BugsLexer(RegexLexer):
+    """
+    Pygments Lexer for OpenBugs and WinBugs
+    models.
+    """
+
+    name = 'BUGS'
+    aliases = ['bugs', 'winbugs', 'openbugs']
+    filenames = ['*.bug']
+    url = 'https://www.mrc-bsu.cam.ac.uk/software/bugs/openbugs'
+    version_added = '1.6'
+
+    _FUNCTIONS = (
+        # Scalar functions
+        'abs', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctanh',
+        'cloglog', 'cos', 'cosh', 'cumulative', 'cut', 'density', 'deviance',
+        'equals', 'expr', 'gammap', 'ilogit', 'icloglog', 'integral', 'log',
+        'logfact', 'loggam', 'logit', 'max', 'min', 'phi', 'post.p.value',
+        'pow', 'prior.p.value', 'probit', 'replicate.post', 'replicate.prior',
+        'round', 'sin', 'sinh', 'solution', 'sqrt', 'step', 'tan', 'tanh',
+        'trunc',
+        # Vector functions
+        'inprod', 'interp.lin', 'inverse', 'logdet', 'mean', 'eigen.vals',
+        'ode', 'prod', 'p.valueM', 'rank', 'ranked', 'replicate.postM',
+        'sd', 'sort', 'sum',
+        # Special
+        'D', 'I', 'F', 'T', 'C')
+    """ OpenBUGS built-in functions
+
+    From http://www.openbugs.info/Manuals/ModelSpecification.html#ContentsAII
+
+    This also includes
+
+    - T, C, I : Truncation and censoring.
+      ``T`` and ``C`` are in OpenBUGS. ``I`` in WinBUGS.
+    - D : ODE
+    - F : Functional http://www.openbugs.info/Examples/Functionals.html
+
+    """
+
+    _DISTRIBUTIONS = ('dbern', 'dbin', 'dcat', 'dnegbin', 'dpois',
+                      'dhyper', 'dbeta', 'dchisqr', 'ddexp', 'dexp',
+                      'dflat', 'dgamma', 'dgev', 'df', 'dggamma', 'dgpar',
+                      'dloglik', 'dlnorm', 'dlogis', 'dnorm', 'dpar',
+                      'dt', 'dunif', 'dweib', 'dmulti', 'ddirch', 'dmnorm',
+                      'dmt', 'dwish')
+    """ OpenBUGS built-in distributions
+
+    Functions from
+    http://www.openbugs.info/Manuals/ModelSpecification.html#ContentsAI
+    """
+
+    tokens = {
+        'whitespace': [
+            (r"\s+", Text),
+        ],
+        'comments': [
+            # Comments
+            (r'#.*$', Comment.Single),
+        ],
+        'root': [
+            # Comments
+            include('comments'),
+            include('whitespace'),
+            # Block start
+            (r'(model)(\s+)(\{)',
+             bygroups(Keyword.Namespace, Text, Punctuation)),
+            # Reserved Words
+            (r'(for|in)(?![\w.])', Keyword.Reserved),
+            # Built-in Functions
+            (r'({})(?=\s*\()'.format(r'|'.join(_FUNCTIONS + _DISTRIBUTIONS)),
+             Name.Builtin),
+            # Regular variable names
+            (r'[A-Za-z][\w.]*', Name),
+            # Number Literals
+            (r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?', Number),
+            # Punctuation
+            (r'\[|\]|\(|\)|:|,|;', Punctuation),
+            # Assignment operators
+            # SLexer makes these tokens Operators.
+            (r'<-|~', Operator),
+            # Infix and prefix operators
+            (r'\+|-|\*|/', Operator),
+            # Block
+            (r'[{}]', Punctuation),
+        ]
+    }
+
+    def analyse_text(text):
+        if re.search(r"^\s*model\s*{", text, re.M):
+            return 0.7
+        else:
+            return 0.0
+
+
+class JagsLexer(RegexLexer):
+    """
+    Pygments Lexer for JAGS.
+    """
+
+    name = 'JAGS'
+    aliases = ['jags']
+    filenames = ['*.jag', '*.bug']
+    url = 'https://mcmc-jags.sourceforge.io'
+    version_added = '1.6'
+
+    # JAGS
+    _FUNCTIONS = (
+        'abs', 'arccos', 'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctanh',
+        'cos', 'cosh', 'cloglog',
+        'equals', 'exp', 'icloglog', 'ifelse', 'ilogit', 'log', 'logfact',
+        'loggam', 'logit', 'phi', 'pow', 'probit', 'round', 'sin', 'sinh',
+        'sqrt', 'step', 'tan', 'tanh', 'trunc', 'inprod', 'interp.lin',
+        'logdet', 'max', 'mean', 'min', 'prod', 'sum', 'sd', 'inverse',
+        'rank', 'sort', 't', 'acos', 'acosh', 'asin', 'asinh', 'atan',
+        # Truncation/Censoring (should I include)
+        'T', 'I')
+    # Distributions with density, probability and quartile functions
+    _DISTRIBUTIONS = tuple(f'[dpq]{x}' for x in
+                           ('bern', 'beta', 'dchiqsqr', 'ddexp', 'dexp',
+                            'df', 'gamma', 'gen.gamma', 'logis', 'lnorm',
+                            'negbin', 'nchisqr', 'norm', 'par', 'pois', 'weib'))
+    # Other distributions without density and probability
+    _OTHER_DISTRIBUTIONS = (
+        'dt', 'dunif', 'dbetabin', 'dbern', 'dbin', 'dcat', 'dhyper',
+        'ddirch', 'dmnorm', 'dwish', 'dmt', 'dmulti', 'dbinom', 'dchisq',
+        'dnbinom', 'dweibull', 'ddirich')
+
+    tokens = {
+        'whitespace': [
+            (r"\s+", Text),
+        ],
+        'names': [
+            # Regular variable names
+            (r'[a-zA-Z][\w.]*\b', Name),
+        ],
+        'comments': [
+            # do not use stateful comments
+            (r'(?s)/\*.*?\*/', Comment.Multiline),
+            # Comments
+            (r'#.*$', Comment.Single),
+        ],
+        'root': [
+            # Comments
+            include('comments'),
+            include('whitespace'),
+            # Block start
+            (r'(model|data)(\s+)(\{)',
+             bygroups(Keyword.Namespace, Text, Punctuation)),
+            (r'var(?![\w.])', Keyword.Declaration),
+            # Reserved Words
+            (r'(for|in)(?![\w.])', Keyword.Reserved),
+            # Builtins
+            # Need to use lookahead because . is a valid char
+            (r'({})(?=\s*\()'.format(r'|'.join(_FUNCTIONS
+                                          + _DISTRIBUTIONS
+                                          + _OTHER_DISTRIBUTIONS)),
+             Name.Builtin),
+            # Names
+            include('names'),
+            # Number Literals
+            (r'[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?', Number),
+            (r'\[|\]|\(|\)|:|,|;', Punctuation),
+            # Assignment operators
+            (r'<-|~', Operator),
+            # # JAGS includes many more than OpenBUGS
+            (r'\+|-|\*|\/|\|\|[&]{2}|[<>=]=?|\^|%.*?%', Operator),
+            (r'[{}]', Punctuation),
+        ]
+    }
+
+    def analyse_text(text):
+        if re.search(r'^\s*model\s*\{', text, re.M):
+            if re.search(r'^\s*data\s*\{', text, re.M):
+                return 0.9
+            elif re.search(r'^\s*var', text, re.M):
+                return 0.9
+            else:
+                return 0.3
+        else:
+            return 0
+
+
+class StanLexer(RegexLexer):
+    """Pygments Lexer for Stan models.
+
+    The Stan modeling language is specified in the *Stan Modeling Language
+    User's Guide and Reference Manual, v2.17.0*,
+    `pdf `__.
+    """
+
+    name = 'Stan'
+    aliases = ['stan']
+    filenames = ['*.stan']
+    url = 'https://mc-stan.org'
+    version_added = '1.6'
+
+    tokens = {
+        'whitespace': [
+            (r"\s+", Text),
+        ],
+        'comments': [
+            (r'(?s)/\*.*?\*/', Comment.Multiline),
+            # Comments
+            (r'(//|#).*$', Comment.Single),
+        ],
+        'root': [
+            (r'"[^"]*"', String),
+            # Comments
+            include('comments'),
+            # block start
+            include('whitespace'),
+            # Block start
+            (r'({})(\s*)(\{{)'.format(r'|'.join(('functions', 'data', r'transformed\s+?data',
+                        'parameters', r'transformed\s+parameters',
+                        'model', r'generated\s+quantities'))),
+             bygroups(Keyword.Namespace, Text, Punctuation)),
+            # target keyword
+            (r'target\s*\+=', Keyword),
+            # Reserved Words
+            (r'({})\b'.format(r'|'.join(_stan_builtins.KEYWORDS)), Keyword),
+            # Truncation
+            (r'T(?=\s*\[)', Keyword),
+            # Data types
+            (r'({})\b'.format(r'|'.join(_stan_builtins.TYPES)), Keyword.Type),
+             # < should be punctuation, but elsewhere I can't tell if it is in
+             # a range constraint
+            (r'(<)(\s*)(upper|lower|offset|multiplier)(\s*)(=)',
+             bygroups(Operator, Whitespace, Keyword, Whitespace, Punctuation)),
+            (r'(,)(\s*)(upper)(\s*)(=)',
+             bygroups(Punctuation, Whitespace, Keyword, Whitespace, Punctuation)),
+            # Punctuation
+            (r"[;,\[\]()]", Punctuation),
+            # Builtin
+            (r'({})(?=\s*\()'.format('|'.join(_stan_builtins.FUNCTIONS)), Name.Builtin),
+            (r'(~)(\s*)({})(?=\s*\()'.format('|'.join(_stan_builtins.DISTRIBUTIONS)),
+                bygroups(Operator, Whitespace, Name.Builtin)),
+            # Special names ending in __, like lp__
+            (r'[A-Za-z]\w*__\b', Name.Builtin.Pseudo),
+            (r'({})\b'.format(r'|'.join(_stan_builtins.RESERVED)), Keyword.Reserved),
+            # user-defined functions
+            (r'[A-Za-z]\w*(?=\s*\()]', Name.Function),
+            # Imaginary Literals
+            (r'[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?i', Number.Float),
+            (r'\.[0-9]+([eE][+-]?[0-9]+)?i', Number.Float),
+            (r'[0-9]+i', Number.Float),
+            # Real Literals
+            (r'[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?', Number.Float),
+            (r'\.[0-9]+([eE][+-]?[0-9]+)?', Number.Float),
+            # Integer Literals
+            (r'[0-9]+', Number.Integer),
+            # Regular variable names
+            (r'[A-Za-z]\w*\b', Name),
+            # Assignment operators
+            (r'<-|(?:\+|-|\.?/|\.?\*|=)?=|~', Operator),
+            # Infix, prefix and postfix operators (and = )
+            (r"\+|-|\.?\*|\.?/|\\|'|\.?\^|!=?|<=?|>=?|\|\||&&|%|\?|:|%/%|!", Operator),
+            # Block delimiters
+            (r'[{}]', Punctuation),
+            # Distribution |
+            (r'\|', Punctuation)
+        ]
+    }
+
+    def analyse_text(text):
+        if re.search(r'^\s*parameters\s*\{', text, re.M):
+            return 1.0
+        else:
+            return 0.0
diff --git a/.venv/Lib/site-packages/pygments/lexers/modula2.py b/.venv/Lib/site-packages/pygments/lexers/modula2.py
new file mode 100644
index 0000000..713f472
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/modula2.py
@@ -0,0 +1,1579 @@
+"""
+    pygments.lexers.modula2
+    ~~~~~~~~~~~~~~~~~~~~~~~
+
+    Multi-Dialect Lexer for Modula-2.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include
+from pygments.util import get_bool_opt, get_list_opt
+from pygments.token import Text, Comment, Operator, Keyword, Name, \
+    String, Number, Punctuation, Error
+
+__all__ = ['Modula2Lexer']
+
+
+# Multi-Dialect Modula-2 Lexer
+class Modula2Lexer(RegexLexer):
+    """
+    For Modula-2 source code.
+
+    The Modula-2 lexer supports several dialects.  By default, it operates in
+    fallback mode, recognising the *combined* literals, punctuation symbols
+    and operators of all supported dialects, and the *combined* reserved words
+    and builtins of PIM Modula-2, ISO Modula-2 and Modula-2 R10, while not
+    differentiating between library defined identifiers.
+
+    To select a specific dialect, a dialect option may be passed
+    or a dialect tag may be embedded into a source file.
+
+    Dialect Options:
+
+    `m2pim`
+        Select PIM Modula-2 dialect.
+    `m2iso`
+        Select ISO Modula-2 dialect.
+    `m2r10`
+        Select Modula-2 R10 dialect.
+    `objm2`
+        Select Objective Modula-2 dialect.
+
+    The PIM and ISO dialect options may be qualified with a language extension.
+
+    Language Extensions:
+
+    `+aglet`
+        Select Aglet Modula-2 extensions, available with m2iso.
+    `+gm2`
+        Select GNU Modula-2 extensions, available with m2pim.
+    `+p1`
+        Select p1 Modula-2 extensions, available with m2iso.
+    `+xds`
+        Select XDS Modula-2 extensions, available with m2iso.
+
+
+    Passing a Dialect Option via Unix Commandline Interface
+
+    Dialect options may be passed to the lexer using the `dialect` key.
+    Only one such option should be passed. If multiple dialect options are
+    passed, the first valid option is used, any subsequent options are ignored.
+
+    Examples:
+
+    `$ pygmentize -O full,dialect=m2iso -f html -o /path/to/output /path/to/input`
+        Use ISO dialect to render input to HTML output
+    `$ pygmentize -O full,dialect=m2iso+p1 -f rtf -o /path/to/output /path/to/input`
+        Use ISO dialect with p1 extensions to render input to RTF output
+
+
+    Embedding a Dialect Option within a source file
+
+    A dialect option may be embedded in a source file in form of a dialect
+    tag, a specially formatted comment that specifies a dialect option.
+
+    Dialect Tag EBNF::
+
+       dialectTag :
+           OpeningCommentDelim Prefix dialectOption ClosingCommentDelim ;
+
+       dialectOption :
+           'm2pim' | 'm2iso' | 'm2r10' | 'objm2' |
+           'm2iso+aglet' | 'm2pim+gm2' | 'm2iso+p1' | 'm2iso+xds' ;
+
+       Prefix : '!' ;
+
+       OpeningCommentDelim : '(*' ;
+
+       ClosingCommentDelim : '*)' ;
+
+    No whitespace is permitted between the tokens of a dialect tag.
+
+    In the event that a source file contains multiple dialect tags, the first
+    tag that contains a valid dialect option will be used and any subsequent
+    dialect tags will be ignored.  Ideally, a dialect tag should be placed
+    at the beginning of a source file.
+
+    An embedded dialect tag overrides a dialect option set via command line.
+
+    Examples:
+
+    ``(*!m2r10*) DEFINITION MODULE Foobar; ...``
+        Use Modula2 R10 dialect to render this source file.
+    ``(*!m2pim+gm2*) DEFINITION MODULE Bazbam; ...``
+        Use PIM dialect with GNU extensions to render this source file.
+
+
+    Algol Publication Mode:
+
+    In Algol publication mode, source text is rendered for publication of
+    algorithms in scientific papers and academic texts, following the format
+    of the Revised Algol-60 Language Report.  It is activated by passing
+    one of two corresponding styles as an option:
+
+    `algol`
+        render reserved words lowercase underline boldface
+        and builtins lowercase boldface italic
+    `algol_nu`
+        render reserved words lowercase boldface (no underlining)
+        and builtins lowercase boldface italic
+
+    The lexer automatically performs the required lowercase conversion when
+    this mode is activated.
+
+    Example:
+
+    ``$ pygmentize -O full,style=algol -f latex -o /path/to/output /path/to/input``
+        Render input file in Algol publication mode to LaTeX output.
+
+
+    Rendering Mode of First Class ADT Identifiers:
+
+    The rendering of standard library first class ADT identifiers is controlled
+    by option flag "treat_stdlib_adts_as_builtins".
+
+    When this option is turned on, standard library ADT identifiers are rendered
+    as builtins.  When it is turned off, they are rendered as ordinary library
+    identifiers.
+
+    `treat_stdlib_adts_as_builtins` (default: On)
+
+    The option is useful for dialects that support ADTs as first class objects
+    and provide ADTs in the standard library that would otherwise be built-in.
+
+    At present, only Modula-2 R10 supports library ADTs as first class objects
+    and therefore, no ADT identifiers are defined for any other dialects.
+
+    Example:
+
+    ``$ pygmentize -O full,dialect=m2r10,treat_stdlib_adts_as_builtins=Off ...``
+        Render standard library ADTs as ordinary library types.
+
+    .. versionchanged:: 2.1
+       Added multi-dialect support.
+    """
+    name = 'Modula-2'
+    url = 'http://www.modula2.org/'
+    aliases = ['modula2', 'm2']
+    filenames = ['*.def', '*.mod']
+    mimetypes = ['text/x-modula2']
+    version_added = '1.3'
+
+    flags = re.MULTILINE | re.DOTALL
+
+    tokens = {
+        'whitespace': [
+            (r'\n+', Text),  # blank lines
+            (r'\s+', Text),  # whitespace
+        ],
+        'dialecttags': [
+            # PIM Dialect Tag
+            (r'\(\*!m2pim\*\)', Comment.Special),
+            # ISO Dialect Tag
+            (r'\(\*!m2iso\*\)', Comment.Special),
+            # M2R10 Dialect Tag
+            (r'\(\*!m2r10\*\)', Comment.Special),
+            # ObjM2 Dialect Tag
+            (r'\(\*!objm2\*\)', Comment.Special),
+            # Aglet Extensions Dialect Tag
+            (r'\(\*!m2iso\+aglet\*\)', Comment.Special),
+            # GNU Extensions Dialect Tag
+            (r'\(\*!m2pim\+gm2\*\)', Comment.Special),
+            # p1 Extensions Dialect Tag
+            (r'\(\*!m2iso\+p1\*\)', Comment.Special),
+            # XDS Extensions Dialect Tag
+            (r'\(\*!m2iso\+xds\*\)', Comment.Special),
+        ],
+        'identifiers': [
+            (r'([a-zA-Z_$][\w$]*)', Name),
+        ],
+        'prefixed_number_literals': [
+            #
+            # Base-2, whole number
+            (r'0b[01]+(\'[01]+)*', Number.Bin),
+            #
+            # Base-16, whole number
+            (r'0[ux][0-9A-F]+(\'[0-9A-F]+)*', Number.Hex),
+        ],
+        'plain_number_literals': [
+            #
+            # Base-10, real number with exponent
+            (r'[0-9]+(\'[0-9]+)*'  # integral part
+             r'\.[0-9]+(\'[0-9]+)*'  # fractional part
+             r'[eE][+-]?[0-9]+(\'[0-9]+)*',  # exponent
+             Number.Float),
+            #
+            # Base-10, real number without exponent
+            (r'[0-9]+(\'[0-9]+)*'  # integral part
+             r'\.[0-9]+(\'[0-9]+)*',  # fractional part
+             Number.Float),
+            #
+            # Base-10, whole number
+            (r'[0-9]+(\'[0-9]+)*', Number.Integer),
+        ],
+        'suffixed_number_literals': [
+            #
+            # Base-8, whole number
+            (r'[0-7]+B', Number.Oct),
+            #
+            # Base-8, character code
+            (r'[0-7]+C', Number.Oct),
+            #
+            # Base-16, number
+            (r'[0-9A-F]+H', Number.Hex),
+        ],
+        'string_literals': [
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
+        ],
+        'digraph_operators': [
+            # Dot Product Operator
+            (r'\*\.', Operator),
+            # Array Concatenation Operator
+            (r'\+>', Operator),  # M2R10 + ObjM2
+            # Inequality Operator
+            (r'<>', Operator),  # ISO + PIM
+            # Less-Or-Equal, Subset
+            (r'<=', Operator),
+            # Greater-Or-Equal, Superset
+            (r'>=', Operator),
+            # Identity Operator
+            (r'==', Operator),  # M2R10 + ObjM2
+            # Type Conversion Operator
+            (r'::', Operator),  # M2R10 + ObjM2
+            # Assignment Symbol
+            (r':=', Operator),
+            # Postfix Increment Mutator
+            (r'\+\+', Operator),  # M2R10 + ObjM2
+            # Postfix Decrement Mutator
+            (r'--', Operator),  # M2R10 + ObjM2
+        ],
+        'unigraph_operators': [
+            # Arithmetic Operators
+            (r'[+-]', Operator),
+            (r'[*/]', Operator),
+            # ISO 80000-2 compliant Set Difference Operator
+            (r'\\', Operator),  # M2R10 + ObjM2
+            # Relational Operators
+            (r'[=#<>]', Operator),
+            # Dereferencing Operator
+            (r'\^', Operator),
+            # Dereferencing Operator Synonym
+            (r'@', Operator),  # ISO
+            # Logical AND Operator Synonym
+            (r'&', Operator),  # PIM + ISO
+            # Logical NOT Operator Synonym
+            (r'~', Operator),  # PIM + ISO
+            # Smalltalk Message Prefix
+            (r'`', Operator),  # ObjM2
+        ],
+        'digraph_punctuation': [
+            # Range Constructor
+            (r'\.\.', Punctuation),
+            # Opening Chevron Bracket
+            (r'<<', Punctuation),  # M2R10 + ISO
+            # Closing Chevron Bracket
+            (r'>>', Punctuation),  # M2R10 + ISO
+            # Blueprint Punctuation
+            (r'->', Punctuation),  # M2R10 + ISO
+            # Distinguish |# and # in M2 R10
+            (r'\|#', Punctuation),
+            # Distinguish ## and # in M2 R10
+            (r'##', Punctuation),
+            # Distinguish |* and * in M2 R10
+            (r'\|\*', Punctuation),
+        ],
+        'unigraph_punctuation': [
+            # Common Punctuation
+            (r'[()\[\]{},.:;|]', Punctuation),
+            # Case Label Separator Synonym
+            (r'!', Punctuation),  # ISO
+            # Blueprint Punctuation
+            (r'\?', Punctuation),  # M2R10 + ObjM2
+        ],
+        'comments': [
+            # Single Line Comment
+            (r'^//.*?\n', Comment.Single),  # M2R10 + ObjM2
+            # Block Comment
+            (r'\(\*([^$].*?)\*\)', Comment.Multiline),
+            # Template Block Comment
+            (r'/\*(.*?)\*/', Comment.Multiline),  # M2R10 + ObjM2
+        ],
+        'pragmas': [
+            # ISO Style Pragmas
+            (r'<\*.*?\*>', Comment.Preproc),  # ISO, M2R10 + ObjM2
+            # Pascal Style Pragmas
+            (r'\(\*\$.*?\*\)', Comment.Preproc),  # PIM
+        ],
+        'root': [
+            include('whitespace'),
+            include('dialecttags'),
+            include('pragmas'),
+            include('comments'),
+            include('identifiers'),
+            include('suffixed_number_literals'),  # PIM + ISO
+            include('prefixed_number_literals'),  # M2R10 + ObjM2
+            include('plain_number_literals'),
+            include('string_literals'),
+            include('digraph_punctuation'),
+            include('digraph_operators'),
+            include('unigraph_punctuation'),
+            include('unigraph_operators'),
+        ]
+    }
+
+#  C o m m o n   D a t a s e t s
+
+    # Common Reserved Words Dataset
+    common_reserved_words = (
+        # 37 common reserved words
+        'AND', 'ARRAY', 'BEGIN', 'BY', 'CASE', 'CONST', 'DEFINITION', 'DIV',
+        'DO', 'ELSE', 'ELSIF', 'END', 'EXIT', 'FOR', 'FROM', 'IF',
+        'IMPLEMENTATION', 'IMPORT', 'IN', 'LOOP', 'MOD', 'MODULE', 'NOT',
+        'OF', 'OR', 'POINTER', 'PROCEDURE', 'RECORD', 'REPEAT', 'RETURN',
+        'SET', 'THEN', 'TO', 'TYPE', 'UNTIL', 'VAR', 'WHILE',
+    )
+
+    # Common Builtins Dataset
+    common_builtins = (
+        # 16 common builtins
+        'ABS', 'BOOLEAN', 'CARDINAL', 'CHAR', 'CHR', 'FALSE', 'INTEGER',
+        'LONGINT', 'LONGREAL', 'MAX', 'MIN', 'NIL', 'ODD', 'ORD', 'REAL',
+        'TRUE',
+    )
+
+    # Common Pseudo-Module Builtins Dataset
+    common_pseudo_builtins = (
+        # 4 common pseudo builtins
+        'ADDRESS', 'BYTE', 'WORD', 'ADR'
+    )
+
+#  P I M   M o d u l a - 2   D a t a s e t s
+
+    # Lexemes to Mark as Error Tokens for PIM Modula-2
+    pim_lexemes_to_reject = (
+        '!', '`', '@', '$', '%', '?', '\\', '==', '++', '--', '::', '*.',
+        '+>', '->', '<<', '>>', '|#', '##',
+    )
+
+    # PIM Modula-2 Additional Reserved Words Dataset
+    pim_additional_reserved_words = (
+        # 3 additional reserved words
+        'EXPORT', 'QUALIFIED', 'WITH',
+    )
+
+    # PIM Modula-2 Additional Builtins Dataset
+    pim_additional_builtins = (
+        # 16 additional builtins
+        'BITSET', 'CAP', 'DEC', 'DISPOSE', 'EXCL', 'FLOAT', 'HALT', 'HIGH',
+        'INC', 'INCL', 'NEW', 'NIL', 'PROC', 'SIZE', 'TRUNC', 'VAL',
+    )
+
+    # PIM Modula-2 Additional Pseudo-Module Builtins Dataset
+    pim_additional_pseudo_builtins = (
+        # 5 additional pseudo builtins
+        'SYSTEM', 'PROCESS', 'TSIZE', 'NEWPROCESS', 'TRANSFER',
+    )
+
+#  I S O   M o d u l a - 2   D a t a s e t s
+
+    # Lexemes to Mark as Error Tokens for ISO Modula-2
+    iso_lexemes_to_reject = (
+        '`', '$', '%', '?', '\\', '==', '++', '--', '::', '*.', '+>', '->',
+        '<<', '>>', '|#', '##',
+    )
+
+    # ISO Modula-2 Additional Reserved Words Dataset
+    iso_additional_reserved_words = (
+        # 9 additional reserved words (ISO 10514-1)
+        'EXCEPT', 'EXPORT', 'FINALLY', 'FORWARD', 'PACKEDSET', 'QUALIFIED',
+        'REM', 'RETRY', 'WITH',
+        # 10 additional reserved words (ISO 10514-2 & ISO 10514-3)
+        'ABSTRACT', 'AS', 'CLASS', 'GUARD', 'INHERIT', 'OVERRIDE', 'READONLY',
+        'REVEAL', 'TRACED', 'UNSAFEGUARDED',
+    )
+
+    # ISO Modula-2 Additional Builtins Dataset
+    iso_additional_builtins = (
+        # 26 additional builtins (ISO 10514-1)
+        'BITSET', 'CAP', 'CMPLX', 'COMPLEX', 'DEC', 'DISPOSE', 'EXCL', 'FLOAT',
+        'HALT', 'HIGH', 'IM', 'INC', 'INCL', 'INT', 'INTERRUPTIBLE',  'LENGTH',
+        'LFLOAT', 'LONGCOMPLEX', 'NEW', 'PROC', 'PROTECTION', 'RE', 'SIZE',
+        'TRUNC', 'UNINTERRUBTIBLE', 'VAL',
+        # 5 additional builtins (ISO 10514-2 & ISO 10514-3)
+        'CREATE', 'DESTROY', 'EMPTY', 'ISMEMBER', 'SELF',
+    )
+
+    # ISO Modula-2 Additional Pseudo-Module Builtins Dataset
+    iso_additional_pseudo_builtins = (
+        # 14 additional builtins (SYSTEM)
+        'SYSTEM', 'BITSPERLOC', 'LOCSPERBYTE', 'LOCSPERWORD', 'LOC',
+        'ADDADR', 'SUBADR', 'DIFADR', 'MAKEADR', 'ADR',
+        'ROTATE', 'SHIFT', 'CAST', 'TSIZE',
+        # 13 additional builtins (COROUTINES)
+        'COROUTINES', 'ATTACH', 'COROUTINE', 'CURRENT', 'DETACH', 'HANDLER',
+        'INTERRUPTSOURCE', 'IOTRANSFER', 'IsATTACHED', 'LISTEN',
+        'NEWCOROUTINE', 'PROT', 'TRANSFER',
+        # 9 additional builtins (EXCEPTIONS)
+        'EXCEPTIONS', 'AllocateSource', 'CurrentNumber', 'ExceptionNumber',
+        'ExceptionSource', 'GetMessage', 'IsCurrentSource',
+        'IsExceptionalExecution', 'RAISE',
+        # 3 additional builtins (TERMINATION)
+        'TERMINATION', 'IsTerminating', 'HasHalted',
+        # 4 additional builtins (M2EXCEPTION)
+        'M2EXCEPTION', 'M2Exceptions', 'M2Exception', 'IsM2Exception',
+        'indexException', 'rangeException', 'caseSelectException',
+        'invalidLocation', 'functionException', 'wholeValueException',
+        'wholeDivException', 'realValueException', 'realDivException',
+        'complexValueException', 'complexDivException', 'protException',
+        'sysException', 'coException', 'exException',
+    )
+
+#  M o d u l a - 2   R 1 0   D a t a s e t s
+
+    # Lexemes to Mark as Error Tokens for Modula-2 R10
+    m2r10_lexemes_to_reject = (
+        '!', '`', '@', '$', '%', '&', '<>',
+    )
+
+    # Modula-2 R10 reserved words in addition to the common set
+    m2r10_additional_reserved_words = (
+        # 12 additional reserved words
+        'ALIAS', 'ARGLIST', 'BLUEPRINT', 'COPY', 'GENLIB', 'INDETERMINATE',
+        'NEW', 'NONE', 'OPAQUE', 'REFERENTIAL', 'RELEASE', 'RETAIN',
+        # 2 additional reserved words with symbolic assembly option
+        'ASM', 'REG',
+    )
+
+    # Modula-2 R10 builtins in addition to the common set
+    m2r10_additional_builtins = (
+        # 26 additional builtins
+        'CARDINAL', 'COUNT', 'EMPTY', 'EXISTS', 'INSERT', 'LENGTH', 'LONGCARD',
+        'OCTET', 'PTR', 'PRED', 'READ', 'READNEW', 'REMOVE', 'RETRIEVE', 'SORT',
+        'STORE', 'SUBSET', 'SUCC', 'TLIMIT', 'TMAX', 'TMIN', 'TRUE', 'TSIZE',
+        'UNICHAR', 'WRITE', 'WRITEF',
+    )
+
+    # Modula-2 R10 Additional Pseudo-Module Builtins Dataset
+    m2r10_additional_pseudo_builtins = (
+        # 13 additional builtins (TPROPERTIES)
+        'TPROPERTIES', 'PROPERTY', 'LITERAL', 'TPROPERTY', 'TLITERAL',
+        'TBUILTIN', 'TDYN', 'TREFC', 'TNIL', 'TBASE', 'TPRECISION',
+        'TMAXEXP', 'TMINEXP',
+        # 4 additional builtins (CONVERSION)
+        'CONVERSION', 'TSXFSIZE', 'SXF', 'VAL',
+        # 35 additional builtins (UNSAFE)
+        'UNSAFE', 'CAST', 'INTRINSIC', 'AVAIL', 'ADD', 'SUB', 'ADDC', 'SUBC',
+        'FETCHADD', 'FETCHSUB', 'SHL', 'SHR', 'ASHR', 'ROTL', 'ROTR', 'ROTLC',
+        'ROTRC', 'BWNOT', 'BWAND', 'BWOR', 'BWXOR', 'BWNAND', 'BWNOR',
+        'SETBIT', 'TESTBIT', 'LSBIT', 'MSBIT', 'CSBITS', 'BAIL', 'HALT',
+        'TODO', 'FFI', 'ADDR', 'VARGLIST', 'VARGC',
+        # 11 additional builtins (ATOMIC)
+        'ATOMIC', 'INTRINSIC', 'AVAIL', 'SWAP', 'CAS', 'INC', 'DEC', 'BWAND',
+        'BWNAND', 'BWOR', 'BWXOR',
+        # 7 additional builtins (COMPILER)
+        'COMPILER', 'DEBUG', 'MODNAME', 'PROCNAME', 'LINENUM', 'DEFAULT',
+        'HASH',
+        # 5 additional builtins (ASSEMBLER)
+        'ASSEMBLER', 'REGISTER', 'SETREG', 'GETREG', 'CODE',
+    )
+
+#  O b j e c t i v e   M o d u l a - 2   D a t a s e t s
+
+    # Lexemes to Mark as Error Tokens for Objective Modula-2
+    objm2_lexemes_to_reject = (
+        '!', '$', '%', '&', '<>',
+    )
+
+    # Objective Modula-2 Extensions
+    # reserved words in addition to Modula-2 R10
+    objm2_additional_reserved_words = (
+        # 16 additional reserved words
+        'BYCOPY', 'BYREF', 'CLASS', 'CONTINUE', 'CRITICAL', 'INOUT', 'METHOD',
+        'ON', 'OPTIONAL', 'OUT', 'PRIVATE', 'PROTECTED', 'PROTOCOL', 'PUBLIC',
+        'SUPER', 'TRY',
+    )
+
+    # Objective Modula-2 Extensions
+    # builtins in addition to Modula-2 R10
+    objm2_additional_builtins = (
+        # 3 additional builtins
+        'OBJECT', 'NO', 'YES',
+    )
+
+    # Objective Modula-2 Extensions
+    # pseudo-module builtins in addition to Modula-2 R10
+    objm2_additional_pseudo_builtins = (
+        # None
+    )
+
+#  A g l e t   M o d u l a - 2   D a t a s e t s
+
+    # Aglet Extensions
+    # reserved words in addition to ISO Modula-2
+    aglet_additional_reserved_words = (
+        # None
+    )
+
+    # Aglet Extensions
+    # builtins in addition to ISO Modula-2
+    aglet_additional_builtins = (
+        # 9 additional builtins
+        'BITSET8', 'BITSET16', 'BITSET32', 'CARDINAL8', 'CARDINAL16',
+        'CARDINAL32', 'INTEGER8', 'INTEGER16', 'INTEGER32',
+    )
+
+    # Aglet Modula-2 Extensions
+    # pseudo-module builtins in addition to ISO Modula-2
+    aglet_additional_pseudo_builtins = (
+        # None
+    )
+
+#  G N U   M o d u l a - 2   D a t a s e t s
+
+    # GNU Extensions
+    # reserved words in addition to PIM Modula-2
+    gm2_additional_reserved_words = (
+        # 10 additional reserved words
+        'ASM', '__ATTRIBUTE__', '__BUILTIN__', '__COLUMN__', '__DATE__',
+        '__FILE__', '__FUNCTION__', '__LINE__', '__MODULE__', 'VOLATILE',
+    )
+
+    # GNU Extensions
+    # builtins in addition to PIM Modula-2
+    gm2_additional_builtins = (
+        # 21 additional builtins
+        'BITSET8', 'BITSET16', 'BITSET32', 'CARDINAL8', 'CARDINAL16',
+        'CARDINAL32', 'CARDINAL64', 'COMPLEX32', 'COMPLEX64', 'COMPLEX96',
+        'COMPLEX128', 'INTEGER8', 'INTEGER16', 'INTEGER32', 'INTEGER64',
+        'REAL8', 'REAL16', 'REAL32', 'REAL96', 'REAL128', 'THROW',
+    )
+
+    # GNU Extensions
+    # pseudo-module builtins in addition to PIM Modula-2
+    gm2_additional_pseudo_builtins = (
+        # None
+    )
+
+#  p 1   M o d u l a - 2   D a t a s e t s
+
+    # p1 Extensions
+    # reserved words in addition to ISO Modula-2
+    p1_additional_reserved_words = (
+        # None
+    )
+
+    # p1 Extensions
+    # builtins in addition to ISO Modula-2
+    p1_additional_builtins = (
+        # None
+    )
+
+    # p1 Modula-2 Extensions
+    # pseudo-module builtins in addition to ISO Modula-2
+    p1_additional_pseudo_builtins = (
+        # 1 additional builtin
+        'BCD',
+    )
+
+#  X D S   M o d u l a - 2   D a t a s e t s
+
+    # XDS Extensions
+    # reserved words in addition to ISO Modula-2
+    xds_additional_reserved_words = (
+        # 1 additional reserved word
+        'SEQ',
+    )
+
+    # XDS Extensions
+    # builtins in addition to ISO Modula-2
+    xds_additional_builtins = (
+        # 9 additional builtins
+        'ASH', 'ASSERT', 'DIFFADR_TYPE', 'ENTIER', 'INDEX', 'LEN',
+        'LONGCARD', 'SHORTCARD', 'SHORTINT',
+    )
+
+    # XDS Modula-2 Extensions
+    # pseudo-module builtins in addition to ISO Modula-2
+    xds_additional_pseudo_builtins = (
+        # 22 additional builtins (SYSTEM)
+        'PROCESS', 'NEWPROCESS', 'BOOL8', 'BOOL16', 'BOOL32', 'CARD8',
+        'CARD16', 'CARD32', 'INT8', 'INT16', 'INT32', 'REF', 'MOVE',
+        'FILL', 'GET', 'PUT', 'CC', 'int', 'unsigned', 'size_t', 'void'
+        # 3 additional builtins (COMPILER)
+        'COMPILER', 'OPTION', 'EQUATION'
+    )
+
+#  P I M   S t a n d a r d   L i b r a r y   D a t a s e t s
+
+    # PIM Modula-2 Standard Library Modules Dataset
+    pim_stdlib_module_identifiers = (
+        'Terminal', 'FileSystem', 'InOut', 'RealInOut', 'MathLib0', 'Storage',
+    )
+
+    # PIM Modula-2 Standard Library Types Dataset
+    pim_stdlib_type_identifiers = (
+        'Flag', 'FlagSet', 'Response', 'Command', 'Lock', 'Permission',
+        'MediumType', 'File', 'FileProc', 'DirectoryProc', 'FileCommand',
+        'DirectoryCommand',
+    )
+
+    # PIM Modula-2 Standard Library Procedures Dataset
+    pim_stdlib_proc_identifiers = (
+        'Read', 'BusyRead', 'ReadAgain', 'Write', 'WriteString', 'WriteLn',
+        'Create', 'Lookup', 'Close', 'Delete', 'Rename', 'SetRead', 'SetWrite',
+        'SetModify', 'SetOpen', 'Doio', 'SetPos', 'GetPos', 'Length', 'Reset',
+        'Again', 'ReadWord', 'WriteWord', 'ReadChar', 'WriteChar',
+        'CreateMedium', 'DeleteMedium', 'AssignName', 'DeassignName',
+        'ReadMedium', 'LookupMedium', 'OpenInput', 'OpenOutput', 'CloseInput',
+        'CloseOutput', 'ReadString', 'ReadInt', 'ReadCard', 'ReadWrd',
+        'WriteInt', 'WriteCard', 'WriteOct', 'WriteHex', 'WriteWrd',
+        'ReadReal', 'WriteReal', 'WriteFixPt', 'WriteRealOct', 'sqrt', 'exp',
+        'ln', 'sin', 'cos', 'arctan', 'entier', 'ALLOCATE', 'DEALLOCATE',
+    )
+
+    # PIM Modula-2 Standard Library Variables Dataset
+    pim_stdlib_var_identifiers = (
+        'Done', 'termCH', 'in', 'out'
+    )
+
+    # PIM Modula-2 Standard Library Constants Dataset
+    pim_stdlib_const_identifiers = (
+        'EOL',
+    )
+
+#  I S O   S t a n d a r d   L i b r a r y   D a t a s e t s
+
+    # ISO Modula-2 Standard Library Modules Dataset
+    iso_stdlib_module_identifiers = (
+        # TO DO
+    )
+
+    # ISO Modula-2 Standard Library Types Dataset
+    iso_stdlib_type_identifiers = (
+        # TO DO
+    )
+
+    # ISO Modula-2 Standard Library Procedures Dataset
+    iso_stdlib_proc_identifiers = (
+        # TO DO
+    )
+
+    # ISO Modula-2 Standard Library Variables Dataset
+    iso_stdlib_var_identifiers = (
+        # TO DO
+    )
+
+    # ISO Modula-2 Standard Library Constants Dataset
+    iso_stdlib_const_identifiers = (
+        # TO DO
+    )
+
+#  M 2   R 1 0   S t a n d a r d   L i b r a r y   D a t a s e t s
+
+    # Modula-2 R10 Standard Library ADTs Dataset
+    m2r10_stdlib_adt_identifiers = (
+        'BCD', 'LONGBCD', 'BITSET', 'SHORTBITSET', 'LONGBITSET',
+        'LONGLONGBITSET', 'COMPLEX', 'LONGCOMPLEX', 'SHORTCARD', 'LONGLONGCARD',
+        'SHORTINT', 'LONGLONGINT', 'POSINT', 'SHORTPOSINT', 'LONGPOSINT',
+        'LONGLONGPOSINT', 'BITSET8', 'BITSET16', 'BITSET32', 'BITSET64',
+        'BITSET128', 'BS8', 'BS16', 'BS32', 'BS64', 'BS128', 'CARDINAL8',
+        'CARDINAL16', 'CARDINAL32', 'CARDINAL64', 'CARDINAL128', 'CARD8',
+        'CARD16', 'CARD32', 'CARD64', 'CARD128', 'INTEGER8', 'INTEGER16',
+        'INTEGER32', 'INTEGER64', 'INTEGER128', 'INT8', 'INT16', 'INT32',
+        'INT64', 'INT128', 'STRING', 'UNISTRING',
+    )
+
+    # Modula-2 R10 Standard Library Blueprints Dataset
+    m2r10_stdlib_blueprint_identifiers = (
+        'ProtoRoot', 'ProtoComputational', 'ProtoNumeric', 'ProtoScalar',
+        'ProtoNonScalar', 'ProtoCardinal', 'ProtoInteger', 'ProtoReal',
+        'ProtoComplex', 'ProtoVector', 'ProtoTuple', 'ProtoCompArray',
+        'ProtoCollection', 'ProtoStaticArray', 'ProtoStaticSet',
+        'ProtoStaticString', 'ProtoArray', 'ProtoString', 'ProtoSet',
+        'ProtoMultiSet', 'ProtoDictionary', 'ProtoMultiDict', 'ProtoExtension',
+        'ProtoIO', 'ProtoCardMath', 'ProtoIntMath', 'ProtoRealMath',
+    )
+
+    # Modula-2 R10 Standard Library Modules Dataset
+    m2r10_stdlib_module_identifiers = (
+        'ASCII', 'BooleanIO', 'CharIO', 'UnicharIO', 'OctetIO',
+        'CardinalIO', 'LongCardIO', 'IntegerIO', 'LongIntIO', 'RealIO',
+        'LongRealIO', 'BCDIO', 'LongBCDIO', 'CardMath', 'LongCardMath',
+        'IntMath', 'LongIntMath', 'RealMath', 'LongRealMath', 'BCDMath',
+        'LongBCDMath', 'FileIO', 'FileSystem', 'Storage', 'IOSupport',
+    )
+
+    # Modula-2 R10 Standard Library Types Dataset
+    m2r10_stdlib_type_identifiers = (
+        'File', 'Status',
+        # TO BE COMPLETED
+    )
+
+    # Modula-2 R10 Standard Library Procedures Dataset
+    m2r10_stdlib_proc_identifiers = (
+        'ALLOCATE', 'DEALLOCATE', 'SIZE',
+        # TO BE COMPLETED
+    )
+
+    # Modula-2 R10 Standard Library Variables Dataset
+    m2r10_stdlib_var_identifiers = (
+        'stdIn', 'stdOut', 'stdErr',
+    )
+
+    # Modula-2 R10 Standard Library Constants Dataset
+    m2r10_stdlib_const_identifiers = (
+        'pi', 'tau',
+    )
+
+#  D i a l e c t s
+
+    # Dialect modes
+    dialects = (
+        'unknown',
+        'm2pim', 'm2iso', 'm2r10', 'objm2',
+        'm2iso+aglet', 'm2pim+gm2', 'm2iso+p1', 'm2iso+xds',
+    )
+
+#   D a t a b a s e s
+
+    # Lexemes to Mark as Errors Database
+    lexemes_to_reject_db = {
+        # Lexemes to reject for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Lexemes to reject for PIM Modula-2
+        'm2pim': (
+            pim_lexemes_to_reject,
+        ),
+        # Lexemes to reject for ISO Modula-2
+        'm2iso': (
+            iso_lexemes_to_reject,
+        ),
+        # Lexemes to reject for Modula-2 R10
+        'm2r10': (
+            m2r10_lexemes_to_reject,
+        ),
+        # Lexemes to reject for Objective Modula-2
+        'objm2': (
+            objm2_lexemes_to_reject,
+        ),
+        # Lexemes to reject for Aglet Modula-2
+        'm2iso+aglet': (
+            iso_lexemes_to_reject,
+        ),
+        # Lexemes to reject for GNU Modula-2
+        'm2pim+gm2': (
+            pim_lexemes_to_reject,
+        ),
+        # Lexemes to reject for p1 Modula-2
+        'm2iso+p1': (
+            iso_lexemes_to_reject,
+        ),
+        # Lexemes to reject for XDS Modula-2
+        'm2iso+xds': (
+            iso_lexemes_to_reject,
+        ),
+    }
+
+    # Reserved Words Database
+    reserved_words_db = {
+        # Reserved words for unknown dialect
+        'unknown': (
+            common_reserved_words,
+            pim_additional_reserved_words,
+            iso_additional_reserved_words,
+            m2r10_additional_reserved_words,
+        ),
+
+        # Reserved words for PIM Modula-2
+        'm2pim': (
+            common_reserved_words,
+            pim_additional_reserved_words,
+        ),
+
+        # Reserved words for Modula-2 R10
+        'm2iso': (
+            common_reserved_words,
+            iso_additional_reserved_words,
+        ),
+
+        # Reserved words for ISO Modula-2
+        'm2r10': (
+            common_reserved_words,
+            m2r10_additional_reserved_words,
+        ),
+
+        # Reserved words for Objective Modula-2
+        'objm2': (
+            common_reserved_words,
+            m2r10_additional_reserved_words,
+            objm2_additional_reserved_words,
+        ),
+
+        # Reserved words for Aglet Modula-2 Extensions
+        'm2iso+aglet': (
+            common_reserved_words,
+            iso_additional_reserved_words,
+            aglet_additional_reserved_words,
+        ),
+
+        # Reserved words for GNU Modula-2 Extensions
+        'm2pim+gm2': (
+            common_reserved_words,
+            pim_additional_reserved_words,
+            gm2_additional_reserved_words,
+        ),
+
+        # Reserved words for p1 Modula-2 Extensions
+        'm2iso+p1': (
+            common_reserved_words,
+            iso_additional_reserved_words,
+            p1_additional_reserved_words,
+        ),
+
+        # Reserved words for XDS Modula-2 Extensions
+        'm2iso+xds': (
+            common_reserved_words,
+            iso_additional_reserved_words,
+            xds_additional_reserved_words,
+        ),
+    }
+
+    # Builtins Database
+    builtins_db = {
+        # Builtins for unknown dialect
+        'unknown': (
+            common_builtins,
+            pim_additional_builtins,
+            iso_additional_builtins,
+            m2r10_additional_builtins,
+        ),
+
+        # Builtins for PIM Modula-2
+        'm2pim': (
+            common_builtins,
+            pim_additional_builtins,
+        ),
+
+        # Builtins for ISO Modula-2
+        'm2iso': (
+            common_builtins,
+            iso_additional_builtins,
+        ),
+
+        # Builtins for ISO Modula-2
+        'm2r10': (
+            common_builtins,
+            m2r10_additional_builtins,
+        ),
+
+        # Builtins for Objective Modula-2
+        'objm2': (
+            common_builtins,
+            m2r10_additional_builtins,
+            objm2_additional_builtins,
+        ),
+
+        # Builtins for Aglet Modula-2 Extensions
+        'm2iso+aglet': (
+            common_builtins,
+            iso_additional_builtins,
+            aglet_additional_builtins,
+        ),
+
+        # Builtins for GNU Modula-2 Extensions
+        'm2pim+gm2': (
+            common_builtins,
+            pim_additional_builtins,
+            gm2_additional_builtins,
+        ),
+
+        # Builtins for p1 Modula-2 Extensions
+        'm2iso+p1': (
+            common_builtins,
+            iso_additional_builtins,
+            p1_additional_builtins,
+        ),
+
+        # Builtins for XDS Modula-2 Extensions
+        'm2iso+xds': (
+            common_builtins,
+            iso_additional_builtins,
+            xds_additional_builtins,
+        ),
+    }
+
+    # Pseudo-Module Builtins Database
+    pseudo_builtins_db = {
+        # Builtins for unknown dialect
+        'unknown': (
+            common_pseudo_builtins,
+            pim_additional_pseudo_builtins,
+            iso_additional_pseudo_builtins,
+            m2r10_additional_pseudo_builtins,
+        ),
+
+        # Builtins for PIM Modula-2
+        'm2pim': (
+            common_pseudo_builtins,
+            pim_additional_pseudo_builtins,
+        ),
+
+        # Builtins for ISO Modula-2
+        'm2iso': (
+            common_pseudo_builtins,
+            iso_additional_pseudo_builtins,
+        ),
+
+        # Builtins for ISO Modula-2
+        'm2r10': (
+            common_pseudo_builtins,
+            m2r10_additional_pseudo_builtins,
+        ),
+
+        # Builtins for Objective Modula-2
+        'objm2': (
+            common_pseudo_builtins,
+            m2r10_additional_pseudo_builtins,
+            objm2_additional_pseudo_builtins,
+        ),
+
+        # Builtins for Aglet Modula-2 Extensions
+        'm2iso+aglet': (
+            common_pseudo_builtins,
+            iso_additional_pseudo_builtins,
+            aglet_additional_pseudo_builtins,
+        ),
+
+        # Builtins for GNU Modula-2 Extensions
+        'm2pim+gm2': (
+            common_pseudo_builtins,
+            pim_additional_pseudo_builtins,
+            gm2_additional_pseudo_builtins,
+        ),
+
+        # Builtins for p1 Modula-2 Extensions
+        'm2iso+p1': (
+            common_pseudo_builtins,
+            iso_additional_pseudo_builtins,
+            p1_additional_pseudo_builtins,
+        ),
+
+        # Builtins for XDS Modula-2 Extensions
+        'm2iso+xds': (
+            common_pseudo_builtins,
+            iso_additional_pseudo_builtins,
+            xds_additional_pseudo_builtins,
+        ),
+    }
+
+    # Standard Library ADTs Database
+    stdlib_adts_db = {
+        # Empty entry for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Standard Library ADTs for PIM Modula-2
+        'm2pim': (
+            # No first class library types
+        ),
+
+        # Standard Library ADTs for ISO Modula-2
+        'm2iso': (
+            # No first class library types
+        ),
+
+        # Standard Library ADTs for Modula-2 R10
+        'm2r10': (
+            m2r10_stdlib_adt_identifiers,
+        ),
+
+        # Standard Library ADTs for Objective Modula-2
+        'objm2': (
+            m2r10_stdlib_adt_identifiers,
+        ),
+
+        # Standard Library ADTs for Aglet Modula-2
+        'm2iso+aglet': (
+            # No first class library types
+        ),
+
+        # Standard Library ADTs for GNU Modula-2
+        'm2pim+gm2': (
+            # No first class library types
+        ),
+
+        # Standard Library ADTs for p1 Modula-2
+        'm2iso+p1': (
+            # No first class library types
+        ),
+
+        # Standard Library ADTs for XDS Modula-2
+        'm2iso+xds': (
+            # No first class library types
+        ),
+    }
+
+    # Standard Library Modules Database
+    stdlib_modules_db = {
+        # Empty entry for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Standard Library Modules for PIM Modula-2
+        'm2pim': (
+            pim_stdlib_module_identifiers,
+        ),
+
+        # Standard Library Modules for ISO Modula-2
+        'm2iso': (
+            iso_stdlib_module_identifiers,
+        ),
+
+        # Standard Library Modules for Modula-2 R10
+        'm2r10': (
+            m2r10_stdlib_blueprint_identifiers,
+            m2r10_stdlib_module_identifiers,
+            m2r10_stdlib_adt_identifiers,
+        ),
+
+        # Standard Library Modules for Objective Modula-2
+        'objm2': (
+            m2r10_stdlib_blueprint_identifiers,
+            m2r10_stdlib_module_identifiers,
+        ),
+
+        # Standard Library Modules for Aglet Modula-2
+        'm2iso+aglet': (
+            iso_stdlib_module_identifiers,
+        ),
+
+        # Standard Library Modules for GNU Modula-2
+        'm2pim+gm2': (
+            pim_stdlib_module_identifiers,
+        ),
+
+        # Standard Library Modules for p1 Modula-2
+        'm2iso+p1': (
+            iso_stdlib_module_identifiers,
+        ),
+
+        # Standard Library Modules for XDS Modula-2
+        'm2iso+xds': (
+            iso_stdlib_module_identifiers,
+        ),
+    }
+
+    # Standard Library Types Database
+    stdlib_types_db = {
+        # Empty entry for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Standard Library Types for PIM Modula-2
+        'm2pim': (
+            pim_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for ISO Modula-2
+        'm2iso': (
+            iso_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for Modula-2 R10
+        'm2r10': (
+            m2r10_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for Objective Modula-2
+        'objm2': (
+            m2r10_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for Aglet Modula-2
+        'm2iso+aglet': (
+            iso_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for GNU Modula-2
+        'm2pim+gm2': (
+            pim_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for p1 Modula-2
+        'm2iso+p1': (
+            iso_stdlib_type_identifiers,
+        ),
+
+        # Standard Library Types for XDS Modula-2
+        'm2iso+xds': (
+            iso_stdlib_type_identifiers,
+        ),
+    }
+
+    # Standard Library Procedures Database
+    stdlib_procedures_db = {
+        # Empty entry for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Standard Library Procedures for PIM Modula-2
+        'm2pim': (
+            pim_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for ISO Modula-2
+        'm2iso': (
+            iso_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for Modula-2 R10
+        'm2r10': (
+            m2r10_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for Objective Modula-2
+        'objm2': (
+            m2r10_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for Aglet Modula-2
+        'm2iso+aglet': (
+            iso_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for GNU Modula-2
+        'm2pim+gm2': (
+            pim_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for p1 Modula-2
+        'm2iso+p1': (
+            iso_stdlib_proc_identifiers,
+        ),
+
+        # Standard Library Procedures for XDS Modula-2
+        'm2iso+xds': (
+            iso_stdlib_proc_identifiers,
+        ),
+    }
+
+    # Standard Library Variables Database
+    stdlib_variables_db = {
+        # Empty entry for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Standard Library Variables for PIM Modula-2
+        'm2pim': (
+            pim_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for ISO Modula-2
+        'm2iso': (
+            iso_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for Modula-2 R10
+        'm2r10': (
+            m2r10_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for Objective Modula-2
+        'objm2': (
+            m2r10_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for Aglet Modula-2
+        'm2iso+aglet': (
+            iso_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for GNU Modula-2
+        'm2pim+gm2': (
+            pim_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for p1 Modula-2
+        'm2iso+p1': (
+            iso_stdlib_var_identifiers,
+        ),
+
+        # Standard Library Variables for XDS Modula-2
+        'm2iso+xds': (
+            iso_stdlib_var_identifiers,
+        ),
+    }
+
+    # Standard Library Constants Database
+    stdlib_constants_db = {
+        # Empty entry for unknown dialect
+        'unknown': (
+            # LEAVE THIS EMPTY
+        ),
+        # Standard Library Constants for PIM Modula-2
+        'm2pim': (
+            pim_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for ISO Modula-2
+        'm2iso': (
+            iso_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for Modula-2 R10
+        'm2r10': (
+            m2r10_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for Objective Modula-2
+        'objm2': (
+            m2r10_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for Aglet Modula-2
+        'm2iso+aglet': (
+            iso_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for GNU Modula-2
+        'm2pim+gm2': (
+            pim_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for p1 Modula-2
+        'm2iso+p1': (
+            iso_stdlib_const_identifiers,
+        ),
+
+        # Standard Library Constants for XDS Modula-2
+        'm2iso+xds': (
+            iso_stdlib_const_identifiers,
+        ),
+    }
+
+#   M e t h o d s
+
+    # initialise a lexer instance
+    def __init__(self, **options):
+        #
+        # check dialect options
+        #
+        dialects = get_list_opt(options, 'dialect', [])
+        #
+        for dialect_option in dialects:
+            if dialect_option in self.dialects[1:-1]:
+                # valid dialect option found
+                self.set_dialect(dialect_option)
+                break
+        #
+        # Fallback Mode (DEFAULT)
+        else:
+            # no valid dialect option
+            self.set_dialect('unknown')
+        #
+        self.dialect_set_by_tag = False
+        #
+        # check style options
+        #
+        styles = get_list_opt(options, 'style', [])
+        #
+        # use lowercase mode for Algol style
+        if 'algol' in styles or 'algol_nu' in styles:
+            self.algol_publication_mode = True
+        else:
+            self.algol_publication_mode = False
+        #
+        # Check option flags
+        #
+        self.treat_stdlib_adts_as_builtins = get_bool_opt(
+            options, 'treat_stdlib_adts_as_builtins', True)
+        #
+        # call superclass initialiser
+        RegexLexer.__init__(self, **options)
+
+    # Set lexer to a specified dialect
+    def set_dialect(self, dialect_id):
+        #
+        # if __debug__:
+        #    print 'entered set_dialect with arg: ', dialect_id
+        #
+        # check dialect name against known dialects
+        if dialect_id not in self.dialects:
+            dialect = 'unknown'  # default
+        else:
+            dialect = dialect_id
+        #
+        # compose lexemes to reject set
+        lexemes_to_reject_set = set()
+        # add each list of reject lexemes for this dialect
+        for list in self.lexemes_to_reject_db[dialect]:
+            lexemes_to_reject_set.update(set(list))
+        #
+        # compose reserved words set
+        reswords_set = set()
+        # add each list of reserved words for this dialect
+        for list in self.reserved_words_db[dialect]:
+            reswords_set.update(set(list))
+        #
+        # compose builtins set
+        builtins_set = set()
+        # add each list of builtins for this dialect excluding reserved words
+        for list in self.builtins_db[dialect]:
+            builtins_set.update(set(list).difference(reswords_set))
+        #
+        # compose pseudo-builtins set
+        pseudo_builtins_set = set()
+        # add each list of builtins for this dialect excluding reserved words
+        for list in self.pseudo_builtins_db[dialect]:
+            pseudo_builtins_set.update(set(list).difference(reswords_set))
+        #
+        # compose ADTs set
+        adts_set = set()
+        # add each list of ADTs for this dialect excluding reserved words
+        for list in self.stdlib_adts_db[dialect]:
+            adts_set.update(set(list).difference(reswords_set))
+        #
+        # compose modules set
+        modules_set = set()
+        # add each list of builtins for this dialect excluding builtins
+        for list in self.stdlib_modules_db[dialect]:
+            modules_set.update(set(list).difference(builtins_set))
+        #
+        # compose types set
+        types_set = set()
+        # add each list of types for this dialect excluding builtins
+        for list in self.stdlib_types_db[dialect]:
+            types_set.update(set(list).difference(builtins_set))
+        #
+        # compose procedures set
+        procedures_set = set()
+        # add each list of procedures for this dialect excluding builtins
+        for list in self.stdlib_procedures_db[dialect]:
+            procedures_set.update(set(list).difference(builtins_set))
+        #
+        # compose variables set
+        variables_set = set()
+        # add each list of variables for this dialect excluding builtins
+        for list in self.stdlib_variables_db[dialect]:
+            variables_set.update(set(list).difference(builtins_set))
+        #
+        # compose constants set
+        constants_set = set()
+        # add each list of constants for this dialect excluding builtins
+        for list in self.stdlib_constants_db[dialect]:
+            constants_set.update(set(list).difference(builtins_set))
+        #
+        # update lexer state
+        self.dialect = dialect
+        self.lexemes_to_reject = lexemes_to_reject_set
+        self.reserved_words = reswords_set
+        self.builtins = builtins_set
+        self.pseudo_builtins = pseudo_builtins_set
+        self.adts = adts_set
+        self.modules = modules_set
+        self.types = types_set
+        self.procedures = procedures_set
+        self.variables = variables_set
+        self.constants = constants_set
+        #
+        # if __debug__:
+        #    print 'exiting set_dialect'
+        #    print ' self.dialect: ', self.dialect
+        #    print ' self.lexemes_to_reject: ', self.lexemes_to_reject
+        #    print ' self.reserved_words: ', self.reserved_words
+        #    print ' self.builtins: ', self.builtins
+        #    print ' self.pseudo_builtins: ', self.pseudo_builtins
+        #    print ' self.adts: ', self.adts
+        #    print ' self.modules: ', self.modules
+        #    print ' self.types: ', self.types
+        #    print ' self.procedures: ', self.procedures
+        #    print ' self.variables: ', self.variables
+        #    print ' self.types: ', self.types
+        #    print ' self.constants: ', self.constants
+
+    # Extracts a dialect name from a dialect tag comment string  and checks
+    # the extracted name against known dialects.  If a match is found,  the
+    # matching name is returned, otherwise dialect id 'unknown' is returned
+    def get_dialect_from_dialect_tag(self, dialect_tag):
+        #
+        # if __debug__:
+        #    print 'entered get_dialect_from_dialect_tag with arg: ', dialect_tag
+        #
+        # constants
+        left_tag_delim = '(*!'
+        right_tag_delim = '*)'
+        left_tag_delim_len = len(left_tag_delim)
+        right_tag_delim_len = len(right_tag_delim)
+        indicator_start = left_tag_delim_len
+        indicator_end = -(right_tag_delim_len)
+        #
+        # check comment string for dialect indicator
+        if len(dialect_tag) > (left_tag_delim_len + right_tag_delim_len) \
+           and dialect_tag.startswith(left_tag_delim) \
+           and dialect_tag.endswith(right_tag_delim):
+            #
+            # if __debug__:
+            #    print 'dialect tag found'
+            #
+            # extract dialect indicator
+            indicator = dialect_tag[indicator_start:indicator_end]
+            #
+            # if __debug__:
+            #    print 'extracted: ', indicator
+            #
+            # check against known dialects
+            for index in range(1, len(self.dialects)):
+                #
+                # if __debug__:
+                #    print 'dialects[', index, ']: ', self.dialects[index]
+                #
+                if indicator == self.dialects[index]:
+                    #
+                    # if __debug__:
+                    #    print 'matching dialect found'
+                    #
+                    # indicator matches known dialect
+                    return indicator
+            else:
+                # indicator does not match any dialect
+                return 'unknown'  # default
+        else:
+            # invalid indicator string
+            return 'unknown'  # default
+
+    # intercept the token stream, modify token attributes and return them
+    def get_tokens_unprocessed(self, text):
+        for index, token, value in RegexLexer.get_tokens_unprocessed(self, text):
+            #
+            # check for dialect tag if dialect has not been set by tag
+            if not self.dialect_set_by_tag and token == Comment.Special:
+                indicated_dialect = self.get_dialect_from_dialect_tag(value)
+                if indicated_dialect != 'unknown':
+                    # token is a dialect indicator
+                    # reset reserved words and builtins
+                    self.set_dialect(indicated_dialect)
+                    self.dialect_set_by_tag = True
+            #
+            # check for reserved words, predefined and stdlib identifiers
+            if token is Name:
+                if value in self.reserved_words:
+                    token = Keyword.Reserved
+                    if self.algol_publication_mode:
+                        value = value.lower()
+                #
+                elif value in self.builtins:
+                    token = Name.Builtin
+                    if self.algol_publication_mode:
+                        value = value.lower()
+                #
+                elif value in self.pseudo_builtins:
+                    token = Name.Builtin.Pseudo
+                    if self.algol_publication_mode:
+                        value = value.lower()
+                #
+                elif value in self.adts:
+                    if not self.treat_stdlib_adts_as_builtins:
+                        token = Name.Namespace
+                    else:
+                        token = Name.Builtin.Pseudo
+                        if self.algol_publication_mode:
+                            value = value.lower()
+                #
+                elif value in self.modules:
+                    token = Name.Namespace
+                #
+                elif value in self.types:
+                    token = Name.Class
+                #
+                elif value in self.procedures:
+                    token = Name.Function
+                #
+                elif value in self.variables:
+                    token = Name.Variable
+                #
+                elif value in self.constants:
+                    token = Name.Constant
+            #
+            elif token in Number:
+                #
+                # mark prefix number literals as error for PIM and ISO dialects
+                if self.dialect not in ('unknown', 'm2r10', 'objm2'):
+                    if "'" in value or value[0:2] in ('0b', '0x', '0u'):
+                        token = Error
+                #
+                elif self.dialect in ('m2r10', 'objm2'):
+                    # mark base-8 number literals as errors for M2 R10 and ObjM2
+                    if token is Number.Oct:
+                        token = Error
+                    # mark suffix base-16 literals as errors for M2 R10 and ObjM2
+                    elif token is Number.Hex and 'H' in value:
+                        token = Error
+                    # mark real numbers with E as errors for M2 R10 and ObjM2
+                    elif token is Number.Float and 'E' in value:
+                        token = Error
+            #
+            elif token in Comment:
+                #
+                # mark single line comment as error for PIM and ISO dialects
+                if token is Comment.Single:
+                    if self.dialect not in ('unknown', 'm2r10', 'objm2'):
+                        token = Error
+                #
+                if token is Comment.Preproc:
+                    # mark ISO pragma as error for PIM dialects
+                    if value.startswith('<*') and \
+                       self.dialect.startswith('m2pim'):
+                        token = Error
+                    # mark PIM pragma as comment for other dialects
+                    elif value.startswith('(*$') and \
+                            self.dialect != 'unknown' and \
+                            not self.dialect.startswith('m2pim'):
+                        token = Comment.Multiline
+            #
+            else:  # token is neither Name nor Comment
+                #
+                # mark lexemes matching the dialect's error token set as errors
+                if value in self.lexemes_to_reject:
+                    token = Error
+                #
+                # substitute lexemes when in Algol mode
+                if self.algol_publication_mode:
+                    if value == '#':
+                        value = '≠'
+                    elif value == '<=':
+                        value = '≤'
+                    elif value == '>=':
+                        value = '≥'
+                    elif value == '==':
+                        value = '≡'
+                    elif value == '*.':
+                        value = '•'
+
+            # return result
+            yield index, token, value
+
+    def analyse_text(text):
+        """It's Pascal-like, but does not use FUNCTION -- uses PROCEDURE
+        instead."""
+
+        # Check if this looks like Pascal, if not, bail out early
+        if not ('(*' in text and '*)' in text and ':=' in text):
+            return
+
+        result = 0
+        # Procedure is in Modula2
+        if re.search(r'\bPROCEDURE\b', text):
+            result += 0.6
+
+        # FUNCTION is only valid in Pascal, but not in Modula2
+        if re.search(r'\bFUNCTION\b', text):
+            result = 0.0
+
+        return result
diff --git a/.venv/Lib/site-packages/pygments/lexers/mojo.py b/.venv/Lib/site-packages/pygments/lexers/mojo.py
new file mode 100644
index 0000000..4df18c4
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/mojo.py
@@ -0,0 +1,707 @@
+"""
+    pygments.lexers.mojo
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Mojo and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import keyword
+
+from pygments import unistring as uni
+from pygments.lexer import (
+    RegexLexer,
+    bygroups,
+    combined,
+    default,
+    include,
+    this,
+    using,
+    words,
+)
+from pygments.token import (
+    Comment,
+    # Error,
+    Keyword,
+    Name,
+    Number,
+    Operator,
+    Punctuation,
+    String,
+    Text,
+    Whitespace,
+)
+from pygments.util import shebang_matches
+
+__all__ = ["MojoLexer"]
+
+
+class MojoLexer(RegexLexer):
+    """
+    For Mojo source code (version 24.2.1).
+    """
+
+    name = "Mojo"
+    url = "https://docs.modular.com/mojo/"
+    aliases = ["mojo", "🔥"]
+    filenames = [
+        "*.mojo",
+        "*.🔥",
+    ]
+    mimetypes = [
+        "text/x-mojo",
+        "application/x-mojo",
+    ]
+    version_added = "2.18"
+
+    uni_name = f"[{uni.xid_start}][{uni.xid_continue}]*"
+
+    def innerstring_rules(ttype):
+        return [
+            # the old style '%s' % (...) string formatting (still valid in Py3)
+            (
+                r"%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?"
+                "[hlL]?[E-GXc-giorsaux%]",
+                String.Interpol,
+            ),
+            # the new style '{}'.format(...) string formatting
+            (
+                r"\{"
+                r"((\w+)((\.\w+)|(\[[^\]]+\]))*)?"  # field name
+                r"(\![sra])?"  # conversion
+                r"(\:(.?[<>=\^])?[-+ ]?#?0?(\d+)?,?(\.\d+)?[E-GXb-gnosx%]?)?"
+                r"\}",
+                String.Interpol,
+            ),
+            # backslashes, quotes and formatting signs must be parsed one at a time
+            (r'[^\\\'"%{\n]+', ttype),
+            (r'[\'"\\]', ttype),
+            # unhandled string formatting sign
+            (r"%|(\{{1,2})", ttype),
+            # newlines are an error (use "nl" state)
+        ]
+
+    def fstring_rules(ttype):
+        return [
+            # Assuming that a '}' is the closing brace after format specifier.
+            # Sadly, this means that we won't detect syntax error. But it's
+            # more important to parse correct syntax correctly, than to
+            # highlight invalid syntax.
+            (r"\}", String.Interpol),
+            (r"\{", String.Interpol, "expr-inside-fstring"),
+            # backslashes, quotes and formatting signs must be parsed one at a time
+            (r'[^\\\'"{}\n]+', ttype),
+            (r'[\'"\\]', ttype),
+            # newlines are an error (use "nl" state)
+        ]
+
+    tokens = {
+        "root": [
+            (r"\s+", Whitespace),
+            (
+                r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")',
+                bygroups(Whitespace, String.Affix, String.Doc),
+            ),
+            (
+                r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')",
+                bygroups(Whitespace, String.Affix, String.Doc),
+            ),
+            (r"\A#!.+$", Comment.Hashbang),
+            (r"#.*$", Comment.Single),
+            (r"\\\n", Whitespace),
+            (r"\\", Whitespace),
+            include("keywords"),
+            include("soft-keywords"),
+            # In the original PR, all the below here used ((?:\s|\\\s)+) to
+            # designate whitespace, but I can't find any example of this being
+            # needed in the example file, so we're replacing it with `\s+`.
+            (
+                r"(alias)(\s+)",
+                bygroups(Keyword, Whitespace),
+                "varname",  # TODO varname the right fit?
+            ),
+            (r"(var)(\s+)", bygroups(Keyword, Whitespace), "varname"),
+            (r"(def)(\s+)", bygroups(Keyword, Whitespace), "funcname"),
+            (r"(fn)(\s+)", bygroups(Keyword, Whitespace), "funcname"),
+            (
+                r"(class)(\s+)",
+                bygroups(Keyword, Whitespace),
+                "classname",
+            ),  # not implemented yet
+            (r"(struct)(\s+)", bygroups(Keyword, Whitespace), "structname"),
+            (r"(trait)(\s+)", bygroups(Keyword, Whitespace), "structname"),
+            (r"(from)(\s+)", bygroups(Keyword.Namespace, Whitespace), "fromimport"),
+            (r"(import)(\s+)", bygroups(Keyword.Namespace, Whitespace), "import"),
+            include("expr"),
+        ],
+        "expr": [
+            # raw f-strings
+            (
+                '(?i)(rf|fr)(""")',
+                bygroups(String.Affix, String.Double),
+                combined("rfstringescape", "tdqf"),
+            ),
+            (
+                "(?i)(rf|fr)(''')",
+                bygroups(String.Affix, String.Single),
+                combined("rfstringescape", "tsqf"),
+            ),
+            (
+                '(?i)(rf|fr)(")',
+                bygroups(String.Affix, String.Double),
+                combined("rfstringescape", "dqf"),
+            ),
+            (
+                "(?i)(rf|fr)(')",
+                bygroups(String.Affix, String.Single),
+                combined("rfstringescape", "sqf"),
+            ),
+            # non-raw f-strings
+            (
+                '([fF])(""")',
+                bygroups(String.Affix, String.Double),
+                combined("fstringescape", "tdqf"),
+            ),
+            (
+                "([fF])(''')",
+                bygroups(String.Affix, String.Single),
+                combined("fstringescape", "tsqf"),
+            ),
+            (
+                '([fF])(")',
+                bygroups(String.Affix, String.Double),
+                combined("fstringescape", "dqf"),
+            ),
+            (
+                "([fF])(')",
+                bygroups(String.Affix, String.Single),
+                combined("fstringescape", "sqf"),
+            ),
+            # raw bytes and strings
+            ('(?i)(rb|br|r)(""")', bygroups(String.Affix, String.Double), "tdqs"),
+            ("(?i)(rb|br|r)(''')", bygroups(String.Affix, String.Single), "tsqs"),
+            ('(?i)(rb|br|r)(")', bygroups(String.Affix, String.Double), "dqs"),
+            ("(?i)(rb|br|r)(')", bygroups(String.Affix, String.Single), "sqs"),
+            # non-raw strings
+            (
+                '([uU]?)(""")',
+                bygroups(String.Affix, String.Double),
+                combined("stringescape", "tdqs"),
+            ),
+            (
+                "([uU]?)(''')",
+                bygroups(String.Affix, String.Single),
+                combined("stringescape", "tsqs"),
+            ),
+            (
+                '([uU]?)(")',
+                bygroups(String.Affix, String.Double),
+                combined("stringescape", "dqs"),
+            ),
+            (
+                "([uU]?)(')",
+                bygroups(String.Affix, String.Single),
+                combined("stringescape", "sqs"),
+            ),
+            # non-raw bytes
+            (
+                '([bB])(""")',
+                bygroups(String.Affix, String.Double),
+                combined("bytesescape", "tdqs"),
+            ),
+            (
+                "([bB])(''')",
+                bygroups(String.Affix, String.Single),
+                combined("bytesescape", "tsqs"),
+            ),
+            (
+                '([bB])(")',
+                bygroups(String.Affix, String.Double),
+                combined("bytesescape", "dqs"),
+            ),
+            (
+                "([bB])(')",
+                bygroups(String.Affix, String.Single),
+                combined("bytesescape", "sqs"),
+            ),
+            (r"[^\S\n]+", Text),
+            include("numbers"),
+            (r"!=|==|<<|>>|:=|[-~+/*%=<>&^|.]", Operator),
+            (r"([]{}:\(\),;[])+", Punctuation),
+            (r"(in|is|and|or|not)\b", Operator.Word),
+            include("expr-keywords"),
+            include("builtins"),
+            include("magicfuncs"),
+            include("magicvars"),
+            include("name"),
+        ],
+        "expr-inside-fstring": [
+            (r"[{([]", Punctuation, "expr-inside-fstring-inner"),
+            # without format specifier
+            (
+                r"(=\s*)?"  # debug (https://bugs.python.org/issue36817)
+                r"(\![sraf])?"  # conversion
+                r"\}",
+                String.Interpol,
+                "#pop",
+            ),
+            # with format specifier
+            # we'll catch the remaining '}' in the outer scope
+            (
+                r"(=\s*)?"  # debug (https://bugs.python.org/issue36817)
+                r"(\![sraf])?"  # conversion
+                r":",
+                String.Interpol,
+                "#pop",
+            ),
+            (r"\s+", Whitespace),  # allow new lines
+            include("expr"),
+        ],
+        "expr-inside-fstring-inner": [
+            (r"[{([]", Punctuation, "expr-inside-fstring-inner"),
+            (r"[])}]", Punctuation, "#pop"),
+            (r"\s+", Whitespace),  # allow new lines
+            include("expr"),
+        ],
+        "expr-keywords": [
+            # Based on https://docs.python.org/3/reference/expressions.html
+            (
+                words(
+                    (
+                        "async for",  # TODO https://docs.modular.com/mojo/roadmap#no-async-for-or-async-with
+                        "async with",  # TODO https://docs.modular.com/mojo/roadmap#no-async-for-or-async-with
+                        "await",
+                        "else",
+                        "for",
+                        "if",
+                        "lambda",
+                        "yield",
+                        "yield from",
+                    ),
+                    suffix=r"\b",
+                ),
+                Keyword,
+            ),
+            (words(("True", "False", "None"), suffix=r"\b"), Keyword.Constant),
+        ],
+        "keywords": [
+            (
+                words(
+                    (
+                        "assert",
+                        "async",
+                        "await",
+                        "borrowed",
+                        "break",
+                        "continue",
+                        "del",
+                        "elif",
+                        "else",
+                        "except",
+                        "finally",
+                        "for",
+                        "global",
+                        "if",
+                        "lambda",
+                        "pass",
+                        "raise",
+                        "nonlocal",
+                        "return",
+                        "try",
+                        "while",
+                        "yield",
+                        "yield from",
+                        "as",
+                        "with",
+                    ),
+                    suffix=r"\b",
+                ),
+                Keyword,
+            ),
+            (words(("True", "False", "None"), suffix=r"\b"), Keyword.Constant),
+        ],
+        "soft-keywords": [
+            # `match`, `case` and `_` soft keywords
+            (
+                r"(^[ \t]*)"  # at beginning of line + possible indentation
+                r"(match|case)\b"  # a possible keyword
+                r"(?![ \t]*(?:"  # not followed by...
+                r"[:,;=^&|@~)\]}]|(?:" +  # characters and keywords that mean this isn't
+                # pattern matching (but None/True/False is ok)
+                r"|".join(k for k in keyword.kwlist if k[0].islower())
+                + r")\b))",
+                bygroups(Whitespace, Keyword),
+                "soft-keywords-inner",
+            ),
+        ],
+        "soft-keywords-inner": [
+            # optional `_` keyword
+            (r"(\s+)([^\n_]*)(_\b)", bygroups(Whitespace, using(this), Keyword)),
+            default("#pop"),
+        ],
+        "builtins": [
+            (
+                words(
+                    (
+                        "__import__",
+                        "abs",
+                        "aiter",
+                        "all",
+                        "any",
+                        "bin",
+                        "bool",
+                        "bytearray",
+                        "breakpoint",
+                        "bytes",
+                        "callable",
+                        "chr",
+                        "classmethod",
+                        "compile",
+                        "complex",
+                        "delattr",
+                        "dict",
+                        "dir",
+                        "divmod",
+                        "enumerate",
+                        "eval",
+                        "filter",
+                        "float",
+                        "format",
+                        "frozenset",
+                        "getattr",
+                        "globals",
+                        "hasattr",
+                        "hash",
+                        "hex",
+                        "id",
+                        "input",
+                        "int",
+                        "isinstance",
+                        "issubclass",
+                        "iter",
+                        "len",
+                        "list",
+                        "locals",
+                        "map",
+                        "max",
+                        "memoryview",
+                        "min",
+                        "next",
+                        "object",
+                        "oct",
+                        "open",
+                        "ord",
+                        "pow",
+                        "print",
+                        "property",
+                        "range",
+                        "repr",
+                        "reversed",
+                        "round",
+                        "set",
+                        "setattr",
+                        "slice",
+                        "sorted",
+                        "staticmethod",
+                        "str",
+                        "sum",
+                        "super",
+                        "tuple",
+                        "type",
+                        "vars",
+                        "zip",
+                        # Mojo builtin types: https://docs.modular.com/mojo/stdlib/builtin/
+                        "AnyType",
+                        "Coroutine",
+                        "DType",
+                        "Error",
+                        "Int",
+                        "List",
+                        "ListLiteral",
+                        "Scalar",
+                        "Int8",
+                        "UInt8",
+                        "Int16",
+                        "UInt16",
+                        "Int32",
+                        "UInt32",
+                        "Int64",
+                        "UInt64",
+                        "BFloat16",
+                        "Float16",
+                        "Float32",
+                        "Float64",
+                        "SIMD",
+                        "String",
+                        "Tensor",
+                        "Tuple",
+                        "Movable",
+                        "Copyable",
+                        "CollectionElement",
+                    ),
+                    prefix=r"(?>',
+    # Binary augmented
+    '+=', '-=', '*=', '/=', '%=', '**=', '&=', '|=', '^=', '<<=', '>>=',
+    # Comparison
+    '==', '!=', '<', '<=', '>', '>=', '<=>',
+    # Patterns and assignment
+    ':=', '?', '=~', '!~', '=>',
+    # Calls and sends
+    '.', '<-', '->',
+]
+_escape_pattern = (
+    r'(?:\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|'
+    r'\\["\'\\bftnr])')
+# _char = _escape_chars + [('.', String.Char)]
+_identifier = r'[_a-zA-Z]\w*'
+
+_constants = [
+    # Void constants
+    'null',
+    # Bool constants
+    'false', 'true',
+    # Double constants
+    'Infinity', 'NaN',
+    # Special objects
+    'M', 'Ref', 'throw', 'traceln',
+]
+
+_guards = [
+    'Any', 'Binding', 'Bool', 'Bytes', 'Char', 'DeepFrozen', 'Double',
+    'Empty', 'Int', 'List', 'Map', 'Near', 'NullOk', 'Same', 'Selfless',
+    'Set', 'Str', 'SubrangeGuard', 'Transparent', 'Void',
+]
+
+_safeScope = [
+    '_accumulateList', '_accumulateMap', '_auditedBy', '_bind',
+    '_booleanFlow', '_comparer', '_equalizer', '_iterForever', '_loop',
+    '_makeBytes', '_makeDouble', '_makeFinalSlot', '_makeInt', '_makeList',
+    '_makeMap', '_makeMessageDesc', '_makeOrderedSpace', '_makeParamDesc',
+    '_makeProtocolDesc', '_makeSourceSpan', '_makeString', '_makeVarSlot',
+    '_makeVerbFacet', '_mapExtract', '_matchSame', '_quasiMatcher',
+    '_slotToBinding', '_splitList', '_suchThat', '_switchFailed',
+    '_validateFor', 'b__quasiParser', 'eval', 'import', 'm__quasiParser',
+    'makeBrandPair', 'makeLazySlot', 'safeScope', 'simple__quasiParser',
+]
+
+
+class MonteLexer(RegexLexer):
+    """
+    Lexer for the Monte programming language.
+    """
+    name = 'Monte'
+    url = 'https://monte.readthedocs.io/'
+    aliases = ['monte']
+    filenames = ['*.mt']
+    version_added = '2.2'
+
+    tokens = {
+        'root': [
+            # Comments
+            (r'#[^\n]*\n', Comment),
+
+            # Docstrings
+            # Apologies for the non-greedy matcher here.
+            (r'/\*\*.*?\*/', String.Doc),
+
+            # `var` declarations
+            (r'\bvar\b', Keyword.Declaration, 'var'),
+
+            # `interface` declarations
+            (r'\binterface\b', Keyword.Declaration, 'interface'),
+
+            # method declarations
+            (words(_methods, prefix='\\b', suffix='\\b'),
+             Keyword, 'method'),
+
+            # All other declarations
+            (words(_declarations, prefix='\\b', suffix='\\b'),
+             Keyword.Declaration),
+
+            # Keywords
+            (words(_keywords, prefix='\\b', suffix='\\b'), Keyword),
+
+            # Literals
+            ('[+-]?0x[_0-9a-fA-F]+', Number.Hex),
+            (r'[+-]?[_0-9]+\.[_0-9]*([eE][+-]?[_0-9]+)?', Number.Float),
+            ('[+-]?[_0-9]+', Number.Integer),
+            ("'", String.Double, 'char'),
+            ('"', String.Double, 'string'),
+
+            # Quasiliterals
+            ('`', String.Backtick, 'ql'),
+
+            # Operators
+            (words(_operators), Operator),
+
+            # Verb operators
+            (_identifier + '=', Operator.Word),
+
+            # Safe scope constants
+            (words(_constants, prefix='\\b', suffix='\\b'),
+             Keyword.Pseudo),
+
+            # Safe scope guards
+            (words(_guards, prefix='\\b', suffix='\\b'), Keyword.Type),
+
+            # All other safe scope names
+            (words(_safeScope, prefix='\\b', suffix='\\b'),
+             Name.Builtin),
+
+            # Identifiers
+            (_identifier, Name),
+
+            # Punctuation
+            (r'\(|\)|\{|\}|\[|\]|:|,', Punctuation),
+
+            # Whitespace
+            (' +', Whitespace),
+
+            # Definite lexer errors
+            ('=', Error),
+        ],
+        'char': [
+            # It is definitely an error to have a char of width == 0.
+            ("'", Error, 'root'),
+            (_escape_pattern, String.Escape, 'charEnd'),
+            ('.', String.Char, 'charEnd'),
+        ],
+        'charEnd': [
+            ("'", String.Char, '#pop:2'),
+            # It is definitely an error to have a char of width > 1.
+            ('.', Error),
+        ],
+        # The state of things coming into an interface.
+        'interface': [
+            (' +', Whitespace),
+            (_identifier, Name.Class, '#pop'),
+            include('root'),
+        ],
+        # The state of things coming into a method.
+        'method': [
+            (' +', Whitespace),
+            (_identifier, Name.Function, '#pop'),
+            include('root'),
+        ],
+        'string': [
+            ('"', String.Double, 'root'),
+            (_escape_pattern, String.Escape),
+            (r'\n', String.Double),
+            ('.', String.Double),
+        ],
+        'ql': [
+            ('`', String.Backtick, 'root'),
+            (r'\$' + _escape_pattern, String.Escape),
+            (r'\$\$', String.Escape),
+            (r'@@', String.Escape),
+            (r'\$\{', String.Interpol, 'qlNest'),
+            (r'@\{', String.Interpol, 'qlNest'),
+            (r'\$' + _identifier, Name),
+            ('@' + _identifier, Name),
+            ('.', String.Backtick),
+        ],
+        'qlNest': [
+            (r'\}', String.Interpol, '#pop'),
+            include('root'),
+        ],
+        # The state of things immediately following `var`.
+        'var': [
+            (' +', Whitespace),
+            (_identifier, Name.Variable, '#pop'),
+            include('root'),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/mosel.py b/.venv/Lib/site-packages/pygments/lexers/mosel.py
new file mode 100644
index 0000000..426c9a1
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/mosel.py
@@ -0,0 +1,447 @@
+"""
+    pygments.lexers.mosel
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the mosel language.
+    http://www.fico.com/en/products/fico-xpress-optimization
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['MoselLexer']
+
+FUNCTIONS = (
+    # core functions
+    '_',
+    'abs',
+    'arctan',
+    'asproc',
+    'assert',
+    'bitflip',
+    'bitneg',
+    'bitset',
+    'bitshift',
+    'bittest',
+    'bitval',
+    'ceil',
+    'cos',
+    'create',
+    'currentdate',
+    'currenttime',
+    'cutelt',
+    'cutfirst',
+    'cuthead',
+    'cutlast',
+    'cuttail',
+    'datablock',
+    'delcell',
+    'exists',
+    'exit',
+    'exp',
+    'exportprob',
+    'fclose',
+    'fflush',
+    'finalize',
+    'findfirst',
+    'findlast',
+    'floor',
+    'fopen',
+    'fselect',
+    'fskipline',
+    'fwrite',
+    'fwrite_',
+    'fwriteln',
+    'fwriteln_',
+    'getact',
+    'getcoeff',
+    'getcoeffs',
+    'getdual',
+    'getelt',
+    'getfid',
+    'getfirst',
+    'getfname',
+    'gethead',
+    'getlast',
+    'getobjval',
+    'getparam',
+    'getrcost',
+    'getreadcnt',
+    'getreverse',
+    'getsize',
+    'getslack',
+    'getsol',
+    'gettail',
+    'gettype',
+    'getvars',
+    'isdynamic',
+    'iseof',
+    'isfinite',
+    'ishidden',
+    'isinf',
+    'isnan',
+    'isodd',
+    'ln',
+    'localsetparam',
+    'log',
+    'makesos1',
+    'makesos2',
+    'maxlist',
+    'memoryuse',
+    'minlist',
+    'newmuid',
+    'publish',
+    'random',
+    'read',
+    'readln',
+    'reset',
+    'restoreparam',
+    'reverse',
+    'round',
+    'setcoeff',
+    'sethidden',
+    'setioerr',
+    'setmatherr',
+    'setname',
+    'setparam',
+    'setrandseed',
+    'setrange',
+    'settype',
+    'sin',
+    'splithead',
+    'splittail',
+    'sqrt',
+    'strfmt',
+    'substr',
+    'timestamp',
+    'unpublish',
+    'versionnum',
+    'versionstr',
+    'write',
+    'write_',
+    'writeln',
+    'writeln_',
+
+    # mosel exam mmxprs | sed -n -e "s/ [pf][a-z]* \([a-zA-Z0-9_]*\).*/'\1',/p" | sort -u
+    'addcut',
+    'addcuts',
+    'addmipsol',
+    'basisstability',
+    'calcsolinfo',
+    'clearmipdir',
+    'clearmodcut',
+    'command',
+    'copysoltoinit',
+    'crossoverlpsol',
+    'defdelayedrows',
+    'defsecurevecs',
+    'delcuts',
+    'dropcuts',
+    'estimatemarginals',
+    'fixglobal',
+    'flushmsgq',
+    'getbstat',
+    'getcnlist',
+    'getcplist',
+    'getdualray',
+    'getiis',
+    'getiissense',
+    'getiistype',
+    'getinfcause',
+    'getinfeas',
+    'getlb',
+    'getlct',
+    'getleft',
+    'getloadedlinctrs',
+    'getloadedmpvars',
+    'getname',
+    'getprimalray',
+    'getprobstat',
+    'getrange',
+    'getright',
+    'getsensrng',
+    'getsize',
+    'getsol',
+    'gettype',
+    'getub',
+    'getvars',
+    'gety',
+    'hasfeature',
+    'implies',
+    'indicator',
+    'initglobal',
+    'ishidden',
+    'isiisvalid',
+    'isintegral',
+    'loadbasis',
+    'loadcuts',
+    'loadlpsol',
+    'loadmipsol',
+    'loadprob',
+    'maximise',
+    'maximize',
+    'minimise',
+    'minimize',
+    'postsolve',
+    'readbasis',
+    'readdirs',
+    'readsol',
+    'refinemipsol',
+    'rejectintsol',
+    'repairinfeas',
+    'repairinfeas_deprec',
+    'resetbasis',
+    'resetiis',
+    'resetsol',
+    'savebasis',
+    'savemipsol',
+    'savesol',
+    'savestate',
+    'selectsol',
+    'setarchconsistency',
+    'setbstat',
+    'setcallback',
+    'setcbcutoff',
+    'setgndata',
+    'sethidden',
+    'setlb',
+    'setmipdir',
+    'setmodcut',
+    'setsol',
+    'setub',
+    'setucbdata',
+    'stopoptimise',
+    'stopoptimize',
+    'storecut',
+    'storecuts',
+    'unloadprob',
+    'uselastbarsol',
+    'writebasis',
+    'writedirs',
+    'writeprob',
+    'writesol',
+    'xor',
+    'xprs_addctr',
+    'xprs_addindic',
+
+    # mosel exam mmsystem | sed -n -e "s/ [pf][a-z]* \([a-zA-Z0-9_]*\).*/'\1',/p" | sort -u
+    'addmonths',
+    'copytext',
+    'cuttext',
+    'deltext',
+    'endswith',
+    'erase',
+    'expandpath',
+    'fcopy',
+    'fdelete',
+    'findfiles',
+    'findtext',
+    'fmove',
+    'formattext',
+    'getasnumber',
+    'getchar',
+    'getcwd',
+    'getdate',
+    'getday',
+    'getdaynum',
+    'getdays',
+    'getdirsep',
+    'getdsoparam',
+    'getendparse',
+    'getenv',
+    'getfsize',
+    'getfstat',
+    'getftime',
+    'gethour',
+    'getminute',
+    'getmonth',
+    'getmsec',
+    'getoserrmsg',
+    'getoserror',
+    'getpathsep',
+    'getqtype',
+    'getsecond',
+    'getsepchar',
+    'getsize',
+    'getstart',
+    'getsucc',
+    'getsysinfo',
+    'getsysstat',
+    'gettime',
+    'gettmpdir',
+    'gettrim',
+    'getweekday',
+    'getyear',
+    'inserttext',
+    'isvalid',
+    'jointext',
+    'makedir',
+    'makepath',
+    'newtar',
+    'newzip',
+    'nextfield',
+    'openpipe',
+    'parseextn',
+    'parseint',
+    'parsereal',
+    'parsetext',
+    'pastetext',
+    'pathmatch',
+    'pathsplit',
+    'qsort',
+    'quote',
+    'readtextline',
+    'regmatch',
+    'regreplace',
+    'removedir',
+    'removefiles',
+    'setchar',
+    'setdate',
+    'setday',
+    'setdsoparam',
+    'setendparse',
+    'setenv',
+    'sethour',
+    'setminute',
+    'setmonth',
+    'setmsec',
+    'setoserror',
+    'setqtype',
+    'setsecond',
+    'setsepchar',
+    'setstart',
+    'setsucc',
+    'settime',
+    'settrim',
+    'setyear',
+    'sleep',
+    'splittext',
+    'startswith',
+    'system',
+    'tarlist',
+    'textfmt',
+    'tolower',
+    'toupper',
+    'trim',
+    'untar',
+    'unzip',
+    'ziplist',
+
+    # mosel exam mmjobs | sed -n -e "s/ [pf][a-z]* \([a-zA-Z0-9_]*\).*/'\1',/p" | sort -u
+    'canceltimer',
+    'clearaliases',
+    'compile',
+    'connect',
+    'detach',
+    'disconnect',
+    'dropnextevent',
+    'findxsrvs',
+    'getaliases',
+    'getannidents',
+    'getannotations',
+    'getbanner',
+    'getclass',
+    'getdsoprop',
+    'getdsopropnum',
+    'getexitcode',
+    'getfromgid',
+    'getfromid',
+    'getfromuid',
+    'getgid',
+    'gethostalias',
+    'getid',
+    'getmodprop',
+    'getmodpropnum',
+    'getnextevent',
+    'getnode',
+    'getrmtid',
+    'getstatus',
+    'getsysinfo',
+    'gettimer',
+    'getuid',
+    'getvalue',
+    'isqueueempty',
+    'load',
+    'nullevent',
+    'peeknextevent',
+    'resetmodpar',
+    'run',
+    'send',
+    'setcontrol',
+    'setdefstream',
+    'setgid',
+    'sethostalias',
+    'setmodpar',
+    'settimer',
+    'setuid',
+    'setworkdir',
+    'stop',
+    'unload',
+    'wait',
+    'waitexpired',
+    'waitfor',
+    'waitforend',
+)
+
+
+class MoselLexer(RegexLexer):
+    """
+    For the Mosel optimization language.
+    """
+    name = 'Mosel'
+    aliases = ['mosel']
+    filenames = ['*.mos']
+    url = 'https://www.fico.com/fico-xpress-optimization/docs/latest/mosel/mosel_lang/dhtml/moselreflang.html'
+    version_added = '2.6'
+
+    tokens = {
+        'root': [
+            (r'\n', Text),
+            (r'\s+', Text.Whitespace),
+            (r'!.*?\n', Comment.Single),
+            (r'\(!(.|\n)*?!\)', Comment.Multiline),
+            (words((
+                'and', 'as', 'break', 'case', 'count', 'declarations', 'do',
+                'dynamic', 'elif', 'else', 'end-', 'end', 'evaluation', 'false',
+                'forall', 'forward', 'from', 'function', 'hashmap', 'if',
+                'imports', 'include', 'initialisations', 'initializations', 'inter',
+                'max', 'min', 'model', 'namespace', 'next', 'not', 'nsgroup',
+                'nssearch', 'of', 'options', 'or', 'package', 'parameters',
+                'procedure', 'public', 'prod', 'record', 'repeat', 'requirements',
+                'return', 'sum', 'then', 'to', 'true', 'union', 'until', 'uses',
+                'version', 'while', 'with'), prefix=r'\b', suffix=r'\b'),
+             Keyword.Builtin),
+            (words((
+                'range', 'array', 'set', 'list', 'mpvar', 'mpproblem', 'linctr',
+                'nlctr', 'integer', 'string', 'real', 'boolean', 'text', 'time',
+                'date', 'datetime', 'returned', 'Model', 'Mosel', 'counter',
+                'xmldoc', 'is_sos1', 'is_sos2', 'is_integer', 'is_binary',
+                'is_continuous', 'is_free', 'is_semcont', 'is_semint',
+                'is_partint'), prefix=r'\b', suffix=r'\b'),
+             Keyword.Type),
+            (r'(\+|\-|\*|/|=|<=|>=|\||\^|<|>|<>|\.\.|\.|:=|::|:|in|mod|div)',
+             Operator),
+            (r'[()\[\]{},;]+', Punctuation),
+            (words(FUNCTIONS,  prefix=r'\b', suffix=r'\b'), Name.Function),
+            (r'(\d+\.(?!\.)\d*|\.(?!.)\d+)([eE][+-]?\d+)?', Number.Float),
+            (r'\d+([eE][+-]?\d+)?', Number.Integer),
+            (r'[+-]?Infinity', Number.Integer),
+            (r'0[xX][0-9a-fA-F]+', Number),
+            (r'"', String.Double, 'double_quote'),
+            (r'\'', String.Single, 'single_quote'),
+            (r'(\w+|(\.(?!\.)))', Text),
+        ],
+        'single_quote': [
+            (r'\'', String.Single, '#pop'),
+            (r'[^\']+', String.Single),
+        ],
+        'double_quote': [
+            (r'(\\"|\\[0-7]{1,3}\D|\\[abfnrtv]|\\\\)', String.Escape),
+            (r'\"', String.Double, '#pop'),
+            (r'[^"\\]+', String.Double),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/ncl.py b/.venv/Lib/site-packages/pygments/lexers/ncl.py
new file mode 100644
index 0000000..d2f4760
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/ncl.py
@@ -0,0 +1,894 @@
+"""
+    pygments.lexers.ncl
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for NCAR Command Language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['NCLLexer']
+
+
+class NCLLexer(RegexLexer):
+    """
+    Lexer for NCL code.
+    """
+    name = 'NCL'
+    aliases = ['ncl']
+    filenames = ['*.ncl']
+    mimetypes = ['text/ncl']
+    url = 'https://www.ncl.ucar.edu'
+    version_added = '2.2'
+
+    flags = re.MULTILINE
+
+    tokens = {
+        'root': [
+            (r';.*\n', Comment),
+            include('strings'),
+            include('core'),
+            (r'[a-zA-Z_]\w*', Name),
+            include('nums'),
+            (r'[\s]+', Text),
+        ],
+        'core': [
+            # Statements
+            (words((
+                'begin', 'break', 'continue', 'create', 'defaultapp', 'do',
+                'else', 'end', 'external', 'exit', 'True', 'False', 'file', 'function',
+                'getvalues', 'graphic', 'group', 'if', 'list', 'load', 'local',
+                'new', '_Missing', 'Missing', 'noparent', 'procedure',
+                'quit', 'QUIT', 'Quit', 'record', 'return', 'setvalues', 'stop',
+                'then', 'while'), prefix=r'\b', suffix=r'\s*\b'),
+             Keyword),
+
+            # Data Types
+            (words((
+                'ubyte', 'uint', 'uint64', 'ulong', 'string', 'byte',
+                'character', 'double', 'float', 'integer', 'int64', 'logical',
+                'long', 'short', 'ushort', 'enumeric', 'numeric', 'snumeric'),
+                prefix=r'\b', suffix=r'\s*\b'),
+             Keyword.Type),
+
+            # Operators
+            (r'[\%^*+\-/<>]', Operator),
+
+            # punctuation:
+            (r'[\[\]():@$!&|.,\\{}]', Punctuation),
+            (r'[=:]', Punctuation),
+
+            # Intrinsics
+            (words((
+                'abs', 'acos', 'addfile', 'addfiles', 'all', 'angmom_atm', 'any',
+                'area_conserve_remap', 'area_hi2lores', 'area_poly_sphere',
+                'asciiread', 'asciiwrite', 'asin', 'atan', 'atan2', 'attsetvalues',
+                'avg', 'betainc', 'bin_avg', 'bin_sum', 'bw_bandpass_filter',
+                'cancor', 'cbinread', 'cbinwrite', 'cd_calendar', 'cd_inv_calendar',
+                'cdfbin_p', 'cdfbin_pr', 'cdfbin_s', 'cdfbin_xn', 'cdfchi_p',
+                'cdfchi_x', 'cdfgam_p', 'cdfgam_x', 'cdfnor_p', 'cdfnor_x',
+                'cdft_p', 'cdft_t', 'ceil', 'center_finite_diff',
+                'center_finite_diff_n', 'cfftb', 'cfftf', 'cfftf_frq_reorder',
+                'charactertodouble', 'charactertofloat', 'charactertointeger',
+                'charactertolong', 'charactertoshort', 'charactertostring',
+                'chartodouble', 'chartofloat', 'chartoint', 'chartointeger',
+                'chartolong', 'chartoshort', 'chartostring', 'chiinv', 'clear',
+                'color_index_to_rgba', 'conform', 'conform_dims', 'cos', 'cosh',
+                'count_unique_values', 'covcorm', 'covcorm_xy', 'craybinnumrec',
+                'craybinrecread', 'create_graphic', 'csa1', 'csa1d', 'csa1s',
+                'csa1x', 'csa1xd', 'csa1xs', 'csa2', 'csa2d', 'csa2l', 'csa2ld',
+                'csa2ls', 'csa2lx', 'csa2lxd', 'csa2lxs', 'csa2s', 'csa2x',
+                'csa2xd', 'csa2xs', 'csa3', 'csa3d', 'csa3l', 'csa3ld', 'csa3ls',
+                'csa3lx', 'csa3lxd', 'csa3lxs', 'csa3s', 'csa3x', 'csa3xd',
+                'csa3xs', 'csc2s', 'csgetp', 'css2c', 'cssetp', 'cssgrid', 'csstri',
+                'csvoro', 'cumsum', 'cz2ccm', 'datatondc', 'day_of_week',
+                'day_of_year', 'days_in_month', 'default_fillvalue', 'delete',
+                'depth_to_pres', 'destroy', 'determinant', 'dewtemp_trh',
+                'dgeevx_lapack', 'dim_acumrun_n', 'dim_avg', 'dim_avg_n',
+                'dim_avg_wgt', 'dim_avg_wgt_n', 'dim_cumsum', 'dim_cumsum_n',
+                'dim_gamfit_n', 'dim_gbits', 'dim_max', 'dim_max_n', 'dim_median',
+                'dim_median_n', 'dim_min', 'dim_min_n', 'dim_num', 'dim_num_n',
+                'dim_numrun_n', 'dim_pqsort', 'dim_pqsort_n', 'dim_product',
+                'dim_product_n', 'dim_rmsd', 'dim_rmsd_n', 'dim_rmvmean',
+                'dim_rmvmean_n', 'dim_rmvmed', 'dim_rmvmed_n', 'dim_spi_n',
+                'dim_standardize', 'dim_standardize_n', 'dim_stat4', 'dim_stat4_n',
+                'dim_stddev', 'dim_stddev_n', 'dim_sum', 'dim_sum_n', 'dim_sum_wgt',
+                'dim_sum_wgt_n', 'dim_variance', 'dim_variance_n', 'dimsizes',
+                'doubletobyte', 'doubletochar', 'doubletocharacter',
+                'doubletofloat', 'doubletoint', 'doubletointeger', 'doubletolong',
+                'doubletoshort', 'dpres_hybrid_ccm', 'dpres_plevel', 'draw',
+                'draw_color_palette', 'dsgetp', 'dsgrid2', 'dsgrid2d', 'dsgrid2s',
+                'dsgrid3', 'dsgrid3d', 'dsgrid3s', 'dspnt2', 'dspnt2d', 'dspnt2s',
+                'dspnt3', 'dspnt3d', 'dspnt3s', 'dssetp', 'dtrend', 'dtrend_msg',
+                'dtrend_msg_n', 'dtrend_n', 'dtrend_quadratic',
+                'dtrend_quadratic_msg_n', 'dv2uvf', 'dv2uvg', 'dz_height',
+                'echo_off', 'echo_on', 'eof2data', 'eof_varimax', 'eofcor',
+                'eofcor_pcmsg', 'eofcor_ts', 'eofcov', 'eofcov_pcmsg', 'eofcov_ts',
+                'eofunc', 'eofunc_ts', 'eofunc_varimax', 'equiv_sample_size', 'erf',
+                'erfc', 'esacr', 'esacv', 'esccr', 'esccv', 'escorc', 'escorc_n',
+                'escovc', 'exit', 'exp', 'exp_tapersh', 'exp_tapersh_wgts',
+                'exp_tapershC', 'ezfftb', 'ezfftb_n', 'ezfftf', 'ezfftf_n',
+                'f2fosh', 'f2foshv', 'f2fsh', 'f2fshv', 'f2gsh', 'f2gshv', 'fabs',
+                'fbindirread', 'fbindirwrite', 'fbinnumrec', 'fbinread',
+                'fbinrecread', 'fbinrecwrite', 'fbinwrite', 'fft2db', 'fft2df',
+                'fftshift', 'fileattdef', 'filechunkdimdef', 'filedimdef',
+                'fileexists', 'filegrpdef', 'filevarattdef', 'filevarchunkdef',
+                'filevarcompressleveldef', 'filevardef', 'filevardimsizes',
+                'filwgts_lancos', 'filwgts_lanczos', 'filwgts_normal',
+                'floattobyte', 'floattochar', 'floattocharacter', 'floattoint',
+                'floattointeger', 'floattolong', 'floattoshort', 'floor',
+                'fluxEddy', 'fo2fsh', 'fo2fshv', 'fourier_info', 'frame', 'fspan',
+                'ftcurv', 'ftcurvd', 'ftcurvi', 'ftcurvp', 'ftcurvpi', 'ftcurvps',
+                'ftcurvs', 'ftest', 'ftgetp', 'ftkurv', 'ftkurvd', 'ftkurvp',
+                'ftkurvpd', 'ftsetp', 'ftsurf', 'g2fsh', 'g2fshv', 'g2gsh',
+                'g2gshv', 'gamma', 'gammainc', 'gaus', 'gaus_lobat',
+                'gaus_lobat_wgt', 'gc_aangle', 'gc_clkwise', 'gc_dangle',
+                'gc_inout', 'gc_latlon', 'gc_onarc', 'gc_pnt2gc', 'gc_qarea',
+                'gc_tarea', 'generate_2d_array', 'get_color_index',
+                'get_color_rgba', 'get_cpu_time', 'get_isolines', 'get_ncl_version',
+                'get_script_name', 'get_script_prefix_name', 'get_sphere_radius',
+                'get_unique_values', 'getbitsone', 'getenv', 'getfiledimsizes',
+                'getfilegrpnames', 'getfilepath', 'getfilevaratts',
+                'getfilevarchunkdimsizes', 'getfilevardims', 'getfilevardimsizes',
+                'getfilevarnames', 'getfilevartypes', 'getvaratts', 'getvardims',
+                'gradsf', 'gradsg', 'greg2jul', 'grid2triple', 'hlsrgb', 'hsvrgb',
+                'hydro', 'hyi2hyo', 'idsfft', 'igradsf', 'igradsg', 'ilapsf',
+                'ilapsg', 'ilapvf', 'ilapvg', 'ind', 'ind_resolve', 'int2p',
+                'int2p_n', 'integertobyte', 'integertochar', 'integertocharacter',
+                'integertoshort', 'inttobyte', 'inttochar', 'inttoshort',
+                'inverse_matrix', 'isatt', 'isbigendian', 'isbyte', 'ischar',
+                'iscoord', 'isdefined', 'isdim', 'isdimnamed', 'isdouble',
+                'isenumeric', 'isfile', 'isfilepresent', 'isfilevar',
+                'isfilevaratt', 'isfilevarcoord', 'isfilevardim', 'isfloat',
+                'isfunc', 'isgraphic', 'isint', 'isint64', 'isinteger',
+                'isleapyear', 'islogical', 'islong', 'ismissing', 'isnan_ieee',
+                'isnumeric', 'ispan', 'isproc', 'isshort', 'issnumeric', 'isstring',
+                'isubyte', 'isuint', 'isuint64', 'isulong', 'isunlimited',
+                'isunsigned', 'isushort', 'isvar', 'jul2greg', 'kmeans_as136',
+                'kolsm2_n', 'kron_product', 'lapsf', 'lapsg', 'lapvf', 'lapvg',
+                'latlon2utm', 'lclvl', 'lderuvf', 'lderuvg', 'linint1', 'linint1_n',
+                'linint2', 'linint2_points', 'linmsg', 'linmsg_n', 'linrood_latwgt',
+                'linrood_wgt', 'list_files', 'list_filevars', 'list_hlus',
+                'list_procfuncs', 'list_vars', 'ListAppend', 'ListCount',
+                'ListGetType', 'ListIndex', 'ListIndexFromName', 'ListPop',
+                'ListPush', 'ListSetType', 'loadscript', 'local_max', 'local_min',
+                'log', 'log10', 'longtobyte', 'longtochar', 'longtocharacter',
+                'longtoint', 'longtointeger', 'longtoshort', 'lspoly', 'lspoly_n',
+                'mask', 'max', 'maxind', 'min', 'minind', 'mixed_layer_depth',
+                'mixhum_ptd', 'mixhum_ptrh', 'mjo_cross_coh2pha',
+                'mjo_cross_segment', 'moc_globe_atl', 'monthday', 'natgrid',
+                'natgridd', 'natgrids', 'ncargpath', 'ncargversion', 'ndctodata',
+                'ndtooned', 'new', 'NewList', 'ngezlogo', 'nggcog', 'nggetp',
+                'nglogo', 'ngsetp', 'NhlAddAnnotation', 'NhlAddData',
+                'NhlAddOverlay', 'NhlAddPrimitive', 'NhlAppGetDefaultParentId',
+                'NhlChangeWorkstation', 'NhlClassName', 'NhlClearWorkstation',
+                'NhlDataPolygon', 'NhlDataPolyline', 'NhlDataPolymarker',
+                'NhlDataToNDC', 'NhlDestroy', 'NhlDraw', 'NhlFrame', 'NhlFreeColor',
+                'NhlGetBB', 'NhlGetClassResources', 'NhlGetErrorObjectId',
+                'NhlGetNamedColorIndex', 'NhlGetParentId',
+                'NhlGetParentWorkstation', 'NhlGetWorkspaceObjectId',
+                'NhlIsAllocatedColor', 'NhlIsApp', 'NhlIsDataComm', 'NhlIsDataItem',
+                'NhlIsDataSpec', 'NhlIsTransform', 'NhlIsView', 'NhlIsWorkstation',
+                'NhlName', 'NhlNDCPolygon', 'NhlNDCPolyline', 'NhlNDCPolymarker',
+                'NhlNDCToData', 'NhlNewColor', 'NhlNewDashPattern', 'NhlNewMarker',
+                'NhlPalGetDefined', 'NhlRemoveAnnotation', 'NhlRemoveData',
+                'NhlRemoveOverlay', 'NhlRemovePrimitive', 'NhlSetColor',
+                'NhlSetDashPattern', 'NhlSetMarker', 'NhlUpdateData',
+                'NhlUpdateWorkstation', 'nice_mnmxintvl', 'nngetaspectd',
+                'nngetaspects', 'nngetp', 'nngetsloped', 'nngetslopes', 'nngetwts',
+                'nngetwtsd', 'nnpnt', 'nnpntd', 'nnpntend', 'nnpntendd',
+                'nnpntinit', 'nnpntinitd', 'nnpntinits', 'nnpnts', 'nnsetp', 'num',
+                'obj_anal_ic', 'omega_ccm', 'onedtond', 'overlay', 'paleo_outline',
+                'pdfxy_bin', 'poisson_grid_fill', 'pop_remap', 'potmp_insitu_ocn',
+                'prcwater_dp', 'pres2hybrid', 'pres_hybrid_ccm', 'pres_sigma',
+                'print', 'print_table', 'printFileVarSummary', 'printVarSummary',
+                'product', 'pslec', 'pslhor', 'pslhyp', 'qsort', 'rand',
+                'random_chi', 'random_gamma', 'random_normal', 'random_setallseed',
+                'random_uniform', 'rcm2points', 'rcm2rgrid', 'rdsstoi',
+                'read_colormap_file', 'reg_multlin', 'regcoef', 'regCoef_n',
+                'regline', 'relhum', 'replace_ieeenan', 'reshape', 'reshape_ind',
+                'rgba_to_color_index', 'rgbhls', 'rgbhsv', 'rgbyiq', 'rgrid2rcm',
+                'rhomb_trunc', 'rip_cape_2d', 'rip_cape_3d', 'round', 'rtest',
+                'runave', 'runave_n', 'set_default_fillvalue', 'set_sphere_radius',
+                'setfileoption', 'sfvp2uvf', 'sfvp2uvg', 'shaec', 'shagc',
+                'shgetnp', 'shgetp', 'shgrid', 'shorttobyte', 'shorttochar',
+                'shorttocharacter', 'show_ascii', 'shsec', 'shsetp', 'shsgc',
+                'shsgc_R42', 'sigma2hybrid', 'simpeq', 'simpne', 'sin',
+                'sindex_yrmo', 'sinh', 'sizeof', 'sleep', 'smth9', 'snindex_yrmo',
+                'solve_linsys', 'span_color_indexes', 'span_color_rgba',
+                'sparse_matrix_mult', 'spcorr', 'spcorr_n', 'specx_anal',
+                'specxy_anal', 'spei', 'sprintf', 'sprinti', 'sqrt', 'sqsort',
+                'srand', 'stat2', 'stat4', 'stat_medrng', 'stat_trim',
+                'status_exit', 'stdatmus_p2tdz', 'stdatmus_z2tdp', 'stddev',
+                'str_capital', 'str_concat', 'str_fields_count', 'str_get_cols',
+                'str_get_dq', 'str_get_field', 'str_get_nl', 'str_get_sq',
+                'str_get_tab', 'str_index_of_substr', 'str_insert', 'str_is_blank',
+                'str_join', 'str_left_strip', 'str_lower', 'str_match',
+                'str_match_ic', 'str_match_ic_regex', 'str_match_ind',
+                'str_match_ind_ic', 'str_match_ind_ic_regex', 'str_match_ind_regex',
+                'str_match_regex', 'str_right_strip', 'str_split',
+                'str_split_by_length', 'str_split_csv', 'str_squeeze', 'str_strip',
+                'str_sub_str', 'str_switch', 'str_upper', 'stringtochar',
+                'stringtocharacter', 'stringtodouble', 'stringtofloat',
+                'stringtoint', 'stringtointeger', 'stringtolong', 'stringtoshort',
+                'strlen', 'student_t', 'sum', 'svd_lapack', 'svdcov', 'svdcov_sv',
+                'svdstd', 'svdstd_sv', 'system', 'systemfunc', 'tan', 'tanh',
+                'taper', 'taper_n', 'tdclrs', 'tdctri', 'tdcudp', 'tdcurv',
+                'tddtri', 'tdez2d', 'tdez3d', 'tdgetp', 'tdgrds', 'tdgrid',
+                'tdgtrs', 'tdinit', 'tditri', 'tdlbla', 'tdlblp', 'tdlbls',
+                'tdline', 'tdlndp', 'tdlnpa', 'tdlpdp', 'tdmtri', 'tdotri',
+                'tdpara', 'tdplch', 'tdprpa', 'tdprpi', 'tdprpt', 'tdsetp',
+                'tdsort', 'tdstri', 'tdstrs', 'tdttri', 'thornthwaite', 'tobyte',
+                'tochar', 'todouble', 'tofloat', 'toint', 'toint64', 'tointeger',
+                'tolong', 'toshort', 'tosigned', 'tostring', 'tostring_with_format',
+                'totype', 'toubyte', 'touint', 'touint64', 'toulong', 'tounsigned',
+                'toushort', 'trend_manken', 'tri_trunc', 'triple2grid',
+                'triple2grid2d', 'trop_wmo', 'ttest', 'typeof', 'undef',
+                'unique_string', 'update', 'ushorttoint', 'ut_calendar',
+                'ut_inv_calendar', 'utm2latlon', 'uv2dv_cfd', 'uv2dvf', 'uv2dvg',
+                'uv2sfvpf', 'uv2sfvpg', 'uv2vr_cfd', 'uv2vrdvf', 'uv2vrdvg',
+                'uv2vrf', 'uv2vrg', 'v5d_close', 'v5d_create', 'v5d_setLowLev',
+                'v5d_setUnits', 'v5d_write', 'v5d_write_var', 'variance', 'vhaec',
+                'vhagc', 'vhsec', 'vhsgc', 'vibeta', 'vinth2p', 'vinth2p_ecmwf',
+                'vinth2p_ecmwf_nodes', 'vinth2p_nodes', 'vintp2p_ecmwf', 'vr2uvf',
+                'vr2uvg', 'vrdv2uvf', 'vrdv2uvg', 'wavelet', 'wavelet_default',
+                'weibull', 'wgt_area_smooth', 'wgt_areaave', 'wgt_areaave2',
+                'wgt_arearmse', 'wgt_arearmse2', 'wgt_areasum2', 'wgt_runave',
+                'wgt_runave_n', 'wgt_vert_avg_beta', 'wgt_volave', 'wgt_volave_ccm',
+                'wgt_volrmse', 'wgt_volrmse_ccm', 'where', 'wk_smooth121', 'wmbarb',
+                'wmbarbmap', 'wmdrft', 'wmgetp', 'wmlabs', 'wmsetp', 'wmstnm',
+                'wmvect', 'wmvectmap', 'wmvlbl', 'wrf_avo', 'wrf_cape_2d',
+                'wrf_cape_3d', 'wrf_dbz', 'wrf_eth', 'wrf_helicity', 'wrf_ij_to_ll',
+                'wrf_interp_1d', 'wrf_interp_2d_xy', 'wrf_interp_3d_z',
+                'wrf_latlon_to_ij', 'wrf_ll_to_ij', 'wrf_omega', 'wrf_pvo',
+                'wrf_rh', 'wrf_slp', 'wrf_smooth_2d', 'wrf_td', 'wrf_tk',
+                'wrf_updraft_helicity', 'wrf_uvmet', 'wrf_virtual_temp',
+                'wrf_wetbulb', 'wrf_wps_close_int', 'wrf_wps_open_int',
+                'wrf_wps_rddata_int', 'wrf_wps_rdhead_int', 'wrf_wps_read_int',
+                'wrf_wps_write_int', 'write_matrix', 'write_table', 'yiqrgb',
+                'z2geouv', 'zonal_mpsi', 'addfiles_GetVar', 'advect_variable',
+                'area_conserve_remap_Wrap', 'area_hi2lores_Wrap',
+                'array_append_record', 'assignFillValue', 'byte2flt',
+                'byte2flt_hdf', 'calcDayAnomTLL', 'calcMonAnomLLLT',
+                'calcMonAnomLLT', 'calcMonAnomTLL', 'calcMonAnomTLLL',
+                'calculate_monthly_values', 'cd_convert', 'changeCase',
+                'changeCaseChar', 'clmDayTLL', 'clmDayTLLL', 'clmMon2clmDay',
+                'clmMonLLLT', 'clmMonLLT', 'clmMonTLL', 'clmMonTLLL', 'closest_val',
+                'copy_VarAtts', 'copy_VarCoords', 'copy_VarCoords_1',
+                'copy_VarCoords_2', 'copy_VarMeta', 'copyatt', 'crossp3',
+                'cshstringtolist', 'cssgrid_Wrap', 'dble2flt', 'decimalPlaces',
+                'delete_VarAtts', 'dim_avg_n_Wrap', 'dim_avg_wgt_n_Wrap',
+                'dim_avg_wgt_Wrap', 'dim_avg_Wrap', 'dim_cumsum_n_Wrap',
+                'dim_cumsum_Wrap', 'dim_max_n_Wrap', 'dim_min_n_Wrap',
+                'dim_rmsd_n_Wrap', 'dim_rmsd_Wrap', 'dim_rmvmean_n_Wrap',
+                'dim_rmvmean_Wrap', 'dim_rmvmed_n_Wrap', 'dim_rmvmed_Wrap',
+                'dim_standardize_n_Wrap', 'dim_standardize_Wrap',
+                'dim_stddev_n_Wrap', 'dim_stddev_Wrap', 'dim_sum_n_Wrap',
+                'dim_sum_wgt_n_Wrap', 'dim_sum_wgt_Wrap', 'dim_sum_Wrap',
+                'dim_variance_n_Wrap', 'dim_variance_Wrap', 'dpres_plevel_Wrap',
+                'dtrend_leftdim', 'dv2uvF_Wrap', 'dv2uvG_Wrap', 'eof_north',
+                'eofcor_Wrap', 'eofcov_Wrap', 'eofunc_north', 'eofunc_ts_Wrap',
+                'eofunc_varimax_reorder', 'eofunc_varimax_Wrap', 'eofunc_Wrap',
+                'epsZero', 'f2fosh_Wrap', 'f2foshv_Wrap', 'f2fsh_Wrap',
+                'f2fshv_Wrap', 'f2gsh_Wrap', 'f2gshv_Wrap', 'fbindirSwap',
+                'fbinseqSwap1', 'fbinseqSwap2', 'flt2dble', 'flt2string',
+                'fo2fsh_Wrap', 'fo2fshv_Wrap', 'g2fsh_Wrap', 'g2fshv_Wrap',
+                'g2gsh_Wrap', 'g2gshv_Wrap', 'generate_resample_indices',
+                'generate_sample_indices', 'generate_unique_indices',
+                'genNormalDist', 'get1Dindex', 'get1Dindex_Collapse',
+                'get1Dindex_Exclude', 'get_file_suffix', 'GetFillColor',
+                'GetFillColorIndex', 'getFillValue', 'getind_latlon2d',
+                'getVarDimNames', 'getVarFillValue', 'grib_stime2itime',
+                'hyi2hyo_Wrap', 'ilapsF_Wrap', 'ilapsG_Wrap', 'ind_nearest_coord',
+                'indStrSubset', 'int2dble', 'int2flt', 'int2p_n_Wrap', 'int2p_Wrap',
+                'isMonotonic', 'isStrSubset', 'latGau', 'latGauWgt', 'latGlobeF',
+                'latGlobeFo', 'latRegWgt', 'linint1_n_Wrap', 'linint1_Wrap',
+                'linint2_points_Wrap', 'linint2_Wrap', 'local_max_1d',
+                'local_min_1d', 'lonFlip', 'lonGlobeF', 'lonGlobeFo', 'lonPivot',
+                'merge_levels_sfc', 'mod', 'month_to_annual',
+                'month_to_annual_weighted', 'month_to_season', 'month_to_season12',
+                'month_to_seasonN', 'monthly_total_to_daily_mean', 'nameDim',
+                'natgrid_Wrap', 'NewCosWeight', 'niceLatLon2D', 'NormCosWgtGlobe',
+                'numAsciiCol', 'numAsciiRow', 'numeric2int',
+                'obj_anal_ic_deprecated', 'obj_anal_ic_Wrap', 'omega_ccm_driver',
+                'omega_to_w', 'oneDtostring', 'pack_values', 'pattern_cor', 'pdfx',
+                'pdfxy', 'pdfxy_conform', 'pot_temp', 'pot_vort_hybrid',
+                'pot_vort_isobaric', 'pres2hybrid_Wrap', 'print_clock',
+                'printMinMax', 'quadroots', 'rcm2points_Wrap', 'rcm2rgrid_Wrap',
+                'readAsciiHead', 'readAsciiTable', 'reg_multlin_stats',
+                'region_ind', 'regline_stats', 'relhum_ttd', 'replaceSingleChar',
+                'RGBtoCmap', 'rgrid2rcm_Wrap', 'rho_mwjf', 'rm_single_dims',
+                'rmAnnCycle1D', 'rmInsufData', 'rmMonAnnCycLLLT', 'rmMonAnnCycLLT',
+                'rmMonAnnCycTLL', 'runave_n_Wrap', 'runave_Wrap', 'short2flt',
+                'short2flt_hdf', 'shsgc_R42_Wrap', 'sign_f90', 'sign_matlab',
+                'smth9_Wrap', 'smthClmDayTLL', 'smthClmDayTLLL', 'SqrtCosWeight',
+                'stat_dispersion', 'static_stability', 'stdMonLLLT', 'stdMonLLT',
+                'stdMonTLL', 'stdMonTLLL', 'symMinMaxPlt', 'table_attach_columns',
+                'table_attach_rows', 'time_to_newtime', 'transpose',
+                'triple2grid_Wrap', 'ut_convert', 'uv2dvF_Wrap', 'uv2dvG_Wrap',
+                'uv2vrF_Wrap', 'uv2vrG_Wrap', 'vr2uvF_Wrap', 'vr2uvG_Wrap',
+                'w_to_omega', 'wallClockElapseTime', 'wave_number_spc',
+                'wgt_areaave_Wrap', 'wgt_runave_leftdim', 'wgt_runave_n_Wrap',
+                'wgt_runave_Wrap', 'wgt_vertical_n', 'wind_component',
+                'wind_direction', 'yyyyddd_to_yyyymmdd', 'yyyymm_time',
+                'yyyymm_to_yyyyfrac', 'yyyymmdd_time', 'yyyymmdd_to_yyyyddd',
+                'yyyymmdd_to_yyyyfrac', 'yyyymmddhh_time', 'yyyymmddhh_to_yyyyfrac',
+                'zonal_mpsi_Wrap', 'zonalAve', 'calendar_decode2', 'cd_string',
+                'kf_filter', 'run_cor', 'time_axis_labels', 'ut_string',
+                'wrf_contour', 'wrf_map', 'wrf_map_overlay', 'wrf_map_overlays',
+                'wrf_map_resources', 'wrf_map_zoom', 'wrf_overlay', 'wrf_overlays',
+                'wrf_user_getvar', 'wrf_user_ij_to_ll', 'wrf_user_intrp2d',
+                'wrf_user_intrp3d', 'wrf_user_latlon_to_ij', 'wrf_user_list_times',
+                'wrf_user_ll_to_ij', 'wrf_user_unstagger', 'wrf_user_vert_interp',
+                'wrf_vector', 'gsn_add_annotation', 'gsn_add_polygon',
+                'gsn_add_polyline', 'gsn_add_polymarker',
+                'gsn_add_shapefile_polygons', 'gsn_add_shapefile_polylines',
+                'gsn_add_shapefile_polymarkers', 'gsn_add_text', 'gsn_attach_plots',
+                'gsn_blank_plot', 'gsn_contour', 'gsn_contour_map',
+                'gsn_contour_shade', 'gsn_coordinates', 'gsn_create_labelbar',
+                'gsn_create_legend', 'gsn_create_text',
+                'gsn_csm_attach_zonal_means', 'gsn_csm_blank_plot',
+                'gsn_csm_contour', 'gsn_csm_contour_map', 'gsn_csm_contour_map_ce',
+                'gsn_csm_contour_map_overlay', 'gsn_csm_contour_map_polar',
+                'gsn_csm_hov', 'gsn_csm_lat_time', 'gsn_csm_map', 'gsn_csm_map_ce',
+                'gsn_csm_map_polar', 'gsn_csm_pres_hgt',
+                'gsn_csm_pres_hgt_streamline', 'gsn_csm_pres_hgt_vector',
+                'gsn_csm_streamline', 'gsn_csm_streamline_contour_map',
+                'gsn_csm_streamline_contour_map_ce',
+                'gsn_csm_streamline_contour_map_polar', 'gsn_csm_streamline_map',
+                'gsn_csm_streamline_map_ce', 'gsn_csm_streamline_map_polar',
+                'gsn_csm_streamline_scalar', 'gsn_csm_streamline_scalar_map',
+                'gsn_csm_streamline_scalar_map_ce',
+                'gsn_csm_streamline_scalar_map_polar', 'gsn_csm_time_lat',
+                'gsn_csm_vector', 'gsn_csm_vector_map', 'gsn_csm_vector_map_ce',
+                'gsn_csm_vector_map_polar', 'gsn_csm_vector_scalar',
+                'gsn_csm_vector_scalar_map', 'gsn_csm_vector_scalar_map_ce',
+                'gsn_csm_vector_scalar_map_polar', 'gsn_csm_x2y', 'gsn_csm_x2y2',
+                'gsn_csm_xy', 'gsn_csm_xy2', 'gsn_csm_xy3', 'gsn_csm_y',
+                'gsn_define_colormap', 'gsn_draw_colormap', 'gsn_draw_named_colors',
+                'gsn_histogram', 'gsn_labelbar_ndc', 'gsn_legend_ndc', 'gsn_map',
+                'gsn_merge_colormaps', 'gsn_open_wks', 'gsn_panel', 'gsn_polygon',
+                'gsn_polygon_ndc', 'gsn_polyline', 'gsn_polyline_ndc',
+                'gsn_polymarker', 'gsn_polymarker_ndc', 'gsn_retrieve_colormap',
+                'gsn_reverse_colormap', 'gsn_streamline', 'gsn_streamline_map',
+                'gsn_streamline_scalar', 'gsn_streamline_scalar_map', 'gsn_table',
+                'gsn_text', 'gsn_text_ndc', 'gsn_vector', 'gsn_vector_map',
+                'gsn_vector_scalar', 'gsn_vector_scalar_map', 'gsn_xy', 'gsn_y',
+                'hsv2rgb', 'maximize_output', 'namedcolor2rgb', 'namedcolor2rgba',
+                'reset_device_coordinates', 'span_named_colors'), prefix=r'\b'),
+             Name.Builtin),
+
+            # Resources
+            (words((
+                'amDataXF', 'amDataYF', 'amJust', 'amOn', 'amOrthogonalPosF',
+                'amParallelPosF', 'amResizeNotify', 'amSide', 'amTrackData',
+                'amViewId', 'amZone', 'appDefaultParent', 'appFileSuffix',
+                'appResources', 'appSysDir', 'appUsrDir', 'caCopyArrays',
+                'caXArray', 'caXCast', 'caXMaxV', 'caXMinV', 'caXMissingV',
+                'caYArray', 'caYCast', 'caYMaxV', 'caYMinV', 'caYMissingV',
+                'cnCellFillEdgeColor', 'cnCellFillMissingValEdgeColor',
+                'cnConpackParams', 'cnConstFEnableFill', 'cnConstFLabelAngleF',
+                'cnConstFLabelBackgroundColor', 'cnConstFLabelConstantSpacingF',
+                'cnConstFLabelFont', 'cnConstFLabelFontAspectF',
+                'cnConstFLabelFontColor', 'cnConstFLabelFontHeightF',
+                'cnConstFLabelFontQuality', 'cnConstFLabelFontThicknessF',
+                'cnConstFLabelFormat', 'cnConstFLabelFuncCode', 'cnConstFLabelJust',
+                'cnConstFLabelOn', 'cnConstFLabelOrthogonalPosF',
+                'cnConstFLabelParallelPosF', 'cnConstFLabelPerimColor',
+                'cnConstFLabelPerimOn', 'cnConstFLabelPerimSpaceF',
+                'cnConstFLabelPerimThicknessF', 'cnConstFLabelSide',
+                'cnConstFLabelString', 'cnConstFLabelTextDirection',
+                'cnConstFLabelZone', 'cnConstFUseInfoLabelRes',
+                'cnExplicitLabelBarLabelsOn', 'cnExplicitLegendLabelsOn',
+                'cnExplicitLineLabelsOn', 'cnFillBackgroundColor', 'cnFillColor',
+                'cnFillColors', 'cnFillDotSizeF', 'cnFillDrawOrder', 'cnFillMode',
+                'cnFillOn', 'cnFillOpacityF', 'cnFillPalette', 'cnFillPattern',
+                'cnFillPatterns', 'cnFillScaleF', 'cnFillScales', 'cnFixFillBleed',
+                'cnGridBoundFillColor', 'cnGridBoundFillPattern',
+                'cnGridBoundFillScaleF', 'cnGridBoundPerimColor',
+                'cnGridBoundPerimDashPattern', 'cnGridBoundPerimOn',
+                'cnGridBoundPerimThicknessF', 'cnHighLabelAngleF',
+                'cnHighLabelBackgroundColor', 'cnHighLabelConstantSpacingF',
+                'cnHighLabelCount', 'cnHighLabelFont', 'cnHighLabelFontAspectF',
+                'cnHighLabelFontColor', 'cnHighLabelFontHeightF',
+                'cnHighLabelFontQuality', 'cnHighLabelFontThicknessF',
+                'cnHighLabelFormat', 'cnHighLabelFuncCode', 'cnHighLabelPerimColor',
+                'cnHighLabelPerimOn', 'cnHighLabelPerimSpaceF',
+                'cnHighLabelPerimThicknessF', 'cnHighLabelString', 'cnHighLabelsOn',
+                'cnHighLowLabelOverlapMode', 'cnHighUseLineLabelRes',
+                'cnInfoLabelAngleF', 'cnInfoLabelBackgroundColor',
+                'cnInfoLabelConstantSpacingF', 'cnInfoLabelFont',
+                'cnInfoLabelFontAspectF', 'cnInfoLabelFontColor',
+                'cnInfoLabelFontHeightF', 'cnInfoLabelFontQuality',
+                'cnInfoLabelFontThicknessF', 'cnInfoLabelFormat',
+                'cnInfoLabelFuncCode', 'cnInfoLabelJust', 'cnInfoLabelOn',
+                'cnInfoLabelOrthogonalPosF', 'cnInfoLabelParallelPosF',
+                'cnInfoLabelPerimColor', 'cnInfoLabelPerimOn',
+                'cnInfoLabelPerimSpaceF', 'cnInfoLabelPerimThicknessF',
+                'cnInfoLabelSide', 'cnInfoLabelString', 'cnInfoLabelTextDirection',
+                'cnInfoLabelZone', 'cnLabelBarEndLabelsOn', 'cnLabelBarEndStyle',
+                'cnLabelDrawOrder', 'cnLabelMasking', 'cnLabelScaleFactorF',
+                'cnLabelScaleValueF', 'cnLabelScalingMode', 'cnLegendLevelFlags',
+                'cnLevelCount', 'cnLevelFlag', 'cnLevelFlags', 'cnLevelSelectionMode',
+                'cnLevelSpacingF', 'cnLevels', 'cnLineColor', 'cnLineColors',
+                'cnLineDashPattern', 'cnLineDashPatterns', 'cnLineDashSegLenF',
+                'cnLineDrawOrder', 'cnLineLabelAngleF', 'cnLineLabelBackgroundColor',
+                'cnLineLabelConstantSpacingF', 'cnLineLabelCount',
+                'cnLineLabelDensityF', 'cnLineLabelFont', 'cnLineLabelFontAspectF',
+                'cnLineLabelFontColor', 'cnLineLabelFontColors',
+                'cnLineLabelFontHeightF', 'cnLineLabelFontQuality',
+                'cnLineLabelFontThicknessF', 'cnLineLabelFormat',
+                'cnLineLabelFuncCode', 'cnLineLabelInterval', 'cnLineLabelPerimColor',
+                'cnLineLabelPerimOn', 'cnLineLabelPerimSpaceF',
+                'cnLineLabelPerimThicknessF', 'cnLineLabelPlacementMode',
+                'cnLineLabelStrings', 'cnLineLabelsOn', 'cnLinePalette',
+                'cnLineThicknessF', 'cnLineThicknesses', 'cnLinesOn',
+                'cnLowLabelAngleF', 'cnLowLabelBackgroundColor',
+                'cnLowLabelConstantSpacingF', 'cnLowLabelCount', 'cnLowLabelFont',
+                'cnLowLabelFontAspectF', 'cnLowLabelFontColor',
+                'cnLowLabelFontHeightF', 'cnLowLabelFontQuality',
+                'cnLowLabelFontThicknessF', 'cnLowLabelFormat', 'cnLowLabelFuncCode',
+                'cnLowLabelPerimColor', 'cnLowLabelPerimOn', 'cnLowLabelPerimSpaceF',
+                'cnLowLabelPerimThicknessF', 'cnLowLabelString', 'cnLowLabelsOn',
+                'cnLowUseHighLabelRes', 'cnMaxDataValueFormat', 'cnMaxLevelCount',
+                'cnMaxLevelValF', 'cnMaxPointDistanceF', 'cnMinLevelValF',
+                'cnMissingValFillColor', 'cnMissingValFillPattern',
+                'cnMissingValFillScaleF', 'cnMissingValPerimColor',
+                'cnMissingValPerimDashPattern', 'cnMissingValPerimGridBoundOn',
+                'cnMissingValPerimOn', 'cnMissingValPerimThicknessF',
+                'cnMonoFillColor', 'cnMonoFillPattern', 'cnMonoFillScale',
+                'cnMonoLevelFlag', 'cnMonoLineColor', 'cnMonoLineDashPattern',
+                'cnMonoLineLabelFontColor', 'cnMonoLineThickness', 'cnNoDataLabelOn',
+                'cnNoDataLabelString', 'cnOutOfRangeFillColor',
+                'cnOutOfRangeFillPattern', 'cnOutOfRangeFillScaleF',
+                'cnOutOfRangePerimColor', 'cnOutOfRangePerimDashPattern',
+                'cnOutOfRangePerimOn', 'cnOutOfRangePerimThicknessF',
+                'cnRasterCellSizeF', 'cnRasterMinCellSizeF', 'cnRasterModeOn',
+                'cnRasterSampleFactorF', 'cnRasterSmoothingOn', 'cnScalarFieldData',
+                'cnSmoothingDistanceF', 'cnSmoothingOn', 'cnSmoothingTensionF',
+                'cnSpanFillPalette', 'cnSpanLinePalette', 'ctCopyTables',
+                'ctXElementSize', 'ctXMaxV', 'ctXMinV', 'ctXMissingV', 'ctXTable',
+                'ctXTableLengths', 'ctXTableType', 'ctYElementSize', 'ctYMaxV',
+                'ctYMinV', 'ctYMissingV', 'ctYTable', 'ctYTableLengths',
+                'ctYTableType', 'dcDelayCompute', 'errBuffer',
+                'errFileName', 'errFilePtr', 'errLevel', 'errPrint', 'errUnitNumber',
+                'gsClipOn', 'gsColors', 'gsEdgeColor', 'gsEdgeDashPattern',
+                'gsEdgeDashSegLenF', 'gsEdgeThicknessF', 'gsEdgesOn',
+                'gsFillBackgroundColor', 'gsFillColor', 'gsFillDotSizeF',
+                'gsFillIndex', 'gsFillLineThicknessF', 'gsFillOpacityF',
+                'gsFillScaleF', 'gsFont', 'gsFontAspectF', 'gsFontColor',
+                'gsFontHeightF', 'gsFontOpacityF', 'gsFontQuality',
+                'gsFontThicknessF', 'gsLineColor', 'gsLineDashPattern',
+                'gsLineDashSegLenF', 'gsLineLabelConstantSpacingF', 'gsLineLabelFont',
+                'gsLineLabelFontAspectF', 'gsLineLabelFontColor',
+                'gsLineLabelFontHeightF', 'gsLineLabelFontQuality',
+                'gsLineLabelFontThicknessF', 'gsLineLabelFuncCode',
+                'gsLineLabelString', 'gsLineOpacityF', 'gsLineThicknessF',
+                'gsMarkerColor', 'gsMarkerIndex', 'gsMarkerOpacityF', 'gsMarkerSizeF',
+                'gsMarkerThicknessF', 'gsSegments', 'gsTextAngleF',
+                'gsTextConstantSpacingF', 'gsTextDirection', 'gsTextFuncCode',
+                'gsTextJustification', 'gsnAboveYRefLineBarColors',
+                'gsnAboveYRefLineBarFillScales', 'gsnAboveYRefLineBarPatterns',
+                'gsnAboveYRefLineColor', 'gsnAddCyclic', 'gsnAttachBorderOn',
+                'gsnAttachPlotsXAxis', 'gsnBelowYRefLineBarColors',
+                'gsnBelowYRefLineBarFillScales', 'gsnBelowYRefLineBarPatterns',
+                'gsnBelowYRefLineColor', 'gsnBoxMargin', 'gsnCenterString',
+                'gsnCenterStringFontColor', 'gsnCenterStringFontHeightF',
+                'gsnCenterStringFuncCode', 'gsnCenterStringOrthogonalPosF',
+                'gsnCenterStringParallelPosF', 'gsnContourLineThicknessesScale',
+                'gsnContourNegLineDashPattern', 'gsnContourPosLineDashPattern',
+                'gsnContourZeroLineThicknessF', 'gsnDebugWriteFileName', 'gsnDraw',
+                'gsnFrame', 'gsnHistogramBarWidthPercent', 'gsnHistogramBinIntervals',
+                'gsnHistogramBinMissing', 'gsnHistogramBinWidth',
+                'gsnHistogramClassIntervals', 'gsnHistogramCompare',
+                'gsnHistogramComputePercentages',
+                'gsnHistogramComputePercentagesNoMissing',
+                'gsnHistogramDiscreteBinValues', 'gsnHistogramDiscreteClassValues',
+                'gsnHistogramHorizontal', 'gsnHistogramMinMaxBinsOn',
+                'gsnHistogramNumberOfBins', 'gsnHistogramPercentSign',
+                'gsnHistogramSelectNiceIntervals', 'gsnLeftString',
+                'gsnLeftStringFontColor', 'gsnLeftStringFontHeightF',
+                'gsnLeftStringFuncCode', 'gsnLeftStringOrthogonalPosF',
+                'gsnLeftStringParallelPosF', 'gsnMajorLatSpacing',
+                'gsnMajorLonSpacing', 'gsnMaskLambertConformal',
+                'gsnMaskLambertConformalOutlineOn', 'gsnMaximize',
+                'gsnMinorLatSpacing', 'gsnMinorLonSpacing', 'gsnPanelBottom',
+                'gsnPanelCenter', 'gsnPanelDebug', 'gsnPanelFigureStrings',
+                'gsnPanelFigureStringsBackgroundFillColor',
+                'gsnPanelFigureStringsFontHeightF', 'gsnPanelFigureStringsJust',
+                'gsnPanelFigureStringsPerimOn', 'gsnPanelLabelBar', 'gsnPanelLeft',
+                'gsnPanelMainFont', 'gsnPanelMainFontColor',
+                'gsnPanelMainFontHeightF', 'gsnPanelMainString', 'gsnPanelRight',
+                'gsnPanelRowSpec', 'gsnPanelScalePlotIndex', 'gsnPanelTop',
+                'gsnPanelXF', 'gsnPanelXWhiteSpacePercent', 'gsnPanelYF',
+                'gsnPanelYWhiteSpacePercent', 'gsnPaperHeight', 'gsnPaperMargin',
+                'gsnPaperOrientation', 'gsnPaperWidth', 'gsnPolar',
+                'gsnPolarLabelDistance', 'gsnPolarLabelFont',
+                'gsnPolarLabelFontHeightF', 'gsnPolarLabelSpacing', 'gsnPolarTime',
+                'gsnPolarUT', 'gsnRightString', 'gsnRightStringFontColor',
+                'gsnRightStringFontHeightF', 'gsnRightStringFuncCode',
+                'gsnRightStringOrthogonalPosF', 'gsnRightStringParallelPosF',
+                'gsnScalarContour', 'gsnScale', 'gsnShape', 'gsnSpreadColorEnd',
+                'gsnSpreadColorStart', 'gsnSpreadColors', 'gsnStringFont',
+                'gsnStringFontColor', 'gsnStringFontHeightF', 'gsnStringFuncCode',
+                'gsnTickMarksOn', 'gsnXAxisIrregular2Linear', 'gsnXAxisIrregular2Log',
+                'gsnXRefLine', 'gsnXRefLineColor', 'gsnXRefLineDashPattern',
+                'gsnXRefLineThicknessF', 'gsnXYAboveFillColors', 'gsnXYBarChart',
+                'gsnXYBarChartBarWidth', 'gsnXYBarChartColors',
+                'gsnXYBarChartColors2', 'gsnXYBarChartFillDotSizeF',
+                'gsnXYBarChartFillLineThicknessF', 'gsnXYBarChartFillOpacityF',
+                'gsnXYBarChartFillScaleF', 'gsnXYBarChartOutlineOnly',
+                'gsnXYBarChartOutlineThicknessF', 'gsnXYBarChartPatterns',
+                'gsnXYBarChartPatterns2', 'gsnXYBelowFillColors', 'gsnXYFillColors',
+                'gsnXYFillOpacities', 'gsnXYLeftFillColors', 'gsnXYRightFillColors',
+                'gsnYAxisIrregular2Linear', 'gsnYAxisIrregular2Log', 'gsnYRefLine',
+                'gsnYRefLineColor', 'gsnYRefLineColors', 'gsnYRefLineDashPattern',
+                'gsnYRefLineDashPatterns', 'gsnYRefLineThicknessF',
+                'gsnYRefLineThicknesses', 'gsnZonalMean', 'gsnZonalMeanXMaxF',
+                'gsnZonalMeanXMinF', 'gsnZonalMeanYRefLine', 'lbAutoManage',
+                'lbBottomMarginF', 'lbBoxCount', 'lbBoxEndCapStyle', 'lbBoxFractions',
+                'lbBoxLineColor', 'lbBoxLineDashPattern', 'lbBoxLineDashSegLenF',
+                'lbBoxLineThicknessF', 'lbBoxLinesOn', 'lbBoxMajorExtentF',
+                'lbBoxMinorExtentF', 'lbBoxSeparatorLinesOn', 'lbBoxSizing',
+                'lbFillBackground', 'lbFillColor', 'lbFillColors', 'lbFillDotSizeF',
+                'lbFillLineThicknessF', 'lbFillPattern', 'lbFillPatterns',
+                'lbFillScaleF', 'lbFillScales', 'lbJustification', 'lbLabelAlignment',
+                'lbLabelAngleF', 'lbLabelAutoStride', 'lbLabelBarOn',
+                'lbLabelConstantSpacingF', 'lbLabelDirection', 'lbLabelFont',
+                'lbLabelFontAspectF', 'lbLabelFontColor', 'lbLabelFontHeightF',
+                'lbLabelFontQuality', 'lbLabelFontThicknessF', 'lbLabelFuncCode',
+                'lbLabelJust', 'lbLabelOffsetF', 'lbLabelPosition', 'lbLabelStride',
+                'lbLabelStrings', 'lbLabelsOn', 'lbLeftMarginF', 'lbMaxLabelLenF',
+                'lbMinLabelSpacingF', 'lbMonoFillColor', 'lbMonoFillPattern',
+                'lbMonoFillScale', 'lbOrientation', 'lbPerimColor',
+                'lbPerimDashPattern', 'lbPerimDashSegLenF', 'lbPerimFill',
+                'lbPerimFillColor', 'lbPerimOn', 'lbPerimThicknessF',
+                'lbRasterFillOn', 'lbRightMarginF', 'lbTitleAngleF',
+                'lbTitleConstantSpacingF', 'lbTitleDirection', 'lbTitleExtentF',
+                'lbTitleFont', 'lbTitleFontAspectF', 'lbTitleFontColor',
+                'lbTitleFontHeightF', 'lbTitleFontQuality', 'lbTitleFontThicknessF',
+                'lbTitleFuncCode', 'lbTitleJust', 'lbTitleOffsetF', 'lbTitleOn',
+                'lbTitlePosition', 'lbTitleString', 'lbTopMarginF', 'lgAutoManage',
+                'lgBottomMarginF', 'lgBoxBackground', 'lgBoxLineColor',
+                'lgBoxLineDashPattern', 'lgBoxLineDashSegLenF', 'lgBoxLineThicknessF',
+                'lgBoxLinesOn', 'lgBoxMajorExtentF', 'lgBoxMinorExtentF',
+                'lgDashIndex', 'lgDashIndexes', 'lgItemCount', 'lgItemOrder',
+                'lgItemPlacement', 'lgItemPositions', 'lgItemType', 'lgItemTypes',
+                'lgJustification', 'lgLabelAlignment', 'lgLabelAngleF',
+                'lgLabelAutoStride', 'lgLabelConstantSpacingF', 'lgLabelDirection',
+                'lgLabelFont', 'lgLabelFontAspectF', 'lgLabelFontColor',
+                'lgLabelFontHeightF', 'lgLabelFontQuality', 'lgLabelFontThicknessF',
+                'lgLabelFuncCode', 'lgLabelJust', 'lgLabelOffsetF', 'lgLabelPosition',
+                'lgLabelStride', 'lgLabelStrings', 'lgLabelsOn', 'lgLeftMarginF',
+                'lgLegendOn', 'lgLineColor', 'lgLineColors', 'lgLineDashSegLenF',
+                'lgLineDashSegLens', 'lgLineLabelConstantSpacingF', 'lgLineLabelFont',
+                'lgLineLabelFontAspectF', 'lgLineLabelFontColor',
+                'lgLineLabelFontColors', 'lgLineLabelFontHeightF',
+                'lgLineLabelFontHeights', 'lgLineLabelFontQuality',
+                'lgLineLabelFontThicknessF', 'lgLineLabelFuncCode',
+                'lgLineLabelStrings', 'lgLineLabelsOn', 'lgLineThicknessF',
+                'lgLineThicknesses', 'lgMarkerColor', 'lgMarkerColors',
+                'lgMarkerIndex', 'lgMarkerIndexes', 'lgMarkerSizeF', 'lgMarkerSizes',
+                'lgMarkerThicknessF', 'lgMarkerThicknesses', 'lgMonoDashIndex',
+                'lgMonoItemType', 'lgMonoLineColor', 'lgMonoLineDashSegLen',
+                'lgMonoLineLabelFontColor', 'lgMonoLineLabelFontHeight',
+                'lgMonoLineThickness', 'lgMonoMarkerColor', 'lgMonoMarkerIndex',
+                'lgMonoMarkerSize', 'lgMonoMarkerThickness', 'lgOrientation',
+                'lgPerimColor', 'lgPerimDashPattern', 'lgPerimDashSegLenF',
+                'lgPerimFill', 'lgPerimFillColor', 'lgPerimOn', 'lgPerimThicknessF',
+                'lgRightMarginF', 'lgTitleAngleF', 'lgTitleConstantSpacingF',
+                'lgTitleDirection', 'lgTitleExtentF', 'lgTitleFont',
+                'lgTitleFontAspectF', 'lgTitleFontColor', 'lgTitleFontHeightF',
+                'lgTitleFontQuality', 'lgTitleFontThicknessF', 'lgTitleFuncCode',
+                'lgTitleJust', 'lgTitleOffsetF', 'lgTitleOn', 'lgTitlePosition',
+                'lgTitleString', 'lgTopMarginF', 'mpAreaGroupCount',
+                'mpAreaMaskingOn', 'mpAreaNames', 'mpAreaTypes', 'mpBottomAngleF',
+                'mpBottomMapPosF', 'mpBottomNDCF', 'mpBottomNPCF',
+                'mpBottomPointLatF', 'mpBottomPointLonF', 'mpBottomWindowF',
+                'mpCenterLatF', 'mpCenterLonF', 'mpCenterRotF', 'mpCountyLineColor',
+                'mpCountyLineDashPattern', 'mpCountyLineDashSegLenF',
+                'mpCountyLineThicknessF', 'mpDataBaseVersion', 'mpDataResolution',
+                'mpDataSetName', 'mpDefaultFillColor', 'mpDefaultFillPattern',
+                'mpDefaultFillScaleF', 'mpDynamicAreaGroups', 'mpEllipticalBoundary',
+                'mpFillAreaSpecifiers', 'mpFillBoundarySets', 'mpFillColor',
+                'mpFillColors', 'mpFillColors-default', 'mpFillDotSizeF',
+                'mpFillDrawOrder', 'mpFillOn', 'mpFillPatternBackground',
+                'mpFillPattern', 'mpFillPatterns', 'mpFillPatterns-default',
+                'mpFillScaleF', 'mpFillScales', 'mpFillScales-default',
+                'mpFixedAreaGroups', 'mpGeophysicalLineColor',
+                'mpGeophysicalLineDashPattern', 'mpGeophysicalLineDashSegLenF',
+                'mpGeophysicalLineThicknessF', 'mpGreatCircleLinesOn',
+                'mpGridAndLimbDrawOrder', 'mpGridAndLimbOn', 'mpGridLatSpacingF',
+                'mpGridLineColor', 'mpGridLineDashPattern', 'mpGridLineDashSegLenF',
+                'mpGridLineThicknessF', 'mpGridLonSpacingF', 'mpGridMaskMode',
+                'mpGridMaxLatF', 'mpGridPolarLonSpacingF', 'mpGridSpacingF',
+                'mpInlandWaterFillColor', 'mpInlandWaterFillPattern',
+                'mpInlandWaterFillScaleF', 'mpLabelDrawOrder', 'mpLabelFontColor',
+                'mpLabelFontHeightF', 'mpLabelsOn', 'mpLambertMeridianF',
+                'mpLambertParallel1F', 'mpLambertParallel2F', 'mpLandFillColor',
+                'mpLandFillPattern', 'mpLandFillScaleF', 'mpLeftAngleF',
+                'mpLeftCornerLatF', 'mpLeftCornerLonF', 'mpLeftMapPosF',
+                'mpLeftNDCF', 'mpLeftNPCF', 'mpLeftPointLatF',
+                'mpLeftPointLonF', 'mpLeftWindowF', 'mpLimbLineColor',
+                'mpLimbLineDashPattern', 'mpLimbLineDashSegLenF',
+                'mpLimbLineThicknessF', 'mpLimitMode', 'mpMaskAreaSpecifiers',
+                'mpMaskOutlineSpecifiers', 'mpMaxLatF', 'mpMaxLonF',
+                'mpMinLatF', 'mpMinLonF', 'mpMonoFillColor', 'mpMonoFillPattern',
+                'mpMonoFillScale', 'mpNationalLineColor', 'mpNationalLineDashPattern',
+                'mpNationalLineThicknessF', 'mpOceanFillColor', 'mpOceanFillPattern',
+                'mpOceanFillScaleF', 'mpOutlineBoundarySets', 'mpOutlineDrawOrder',
+                'mpOutlineMaskingOn', 'mpOutlineOn', 'mpOutlineSpecifiers',
+                'mpPerimDrawOrder', 'mpPerimLineColor', 'mpPerimLineDashPattern',
+                'mpPerimLineDashSegLenF', 'mpPerimLineThicknessF', 'mpPerimOn',
+                'mpPolyMode', 'mpProjection', 'mpProvincialLineColor',
+                'mpProvincialLineDashPattern', 'mpProvincialLineDashSegLenF',
+                'mpProvincialLineThicknessF', 'mpRelativeCenterLat',
+                'mpRelativeCenterLon', 'mpRightAngleF', 'mpRightCornerLatF',
+                'mpRightCornerLonF', 'mpRightMapPosF', 'mpRightNDCF',
+                'mpRightNPCF', 'mpRightPointLatF', 'mpRightPointLonF',
+                'mpRightWindowF', 'mpSatelliteAngle1F', 'mpSatelliteAngle2F',
+                'mpSatelliteDistF', 'mpShapeMode', 'mpSpecifiedFillColors',
+                'mpSpecifiedFillDirectIndexing', 'mpSpecifiedFillPatterns',
+                'mpSpecifiedFillPriority', 'mpSpecifiedFillScales',
+                'mpTopAngleF', 'mpTopMapPosF', 'mpTopNDCF', 'mpTopNPCF',
+                'mpTopPointLatF', 'mpTopPointLonF', 'mpTopWindowF',
+                'mpUSStateLineColor', 'mpUSStateLineDashPattern',
+                'mpUSStateLineDashSegLenF', 'mpUSStateLineThicknessF',
+                'pmAnnoManagers', 'pmAnnoViews', 'pmLabelBarDisplayMode',
+                'pmLabelBarHeightF', 'pmLabelBarKeepAspect', 'pmLabelBarOrthogonalPosF',
+                'pmLabelBarParallelPosF', 'pmLabelBarSide', 'pmLabelBarWidthF',
+                'pmLabelBarZone', 'pmLegendDisplayMode', 'pmLegendHeightF',
+                'pmLegendKeepAspect', 'pmLegendOrthogonalPosF',
+                'pmLegendParallelPosF', 'pmLegendSide', 'pmLegendWidthF',
+                'pmLegendZone', 'pmOverlaySequenceIds', 'pmTickMarkDisplayMode',
+                'pmTickMarkZone', 'pmTitleDisplayMode', 'pmTitleZone',
+                'prGraphicStyle', 'prPolyType', 'prXArray', 'prYArray',
+                'sfCopyData', 'sfDataArray', 'sfDataMaxV', 'sfDataMinV',
+                'sfElementNodes', 'sfExchangeDimensions', 'sfFirstNodeIndex',
+                'sfMissingValueV', 'sfXArray', 'sfXCActualEndF', 'sfXCActualStartF',
+                'sfXCEndIndex', 'sfXCEndSubsetV', 'sfXCEndV', 'sfXCStartIndex',
+                'sfXCStartSubsetV', 'sfXCStartV', 'sfXCStride', 'sfXCellBounds',
+                'sfYArray', 'sfYCActualEndF', 'sfYCActualStartF', 'sfYCEndIndex',
+                'sfYCEndSubsetV', 'sfYCEndV', 'sfYCStartIndex', 'sfYCStartSubsetV',
+                'sfYCStartV', 'sfYCStride', 'sfYCellBounds', 'stArrowLengthF',
+                'stArrowStride', 'stCrossoverCheckCount',
+                'stExplicitLabelBarLabelsOn', 'stLabelBarEndLabelsOn',
+                'stLabelFormat', 'stLengthCheckCount', 'stLevelColors',
+                'stLevelCount', 'stLevelPalette', 'stLevelSelectionMode',
+                'stLevelSpacingF', 'stLevels', 'stLineColor', 'stLineOpacityF',
+                'stLineStartStride', 'stLineThicknessF', 'stMapDirection',
+                'stMaxLevelCount', 'stMaxLevelValF', 'stMinArrowSpacingF',
+                'stMinDistanceF', 'stMinLevelValF', 'stMinLineSpacingF',
+                'stMinStepFactorF', 'stMonoLineColor', 'stNoDataLabelOn',
+                'stNoDataLabelString', 'stScalarFieldData', 'stScalarMissingValColor',
+                'stSpanLevelPalette', 'stStepSizeF', 'stStreamlineDrawOrder',
+                'stUseScalarArray', 'stVectorFieldData', 'stZeroFLabelAngleF',
+                'stZeroFLabelBackgroundColor', 'stZeroFLabelConstantSpacingF',
+                'stZeroFLabelFont', 'stZeroFLabelFontAspectF',
+                'stZeroFLabelFontColor', 'stZeroFLabelFontHeightF',
+                'stZeroFLabelFontQuality', 'stZeroFLabelFontThicknessF',
+                'stZeroFLabelFuncCode', 'stZeroFLabelJust', 'stZeroFLabelOn',
+                'stZeroFLabelOrthogonalPosF', 'stZeroFLabelParallelPosF',
+                'stZeroFLabelPerimColor', 'stZeroFLabelPerimOn',
+                'stZeroFLabelPerimSpaceF', 'stZeroFLabelPerimThicknessF',
+                'stZeroFLabelSide', 'stZeroFLabelString', 'stZeroFLabelTextDirection',
+                'stZeroFLabelZone', 'tfDoNDCOverlay', 'tfPlotManagerOn',
+                'tfPolyDrawList', 'tfPolyDrawOrder', 'tiDeltaF', 'tiMainAngleF',
+                'tiMainConstantSpacingF', 'tiMainDirection', 'tiMainFont',
+                'tiMainFontAspectF', 'tiMainFontColor', 'tiMainFontHeightF',
+                'tiMainFontQuality', 'tiMainFontThicknessF', 'tiMainFuncCode',
+                'tiMainJust', 'tiMainOffsetXF', 'tiMainOffsetYF', 'tiMainOn',
+                'tiMainPosition', 'tiMainSide', 'tiMainString', 'tiUseMainAttributes',
+                'tiXAxisAngleF', 'tiXAxisConstantSpacingF', 'tiXAxisDirection',
+                'tiXAxisFont', 'tiXAxisFontAspectF', 'tiXAxisFontColor',
+                'tiXAxisFontHeightF', 'tiXAxisFontQuality', 'tiXAxisFontThicknessF',
+                'tiXAxisFuncCode', 'tiXAxisJust', 'tiXAxisOffsetXF',
+                'tiXAxisOffsetYF', 'tiXAxisOn', 'tiXAxisPosition', 'tiXAxisSide',
+                'tiXAxisString', 'tiYAxisAngleF', 'tiYAxisConstantSpacingF',
+                'tiYAxisDirection', 'tiYAxisFont', 'tiYAxisFontAspectF',
+                'tiYAxisFontColor', 'tiYAxisFontHeightF', 'tiYAxisFontQuality',
+                'tiYAxisFontThicknessF', 'tiYAxisFuncCode', 'tiYAxisJust',
+                'tiYAxisOffsetXF', 'tiYAxisOffsetYF', 'tiYAxisOn', 'tiYAxisPosition',
+                'tiYAxisSide', 'tiYAxisString', 'tmBorderLineColor',
+                'tmBorderThicknessF', 'tmEqualizeXYSizes', 'tmLabelAutoStride',
+                'tmSciNoteCutoff', 'tmXBAutoPrecision', 'tmXBBorderOn',
+                'tmXBDataLeftF', 'tmXBDataRightF', 'tmXBFormat', 'tmXBIrrTensionF',
+                'tmXBIrregularPoints', 'tmXBLabelAngleF', 'tmXBLabelConstantSpacingF',
+                'tmXBLabelDeltaF', 'tmXBLabelDirection', 'tmXBLabelFont',
+                'tmXBLabelFontAspectF', 'tmXBLabelFontColor', 'tmXBLabelFontHeightF',
+                'tmXBLabelFontQuality', 'tmXBLabelFontThicknessF',
+                'tmXBLabelFuncCode', 'tmXBLabelJust', 'tmXBLabelStride', 'tmXBLabels',
+                'tmXBLabelsOn', 'tmXBMajorLengthF', 'tmXBMajorLineColor',
+                'tmXBMajorOutwardLengthF', 'tmXBMajorThicknessF', 'tmXBMaxLabelLenF',
+                'tmXBMaxTicks', 'tmXBMinLabelSpacingF', 'tmXBMinorLengthF',
+                'tmXBMinorLineColor', 'tmXBMinorOn', 'tmXBMinorOutwardLengthF',
+                'tmXBMinorPerMajor', 'tmXBMinorThicknessF', 'tmXBMinorValues',
+                'tmXBMode', 'tmXBOn', 'tmXBPrecision', 'tmXBStyle', 'tmXBTickEndF',
+                'tmXBTickSpacingF', 'tmXBTickStartF', 'tmXBValues', 'tmXMajorGrid',
+                'tmXMajorGridLineColor', 'tmXMajorGridLineDashPattern',
+                'tmXMajorGridThicknessF', 'tmXMinorGrid', 'tmXMinorGridLineColor',
+                'tmXMinorGridLineDashPattern', 'tmXMinorGridThicknessF',
+                'tmXTAutoPrecision', 'tmXTBorderOn', 'tmXTDataLeftF',
+                'tmXTDataRightF', 'tmXTFormat', 'tmXTIrrTensionF',
+                'tmXTIrregularPoints', 'tmXTLabelAngleF', 'tmXTLabelConstantSpacingF',
+                'tmXTLabelDeltaF', 'tmXTLabelDirection', 'tmXTLabelFont',
+                'tmXTLabelFontAspectF', 'tmXTLabelFontColor', 'tmXTLabelFontHeightF',
+                'tmXTLabelFontQuality', 'tmXTLabelFontThicknessF',
+                'tmXTLabelFuncCode', 'tmXTLabelJust', 'tmXTLabelStride', 'tmXTLabels',
+                'tmXTLabelsOn', 'tmXTMajorLengthF', 'tmXTMajorLineColor',
+                'tmXTMajorOutwardLengthF', 'tmXTMajorThicknessF', 'tmXTMaxLabelLenF',
+                'tmXTMaxTicks', 'tmXTMinLabelSpacingF', 'tmXTMinorLengthF',
+                'tmXTMinorLineColor', 'tmXTMinorOn', 'tmXTMinorOutwardLengthF',
+                'tmXTMinorPerMajor', 'tmXTMinorThicknessF', 'tmXTMinorValues',
+                'tmXTMode', 'tmXTOn', 'tmXTPrecision', 'tmXTStyle', 'tmXTTickEndF',
+                'tmXTTickSpacingF', 'tmXTTickStartF', 'tmXTValues', 'tmXUseBottom',
+                'tmYLAutoPrecision', 'tmYLBorderOn', 'tmYLDataBottomF',
+                'tmYLDataTopF', 'tmYLFormat', 'tmYLIrrTensionF',
+                'tmYLIrregularPoints', 'tmYLLabelAngleF', 'tmYLLabelConstantSpacingF',
+                'tmYLLabelDeltaF', 'tmYLLabelDirection', 'tmYLLabelFont',
+                'tmYLLabelFontAspectF', 'tmYLLabelFontColor', 'tmYLLabelFontHeightF',
+                'tmYLLabelFontQuality', 'tmYLLabelFontThicknessF',
+                'tmYLLabelFuncCode', 'tmYLLabelJust', 'tmYLLabelStride', 'tmYLLabels',
+                'tmYLLabelsOn', 'tmYLMajorLengthF', 'tmYLMajorLineColor',
+                'tmYLMajorOutwardLengthF', 'tmYLMajorThicknessF', 'tmYLMaxLabelLenF',
+                'tmYLMaxTicks', 'tmYLMinLabelSpacingF', 'tmYLMinorLengthF',
+                'tmYLMinorLineColor', 'tmYLMinorOn', 'tmYLMinorOutwardLengthF',
+                'tmYLMinorPerMajor', 'tmYLMinorThicknessF', 'tmYLMinorValues',
+                'tmYLMode', 'tmYLOn', 'tmYLPrecision', 'tmYLStyle', 'tmYLTickEndF',
+                'tmYLTickSpacingF', 'tmYLTickStartF', 'tmYLValues', 'tmYMajorGrid',
+                'tmYMajorGridLineColor', 'tmYMajorGridLineDashPattern',
+                'tmYMajorGridThicknessF', 'tmYMinorGrid', 'tmYMinorGridLineColor',
+                'tmYMinorGridLineDashPattern', 'tmYMinorGridThicknessF',
+                'tmYRAutoPrecision', 'tmYRBorderOn', 'tmYRDataBottomF',
+                'tmYRDataTopF', 'tmYRFormat', 'tmYRIrrTensionF',
+                'tmYRIrregularPoints', 'tmYRLabelAngleF', 'tmYRLabelConstantSpacingF',
+                'tmYRLabelDeltaF', 'tmYRLabelDirection', 'tmYRLabelFont',
+                'tmYRLabelFontAspectF', 'tmYRLabelFontColor', 'tmYRLabelFontHeightF',
+                'tmYRLabelFontQuality', 'tmYRLabelFontThicknessF',
+                'tmYRLabelFuncCode', 'tmYRLabelJust', 'tmYRLabelStride', 'tmYRLabels',
+                'tmYRLabelsOn', 'tmYRMajorLengthF', 'tmYRMajorLineColor',
+                'tmYRMajorOutwardLengthF', 'tmYRMajorThicknessF', 'tmYRMaxLabelLenF',
+                'tmYRMaxTicks', 'tmYRMinLabelSpacingF', 'tmYRMinorLengthF',
+                'tmYRMinorLineColor', 'tmYRMinorOn', 'tmYRMinorOutwardLengthF',
+                'tmYRMinorPerMajor', 'tmYRMinorThicknessF', 'tmYRMinorValues',
+                'tmYRMode', 'tmYROn', 'tmYRPrecision', 'tmYRStyle', 'tmYRTickEndF',
+                'tmYRTickSpacingF', 'tmYRTickStartF', 'tmYRValues', 'tmYUseLeft',
+                'trGridType', 'trLineInterpolationOn',
+                'trXAxisType', 'trXCoordPoints', 'trXInterPoints', 'trXLog',
+                'trXMaxF', 'trXMinF', 'trXReverse', 'trXSamples', 'trXTensionF',
+                'trYAxisType', 'trYCoordPoints', 'trYInterPoints', 'trYLog',
+                'trYMaxF', 'trYMinF', 'trYReverse', 'trYSamples', 'trYTensionF',
+                'txAngleF', 'txBackgroundFillColor', 'txConstantSpacingF', 'txDirection',
+                'txFont', 'HLU-Fonts', 'txFontAspectF', 'txFontColor',
+                'txFontHeightF', 'txFontOpacityF', 'txFontQuality',
+                'txFontThicknessF', 'txFuncCode', 'txJust', 'txPerimColor',
+                'txPerimDashLengthF', 'txPerimDashPattern', 'txPerimOn',
+                'txPerimSpaceF', 'txPerimThicknessF', 'txPosXF', 'txPosYF',
+                'txString', 'vcExplicitLabelBarLabelsOn', 'vcFillArrowEdgeColor',
+                'vcFillArrowEdgeThicknessF', 'vcFillArrowFillColor',
+                'vcFillArrowHeadInteriorXF', 'vcFillArrowHeadMinFracXF',
+                'vcFillArrowHeadMinFracYF', 'vcFillArrowHeadXF', 'vcFillArrowHeadYF',
+                'vcFillArrowMinFracWidthF', 'vcFillArrowWidthF', 'vcFillArrowsOn',
+                'vcFillOverEdge', 'vcGlyphOpacityF', 'vcGlyphStyle',
+                'vcLabelBarEndLabelsOn', 'vcLabelFontColor', 'vcLabelFontHeightF',
+                'vcLabelsOn', 'vcLabelsUseVectorColor', 'vcLevelColors',
+                'vcLevelCount', 'vcLevelPalette', 'vcLevelSelectionMode',
+                'vcLevelSpacingF', 'vcLevels', 'vcLineArrowColor',
+                'vcLineArrowHeadMaxSizeF', 'vcLineArrowHeadMinSizeF',
+                'vcLineArrowThicknessF', 'vcMagnitudeFormat',
+                'vcMagnitudeScaleFactorF', 'vcMagnitudeScaleValueF',
+                'vcMagnitudeScalingMode', 'vcMapDirection', 'vcMaxLevelCount',
+                'vcMaxLevelValF', 'vcMaxMagnitudeF', 'vcMinAnnoAngleF',
+                'vcMinAnnoArrowAngleF', 'vcMinAnnoArrowEdgeColor',
+                'vcMinAnnoArrowFillColor', 'vcMinAnnoArrowLineColor',
+                'vcMinAnnoArrowMinOffsetF', 'vcMinAnnoArrowSpaceF',
+                'vcMinAnnoArrowUseVecColor', 'vcMinAnnoBackgroundColor',
+                'vcMinAnnoConstantSpacingF', 'vcMinAnnoExplicitMagnitudeF',
+                'vcMinAnnoFont', 'vcMinAnnoFontAspectF', 'vcMinAnnoFontColor',
+                'vcMinAnnoFontHeightF', 'vcMinAnnoFontQuality',
+                'vcMinAnnoFontThicknessF', 'vcMinAnnoFuncCode', 'vcMinAnnoJust',
+                'vcMinAnnoOn', 'vcMinAnnoOrientation', 'vcMinAnnoOrthogonalPosF',
+                'vcMinAnnoParallelPosF', 'vcMinAnnoPerimColor', 'vcMinAnnoPerimOn',
+                'vcMinAnnoPerimSpaceF', 'vcMinAnnoPerimThicknessF', 'vcMinAnnoSide',
+                'vcMinAnnoString1', 'vcMinAnnoString1On', 'vcMinAnnoString2',
+                'vcMinAnnoString2On', 'vcMinAnnoTextDirection', 'vcMinAnnoZone',
+                'vcMinDistanceF', 'vcMinFracLengthF', 'vcMinLevelValF',
+                'vcMinMagnitudeF', 'vcMonoFillArrowEdgeColor',
+                'vcMonoFillArrowFillColor', 'vcMonoLineArrowColor',
+                'vcMonoWindBarbColor', 'vcNoDataLabelOn', 'vcNoDataLabelString',
+                'vcPositionMode', 'vcRefAnnoAngleF', 'vcRefAnnoArrowAngleF',
+                'vcRefAnnoArrowEdgeColor', 'vcRefAnnoArrowFillColor',
+                'vcRefAnnoArrowLineColor', 'vcRefAnnoArrowMinOffsetF',
+                'vcRefAnnoArrowSpaceF', 'vcRefAnnoArrowUseVecColor',
+                'vcRefAnnoBackgroundColor', 'vcRefAnnoConstantSpacingF',
+                'vcRefAnnoExplicitMagnitudeF', 'vcRefAnnoFont',
+                'vcRefAnnoFontAspectF', 'vcRefAnnoFontColor', 'vcRefAnnoFontHeightF',
+                'vcRefAnnoFontQuality', 'vcRefAnnoFontThicknessF',
+                'vcRefAnnoFuncCode', 'vcRefAnnoJust', 'vcRefAnnoOn',
+                'vcRefAnnoOrientation', 'vcRefAnnoOrthogonalPosF',
+                'vcRefAnnoParallelPosF', 'vcRefAnnoPerimColor', 'vcRefAnnoPerimOn',
+                'vcRefAnnoPerimSpaceF', 'vcRefAnnoPerimThicknessF', 'vcRefAnnoSide',
+                'vcRefAnnoString1', 'vcRefAnnoString1On', 'vcRefAnnoString2',
+                'vcRefAnnoString2On', 'vcRefAnnoTextDirection', 'vcRefAnnoZone',
+                'vcRefLengthF', 'vcRefMagnitudeF', 'vcScalarFieldData',
+                'vcScalarMissingValColor', 'vcScalarValueFormat',
+                'vcScalarValueScaleFactorF', 'vcScalarValueScaleValueF',
+                'vcScalarValueScalingMode', 'vcSpanLevelPalette', 'vcUseRefAnnoRes',
+                'vcUseScalarArray', 'vcVectorDrawOrder', 'vcVectorFieldData',
+                'vcWindBarbCalmCircleSizeF', 'vcWindBarbColor',
+                'vcWindBarbLineThicknessF', 'vcWindBarbScaleFactorF',
+                'vcWindBarbTickAngleF', 'vcWindBarbTickLengthF',
+                'vcWindBarbTickSpacingF', 'vcZeroFLabelAngleF',
+                'vcZeroFLabelBackgroundColor', 'vcZeroFLabelConstantSpacingF',
+                'vcZeroFLabelFont', 'vcZeroFLabelFontAspectF',
+                'vcZeroFLabelFontColor', 'vcZeroFLabelFontHeightF',
+                'vcZeroFLabelFontQuality', 'vcZeroFLabelFontThicknessF',
+                'vcZeroFLabelFuncCode', 'vcZeroFLabelJust', 'vcZeroFLabelOn',
+                'vcZeroFLabelOrthogonalPosF', 'vcZeroFLabelParallelPosF',
+                'vcZeroFLabelPerimColor', 'vcZeroFLabelPerimOn',
+                'vcZeroFLabelPerimSpaceF', 'vcZeroFLabelPerimThicknessF',
+                'vcZeroFLabelSide', 'vcZeroFLabelString', 'vcZeroFLabelTextDirection',
+                'vcZeroFLabelZone', 'vfCopyData', 'vfDataArray',
+                'vfExchangeDimensions', 'vfExchangeUVData', 'vfMagMaxV', 'vfMagMinV',
+                'vfMissingUValueV', 'vfMissingVValueV', 'vfPolarData',
+                'vfSingleMissingValue', 'vfUDataArray', 'vfUMaxV', 'vfUMinV',
+                'vfVDataArray', 'vfVMaxV', 'vfVMinV', 'vfXArray', 'vfXCActualEndF',
+                'vfXCActualStartF', 'vfXCEndIndex', 'vfXCEndSubsetV', 'vfXCEndV',
+                'vfXCStartIndex', 'vfXCStartSubsetV', 'vfXCStartV', 'vfXCStride',
+                'vfYArray', 'vfYCActualEndF', 'vfYCActualStartF', 'vfYCEndIndex',
+                'vfYCEndSubsetV', 'vfYCEndV', 'vfYCStartIndex', 'vfYCStartSubsetV',
+                'vfYCStartV', 'vfYCStride', 'vpAnnoManagerId', 'vpClipOn',
+                'vpHeightF', 'vpKeepAspect', 'vpOn', 'vpUseSegments', 'vpWidthF',
+                'vpXF', 'vpYF', 'wkAntiAlias', 'wkBackgroundColor', 'wkBackgroundOpacityF',
+                'wkColorMapLen', 'wkColorMap', 'wkColorModel', 'wkDashTableLength',
+                'wkDefGraphicStyleId', 'wkDeviceLowerX', 'wkDeviceLowerY',
+                'wkDeviceUpperX', 'wkDeviceUpperY', 'wkFileName', 'wkFillTableLength',
+                'wkForegroundColor', 'wkFormat', 'wkFullBackground', 'wkGksWorkId',
+                'wkHeight', 'wkMarkerTableLength', 'wkMetaName', 'wkOrientation',
+                'wkPDFFileName', 'wkPDFFormat', 'wkPDFResolution', 'wkPSFileName',
+                'wkPSFormat', 'wkPSResolution', 'wkPaperHeightF', 'wkPaperSize',
+                'wkPaperWidthF', 'wkPause', 'wkTopLevelViews', 'wkViews',
+                'wkVisualType', 'wkWidth', 'wkWindowId', 'wkXColorMode', 'wsCurrentSize',
+                'wsMaximumSize', 'wsThresholdSize', 'xyComputeXMax',
+                'xyComputeXMin', 'xyComputeYMax', 'xyComputeYMin', 'xyCoordData',
+                'xyCoordDataSpec', 'xyCurveDrawOrder', 'xyDashPattern',
+                'xyDashPatterns', 'xyExplicitLabels', 'xyExplicitLegendLabels',
+                'xyLabelMode', 'xyLineColor', 'xyLineColors', 'xyLineDashSegLenF',
+                'xyLineLabelConstantSpacingF', 'xyLineLabelFont',
+                'xyLineLabelFontAspectF', 'xyLineLabelFontColor',
+                'xyLineLabelFontColors', 'xyLineLabelFontHeightF',
+                'xyLineLabelFontQuality', 'xyLineLabelFontThicknessF',
+                'xyLineLabelFuncCode', 'xyLineThicknessF', 'xyLineThicknesses',
+                'xyMarkLineMode', 'xyMarkLineModes', 'xyMarker', 'xyMarkerColor',
+                'xyMarkerColors', 'xyMarkerSizeF', 'xyMarkerSizes',
+                'xyMarkerThicknessF', 'xyMarkerThicknesses', 'xyMarkers',
+                'xyMonoDashPattern', 'xyMonoLineColor', 'xyMonoLineLabelFontColor',
+                'xyMonoLineThickness', 'xyMonoMarkLineMode', 'xyMonoMarker',
+                'xyMonoMarkerColor', 'xyMonoMarkerSize', 'xyMonoMarkerThickness',
+                'xyXIrrTensionF', 'xyXIrregularPoints', 'xyXStyle', 'xyYIrrTensionF',
+                'xyYIrregularPoints', 'xyYStyle'), prefix=r'\b'),
+             Name.Builtin),
+
+            # Booleans
+            (r'\.(True|False)\.', Name.Builtin),
+            # Comparing Operators
+            (r'\.(eq|ne|lt|le|gt|ge|not|and|or|xor)\.', Operator.Word),
+        ],
+
+        'strings': [
+            (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
+        ],
+
+        'nums': [
+            (r'\d+(?![.e])(_[a-z]\w+)?', Number.Integer),
+            (r'[+-]?\d*\.\d+(e[-+]?\d+)?(_[a-z]\w+)?', Number.Float),
+            (r'[+-]?\d+\.\d*(e[-+]?\d+)?(_[a-z]\w+)?', Number.Float),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/nimrod.py b/.venv/Lib/site-packages/pygments/lexers/nimrod.py
new file mode 100644
index 0000000..365a8dc
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/nimrod.py
@@ -0,0 +1,199 @@
+"""
+    pygments.lexers.nimrod
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for the Nim language (formerly known as Nimrod).
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, default, bygroups
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Error
+
+__all__ = ['NimrodLexer']
+
+
+class NimrodLexer(RegexLexer):
+    """
+    For Nim source code.
+    """
+
+    name = 'Nimrod'
+    url = 'http://nim-lang.org/'
+    aliases = ['nimrod', 'nim']
+    filenames = ['*.nim', '*.nimrod']
+    mimetypes = ['text/x-nim']
+    version_added = '1.5'
+
+    flags = re.MULTILINE | re.IGNORECASE
+
+    def underscorize(words):
+        newWords = []
+        new = []
+        for word in words:
+            for ch in word:
+                new.append(ch)
+                new.append("_?")
+            newWords.append(''.join(new))
+            new = []
+        return "|".join(newWords)
+
+    keywords = [
+        'addr', 'and', 'as', 'asm', 'bind', 'block', 'break', 'case',
+        'cast', 'concept', 'const', 'continue', 'converter', 'defer', 'discard',
+        'distinct', 'div', 'do', 'elif', 'else', 'end', 'enum', 'except',
+        'export', 'finally', 'for', 'if', 'in', 'yield', 'interface',
+        'is', 'isnot', 'iterator', 'let', 'mixin', 'mod',
+        'not', 'notin', 'object', 'of', 'or', 'out', 'ptr', 'raise',
+        'ref', 'return', 'shl', 'shr', 'static', 'try',
+        'tuple', 'type', 'using', 'when', 'while', 'xor'
+    ]
+
+    keywordsPseudo = [
+        'nil', 'true', 'false'
+    ]
+
+    opWords = [
+        'and', 'or', 'not', 'xor', 'shl', 'shr', 'div', 'mod', 'in',
+        'notin', 'is', 'isnot'
+    ]
+
+    types = [
+        'int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64',
+        'bool', 'char', 'range', 'array', 'seq', 'set', 'string'
+    ]
+
+    tokens = {
+        'root': [
+            # Comments
+            (r'##\[', String.Doc, 'doccomment'),
+            (r'##.*$', String.Doc),
+            (r'#\[', Comment.Multiline, 'comment'),
+            (r'#.*$', Comment),
+
+            # Pragmas
+            (r'\{\.', String.Other, 'pragma'),
+
+            # Operators
+            (r'[*=><+\-/@$~&%!?|\\\[\]]', Operator),
+            (r'\.\.|\.|,|\[\.|\.\]|\{\.|\.\}|\(\.|\.\)|\{|\}|\(|\)|:|\^|`|;',
+             Punctuation),
+
+            # Case statement branch
+            (r'(\n\s*)(of)(\s)', bygroups(Text.Whitespace, Keyword,
+                                          Text.Whitespace), 'casebranch'),
+
+            # Strings
+            (r'(?:[\w]+)"', String, 'rdqs'),
+            (r'"""', String.Double, 'tdqs'),
+            ('"', String, 'dqs'),
+
+            # Char
+            ("'", String.Char, 'chars'),
+
+            # Keywords
+            (rf'({underscorize(opWords)})\b', Operator.Word),
+            (r'(proc|func|method|macro|template)(\s)(?![(\[\]])',
+             bygroups(Keyword, Text.Whitespace), 'funcname'),
+            (rf'({underscorize(keywords)})\b', Keyword),
+            (r'({})\b'.format(underscorize(['from', 'import', 'include', 'export'])),
+             Keyword.Namespace),
+            (r'(v_?a_?r)\b', Keyword.Declaration),
+            (rf'({underscorize(types)})\b', Name.Builtin),
+            (rf'({underscorize(keywordsPseudo)})\b', Keyword.Pseudo),
+
+            # Identifiers
+            (r'\b((?![_\d])\w)(((?!_)\w)|(_(?!_)\w))*', Name),
+
+            # Numbers
+            (r'[0-9][0-9_]*(?=([e.]|\'f(32|64)))',
+             Number.Float, ('float-suffix', 'float-number')),
+            (r'0x[a-f0-9][a-f0-9_]*', Number.Hex, 'int-suffix'),
+            (r'0b[01][01_]*', Number.Bin, 'int-suffix'),
+            (r'0o[0-7][0-7_]*', Number.Oct, 'int-suffix'),
+            (r'[0-9][0-9_]*', Number.Integer, 'int-suffix'),
+
+            # Whitespace
+            (r'\s+', Text.Whitespace),
+            (r'.+$', Error),
+        ],
+        'chars': [
+            (r'\\([\\abcefnrtvl"\']|x[a-f0-9]{2}|[0-9]{1,3})', String.Escape),
+            (r"'", String.Char, '#pop'),
+            (r".", String.Char)
+        ],
+        'strings': [
+            (r'(?|>=|>>|>|<=|<<|<|\+|-|=|/|\*|%|\+=|-=|!|@', Operator),
+            (r'\(|\)|\[|\]|,|\.\.\.|\.\.|\.|::|:', Punctuation),
+            (r'`\{[^`]*`\}', Text),  # Extern blocks won't be Lexed by Nit
+            (r'[\r\n\t ]+', Text),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/nix.py b/.venv/Lib/site-packages/pygments/lexers/nix.py
new file mode 100644
index 0000000..3fa88c6
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/nix.py
@@ -0,0 +1,144 @@
+"""
+    pygments.lexers.nix
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the NixOS Nix language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Literal
+
+__all__ = ['NixLexer']
+
+
+class NixLexer(RegexLexer):
+    """
+    For the Nix language.
+    """
+
+    name = 'Nix'
+    url = 'http://nixos.org/nix/'
+    aliases = ['nixos', 'nix']
+    filenames = ['*.nix']
+    mimetypes = ['text/x-nix']
+    version_added = '2.0'
+
+    keywords = ['rec', 'with', 'let', 'in', 'inherit', 'assert', 'if',
+                'else', 'then', '...']
+    builtins = ['import', 'abort', 'baseNameOf', 'dirOf', 'isNull', 'builtins',
+                'map', 'removeAttrs', 'throw', 'toString', 'derivation']
+    operators = ['++', '+', '?', '.', '!', '//', '==', '/',
+                 '!=', '&&', '||', '->', '=', '<', '>', '*', '-']
+
+    punctuations = ["(", ")", "[", "]", ";", "{", "}", ":", ",", "@"]
+
+    tokens = {
+        'root': [
+            # comments starting with #
+            (r'#.*$', Comment.Single),
+
+            # multiline comments
+            (r'/\*', Comment.Multiline, 'comment'),
+
+            # whitespace
+            (r'\s+', Text),
+
+            # keywords
+            ('({})'.format('|'.join(re.escape(entry) + '\\b' for entry in keywords)), Keyword),
+
+            # highlight the builtins
+            ('({})'.format('|'.join(re.escape(entry) + '\\b' for entry in builtins)),
+             Name.Builtin),
+
+            (r'\b(true|false|null)\b', Name.Constant),
+
+            # floats
+            (r'-?(\d+\.\d*|\.\d+)([eE][-+]?\d+)?', Number.Float),
+
+            # integers
+            (r'-?[0-9]+', Number.Integer),
+
+            # paths
+            (r'[\w.+-]*(\/[\w.+-]+)+', Literal),
+            (r'~(\/[\w.+-]+)+', Literal),
+            (r'\<[\w.+-]+(\/[\w.+-]+)*\>', Literal),
+
+            # operators
+            ('({})'.format('|'.join(re.escape(entry) for entry in operators)),
+             Operator),
+
+            # word operators
+            (r'\b(or|and)\b', Operator.Word),
+
+            (r'\{', Punctuation, 'block'),
+
+            # punctuations
+            ('({})'.format('|'.join(re.escape(entry) for entry in punctuations)), Punctuation),
+
+            # strings
+            (r'"', String.Double, 'doublequote'),
+            (r"''", String.Multiline, 'multiline'),
+
+            # urls
+            (r'[a-zA-Z][a-zA-Z0-9\+\-\.]*\:[\w%/?:@&=+$,\\.!~*\'-]+', Literal),
+
+            # names of variables
+            (r'[\w-]+(?=\s*=)', String.Symbol),
+            (r'[a-zA-Z_][\w\'-]*', Text),
+
+            (r"\$\{", String.Interpol, 'antiquote'),
+        ],
+        'comment': [
+            (r'[^/*]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[*/]', Comment.Multiline),
+        ],
+        'multiline': [
+            (r"''(\$|'|\\n|\\r|\\t|\\)", String.Escape),
+            (r"''", String.Multiline, '#pop'),
+            (r'\$\{', String.Interpol, 'antiquote'),
+            (r"[^'\$]+", String.Multiline),
+            (r"\$[^\{']", String.Multiline),
+            (r"'[^']", String.Multiline),
+            (r"\$(?=')", String.Multiline),
+        ],
+        'doublequote': [
+            (r'\\(\\|"|\$|n)', String.Escape),
+            (r'"', String.Double, '#pop'),
+            (r'\$\{', String.Interpol, 'antiquote'),
+            (r'[^"\\\$]+', String.Double),
+            (r'\$[^\{"]', String.Double),
+            (r'\$(?=")', String.Double),
+            (r'\\', String.Double),
+        ],
+        'antiquote': [
+            (r"\}", String.Interpol, '#pop'),
+            # TODO: we should probably escape also here ''${ \${
+            (r"\$\{", String.Interpol, '#push'),
+            include('root'),
+        ],
+        'block': [
+            (r"\}", Punctuation, '#pop'),
+            include('root'),
+        ],
+    }
+
+    def analyse_text(text):
+        rv = 0.0
+        # TODO: let/in
+        if re.search(r'import.+?<[^>]+>', text):
+            rv += 0.4
+        if re.search(r'mkDerivation\s+(\(|\{|rec)', text):
+            rv += 0.4
+        if re.search(r'=\s+mkIf\s+', text):
+            rv += 0.4
+        if re.search(r'\{[a-zA-Z,\s]+\}:', text):
+            rv += 0.1
+        return rv
diff --git a/.venv/Lib/site-packages/pygments/lexers/numbair.py b/.venv/Lib/site-packages/pygments/lexers/numbair.py
new file mode 100644
index 0000000..435863e
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/numbair.py
@@ -0,0 +1,63 @@
+"""
+    pygments.lexers.numbair
+    ~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for other Numba Intermediate Representation.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, include, bygroups, words
+from pygments.token import Whitespace, Name, String,  Punctuation, Keyword, \
+    Operator, Number
+
+__all__ = ["NumbaIRLexer"]
+
+class NumbaIRLexer(RegexLexer):
+    """
+    Lexer for Numba IR
+    """
+    name = 'Numba_IR'
+    url = "https://numba.readthedocs.io/en/stable/developer/architecture.html#stage-2-generate-the-numba-ir"
+    aliases = ['numba_ir', 'numbair']
+    filenames = ['*.numba_ir']
+    mimetypes = ['text/x-numba_ir', 'text/x-numbair']
+    version_added = '2.19'
+
+    identifier = r'\$[a-zA-Z0-9._]+'
+    fun_or_var = r'([a-zA-Z_]+[a-zA-Z0-9]*)'
+
+    tokens = {
+        'root' : [
+            (r'(label)(\ [0-9]+)(:)$',
+                bygroups(Keyword, Name.Label, Punctuation)),
+
+            (r'=', Operator),
+            include('whitespace'),
+            include('keyword'),
+
+            (identifier, Name.Variable),
+            (fun_or_var + r'(\()',
+                bygroups(Name.Function, Punctuation)),
+            (fun_or_var + r'(\=)',
+                bygroups(Name.Attribute, Punctuation)),
+            (fun_or_var, Name.Constant),
+            (r'[0-9]+', Number),
+
+            # 
+            (r'<[^>\n]*>', String),
+
+            (r'[=<>{}\[\]()*.,!\':]|x\b', Punctuation)
+        ],
+
+        'keyword':[
+            (words((
+                'del', 'jump', 'call', 'branch',
+            ), suffix=' '), Keyword),
+        ],
+
+        'whitespace': [
+            (r'(\n|\s)+', Whitespace),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/oberon.py b/.venv/Lib/site-packages/pygments/lexers/oberon.py
new file mode 100644
index 0000000..61f3c2d
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/oberon.py
@@ -0,0 +1,120 @@
+"""
+    pygments.lexers.oberon
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Oberon family languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['ComponentPascalLexer']
+
+
+class ComponentPascalLexer(RegexLexer):
+    """
+    For Component Pascal source code.
+    """
+    name = 'Component Pascal'
+    aliases = ['componentpascal', 'cp']
+    filenames = ['*.cp', '*.cps']
+    mimetypes = ['text/x-component-pascal']
+    url = 'https://blackboxframework.org'
+    version_added = '2.1'
+
+    flags = re.MULTILINE | re.DOTALL
+
+    tokens = {
+        'root': [
+            include('whitespace'),
+            include('comments'),
+            include('punctuation'),
+            include('numliterals'),
+            include('strings'),
+            include('operators'),
+            include('builtins'),
+            include('identifiers'),
+        ],
+        'whitespace': [
+            (r'\n+', Text),  # blank lines
+            (r'\s+', Text),  # whitespace
+        ],
+        'comments': [
+            (r'\(\*([^$].*?)\*\)', Comment.Multiline),
+            # TODO: nested comments (* (* ... *) ... (* ... *) *) not supported!
+        ],
+        'punctuation': [
+            (r'[()\[\]{},.:;|]', Punctuation),
+        ],
+        'numliterals': [
+            (r'[0-9A-F]+X\b', Number.Hex),                 # char code
+            (r'[0-9A-F]+[HL]\b', Number.Hex),              # hexadecimal number
+            (r'[0-9]+\.[0-9]+E[+-][0-9]+', Number.Float),  # real number
+            (r'[0-9]+\.[0-9]+', Number.Float),             # real number
+            (r'[0-9]+', Number.Integer),                   # decimal whole number
+        ],
+        'strings': [
+            (r"'[^\n']*'", String),  # single quoted string
+            (r'"[^\n"]*"', String),  # double quoted string
+        ],
+        'operators': [
+            # Arithmetic Operators
+            (r'[+-]', Operator),
+            (r'[*/]', Operator),
+            # Relational Operators
+            (r'[=#<>]', Operator),
+            # Dereferencing Operator
+            (r'\^', Operator),
+            # Logical AND Operator
+            (r'&', Operator),
+            # Logical NOT Operator
+            (r'~', Operator),
+            # Assignment Symbol
+            (r':=', Operator),
+            # Range Constructor
+            (r'\.\.', Operator),
+            (r'\$', Operator),
+        ],
+        'identifiers': [
+            (r'([a-zA-Z_$][\w$]*)', Name),
+        ],
+        'builtins': [
+            (words((
+                'ANYPTR', 'ANYREC', 'BOOLEAN', 'BYTE', 'CHAR', 'INTEGER', 'LONGINT',
+                'REAL', 'SET', 'SHORTCHAR', 'SHORTINT', 'SHORTREAL'
+                ), suffix=r'\b'), Keyword.Type),
+            (words((
+                'ABS', 'ABSTRACT', 'ARRAY', 'ASH', 'ASSERT', 'BEGIN', 'BITS', 'BY',
+                'CAP', 'CASE', 'CHR', 'CLOSE', 'CONST', 'DEC', 'DIV', 'DO', 'ELSE',
+                'ELSIF', 'EMPTY', 'END', 'ENTIER', 'EXCL', 'EXIT', 'EXTENSIBLE', 'FOR',
+                'HALT', 'IF', 'IMPORT', 'IN', 'INC', 'INCL', 'IS', 'LEN', 'LIMITED',
+                'LONG', 'LOOP', 'MAX', 'MIN', 'MOD', 'MODULE', 'NEW', 'ODD', 'OF',
+                'OR', 'ORD', 'OUT', 'POINTER', 'PROCEDURE', 'RECORD', 'REPEAT', 'RETURN',
+                'SHORT', 'SHORTCHAR', 'SHORTINT', 'SIZE', 'THEN', 'TYPE', 'TO', 'UNTIL',
+                'VAR', 'WHILE', 'WITH'
+                ), suffix=r'\b'), Keyword.Reserved),
+            (r'(TRUE|FALSE|NIL|INF)\b', Keyword.Constant),
+        ]
+    }
+
+    def analyse_text(text):
+        """The only other lexer using .cp is the C++ one, so we check if for
+        a few common Pascal keywords here. Those are unfortunately quite
+        common across various business languages as well."""
+        result = 0
+        if 'BEGIN' in text:
+            result += 0.01
+        if 'END' in text:
+            result += 0.01
+        if 'PROCEDURE' in text:
+            result += 0.01
+        if 'END' in text:
+            result += 0.01
+
+        return result
diff --git a/.venv/Lib/site-packages/pygments/lexers/objective.py b/.venv/Lib/site-packages/pygments/lexers/objective.py
new file mode 100644
index 0000000..899c2c4
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/objective.py
@@ -0,0 +1,513 @@
+"""
+    pygments.lexers.objective
+    ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Objective-C family languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, bygroups, using, this, words, \
+    inherit, default
+from pygments.token import Text, Keyword, Name, String, Operator, \
+    Number, Punctuation, Literal, Comment, Whitespace
+
+from pygments.lexers.c_cpp import CLexer, CppLexer
+
+__all__ = ['ObjectiveCLexer', 'ObjectiveCppLexer', 'LogosLexer', 'SwiftLexer']
+
+
+def objective(baselexer):
+    """
+    Generate a subclass of baselexer that accepts the Objective-C syntax
+    extensions.
+    """
+
+    # Have to be careful not to accidentally match JavaDoc/Doxygen syntax here,
+    # since that's quite common in ordinary C/C++ files.  It's OK to match
+    # JavaDoc/Doxygen keywords that only apply to Objective-C, mind.
+    #
+    # The upshot of this is that we CANNOT match @class or @interface
+    _oc_keywords = re.compile(r'@(?:end|implementation|protocol)')
+
+    # Matches [ ? identifier  ( identifier ? ] |  identifier? : )
+    # (note the identifier is *optional* when there is a ':'!)
+    _oc_message = re.compile(r'\[\s*[a-zA-Z_]\w*\s+'
+                             r'(?:[a-zA-Z_]\w*\s*\]|'
+                             r'(?:[a-zA-Z_]\w*)?:)')
+
+    class GeneratedObjectiveCVariant(baselexer):
+        """
+        Implements Objective-C syntax on top of an existing C family lexer.
+        """
+
+        tokens = {
+            'statements': [
+                (r'@"', String, 'string'),
+                (r'@(YES|NO)', Number),
+                (r"@'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char),
+                (r'@(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[lL]?', Number.Float),
+                (r'@(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
+                (r'@0x[0-9a-fA-F]+[Ll]?', Number.Hex),
+                (r'@0[0-7]+[Ll]?', Number.Oct),
+                (r'@\d+[Ll]?', Number.Integer),
+                (r'@\(', Literal, 'literal_number'),
+                (r'@\[', Literal, 'literal_array'),
+                (r'@\{', Literal, 'literal_dictionary'),
+                (words((
+                    '@selector', '@private', '@protected', '@public', '@encode',
+                    '@synchronized', '@try', '@throw', '@catch', '@finally',
+                    '@end', '@property', '@synthesize', '__bridge', '__bridge_transfer',
+                    '__autoreleasing', '__block', '__weak', '__strong', 'weak', 'strong',
+                    'copy', 'retain', 'assign', 'unsafe_unretained', 'atomic', 'nonatomic',
+                    'readonly', 'readwrite', 'setter', 'getter', 'typeof', 'in',
+                    'out', 'inout', 'release', 'class', '@dynamic', '@optional',
+                    '@required', '@autoreleasepool', '@import'), suffix=r'\b'),
+                 Keyword),
+                (words(('id', 'instancetype', 'Class', 'IMP', 'SEL', 'BOOL',
+                        'IBOutlet', 'IBAction', 'unichar'), suffix=r'\b'),
+                 Keyword.Type),
+                (r'@(true|false|YES|NO)\n', Name.Builtin),
+                (r'(YES|NO|nil|self|super)\b', Name.Builtin),
+                # Carbon types
+                (r'(Boolean|UInt8|SInt8|UInt16|SInt16|UInt32|SInt32)\b', Keyword.Type),
+                # Carbon built-ins
+                (r'(TRUE|FALSE)\b', Name.Builtin),
+                (r'(@interface|@implementation)(\s+)', bygroups(Keyword, Text),
+                 ('#pop', 'oc_classname')),
+                (r'(@class|@protocol)(\s+)', bygroups(Keyword, Text),
+                 ('#pop', 'oc_forward_classname')),
+                # @ can also prefix other expressions like @{...} or @(...)
+                (r'@', Punctuation),
+                inherit,
+            ],
+            'oc_classname': [
+                # interface definition that inherits
+                (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?(\s*)(\{)',
+                 bygroups(Name.Class, Text, Name.Class, Text, Punctuation),
+                 ('#pop', 'oc_ivars')),
+                (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?',
+                 bygroups(Name.Class, Text, Name.Class), '#pop'),
+                # interface definition for a category
+                (r'([a-zA-Z$_][\w$]*)(\s*)(\([a-zA-Z$_][\w$]*\))(\s*)(\{)',
+                 bygroups(Name.Class, Text, Name.Label, Text, Punctuation),
+                 ('#pop', 'oc_ivars')),
+                (r'([a-zA-Z$_][\w$]*)(\s*)(\([a-zA-Z$_][\w$]*\))',
+                 bygroups(Name.Class, Text, Name.Label), '#pop'),
+                # simple interface / implementation
+                (r'([a-zA-Z$_][\w$]*)(\s*)(\{)',
+                 bygroups(Name.Class, Text, Punctuation), ('#pop', 'oc_ivars')),
+                (r'([a-zA-Z$_][\w$]*)', Name.Class, '#pop')
+            ],
+            'oc_forward_classname': [
+                (r'([a-zA-Z$_][\w$]*)(\s*,\s*)',
+                 bygroups(Name.Class, Text), 'oc_forward_classname'),
+                (r'([a-zA-Z$_][\w$]*)(\s*;?)',
+                 bygroups(Name.Class, Text), '#pop')
+            ],
+            'oc_ivars': [
+                include('whitespace'),
+                include('statements'),
+                (';', Punctuation),
+                (r'\{', Punctuation, '#push'),
+                (r'\}', Punctuation, '#pop'),
+            ],
+            'root': [
+                # methods
+                (r'^([-+])(\s*)'                         # method marker
+                 r'(\(.*?\))?(\s*)'                      # return type
+                 r'([a-zA-Z$_][\w$]*:?)',        # begin of method name
+                 bygroups(Punctuation, Text, using(this),
+                          Text, Name.Function),
+                 'method'),
+                inherit,
+            ],
+            'method': [
+                include('whitespace'),
+                # TODO unsure if ellipses are allowed elsewhere, see
+                # discussion in Issue 789
+                (r',', Punctuation),
+                (r'\.\.\.', Punctuation),
+                (r'(\(.*?\))(\s*)([a-zA-Z$_][\w$]*)',
+                 bygroups(using(this), Text, Name.Variable)),
+                (r'[a-zA-Z$_][\w$]*:', Name.Function),
+                (';', Punctuation, '#pop'),
+                (r'\{', Punctuation, 'function'),
+                default('#pop'),
+            ],
+            'literal_number': [
+                (r'\(', Punctuation, 'literal_number_inner'),
+                (r'\)', Literal, '#pop'),
+                include('statement'),
+            ],
+            'literal_number_inner': [
+                (r'\(', Punctuation, '#push'),
+                (r'\)', Punctuation, '#pop'),
+                include('statement'),
+            ],
+            'literal_array': [
+                (r'\[', Punctuation, 'literal_array_inner'),
+                (r'\]', Literal, '#pop'),
+                include('statement'),
+            ],
+            'literal_array_inner': [
+                (r'\[', Punctuation, '#push'),
+                (r'\]', Punctuation, '#pop'),
+                include('statement'),
+            ],
+            'literal_dictionary': [
+                (r'\}', Literal, '#pop'),
+                include('statement'),
+            ],
+        }
+
+        def analyse_text(text):
+            if _oc_keywords.search(text):
+                return 1.0
+            elif '@"' in text:  # strings
+                return 0.8
+            elif re.search('@[0-9]+', text):
+                return 0.7
+            elif _oc_message.search(text):
+                return 0.8
+            return 0
+
+        def get_tokens_unprocessed(self, text, stack=('root',)):
+            from pygments.lexers._cocoa_builtins import COCOA_INTERFACES, \
+                COCOA_PROTOCOLS, COCOA_PRIMITIVES
+
+            for index, token, value in \
+                    baselexer.get_tokens_unprocessed(self, text, stack):
+                if token is Name or token is Name.Class:
+                    if value in COCOA_INTERFACES or value in COCOA_PROTOCOLS \
+                       or value in COCOA_PRIMITIVES:
+                        token = Name.Builtin.Pseudo
+
+                yield index, token, value
+
+    return GeneratedObjectiveCVariant
+
+
+class ObjectiveCLexer(objective(CLexer)):
+    """
+    For Objective-C source code with preprocessor directives.
+    """
+
+    name = 'Objective-C'
+    url = 'https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html'
+    aliases = ['objective-c', 'objectivec', 'obj-c', 'objc']
+    filenames = ['*.m', '*.h']
+    mimetypes = ['text/x-objective-c']
+    version_added = ''
+    priority = 0.05    # Lower than C
+
+
+class ObjectiveCppLexer(objective(CppLexer)):
+    """
+    For Objective-C++ source code with preprocessor directives.
+    """
+
+    name = 'Objective-C++'
+    aliases = ['objective-c++', 'objectivec++', 'obj-c++', 'objc++']
+    filenames = ['*.mm', '*.hh']
+    mimetypes = ['text/x-objective-c++']
+    version_added = ''
+    priority = 0.05    # Lower than C++
+
+
+class LogosLexer(ObjectiveCppLexer):
+    """
+    For Logos + Objective-C source code with preprocessor directives.
+    """
+
+    name = 'Logos'
+    aliases = ['logos']
+    filenames = ['*.x', '*.xi', '*.xm', '*.xmi']
+    mimetypes = ['text/x-logos']
+    version_added = '1.6'
+    priority = 0.25
+
+    tokens = {
+        'statements': [
+            (r'(%orig|%log)\b', Keyword),
+            (r'(%c)\b(\()(\s*)([a-zA-Z$_][\w$]*)(\s*)(\))',
+             bygroups(Keyword, Punctuation, Text, Name.Class, Text, Punctuation)),
+            (r'(%init)\b(\()',
+             bygroups(Keyword, Punctuation), 'logos_init_directive'),
+            (r'(%init)(?=\s*;)', bygroups(Keyword)),
+            (r'(%hook|%group)(\s+)([a-zA-Z$_][\w$]+)',
+             bygroups(Keyword, Text, Name.Class), '#pop'),
+            (r'(%subclass)(\s+)', bygroups(Keyword, Text),
+             ('#pop', 'logos_classname')),
+            inherit,
+        ],
+        'logos_init_directive': [
+            (r'\s+', Text),
+            (',', Punctuation, ('logos_init_directive', '#pop')),
+            (r'([a-zA-Z$_][\w$]*)(\s*)(=)(\s*)([^);]*)',
+             bygroups(Name.Class, Text, Punctuation, Text, Text)),
+            (r'([a-zA-Z$_][\w$]*)', Name.Class),
+            (r'\)', Punctuation, '#pop'),
+        ],
+        'logos_classname': [
+            (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?',
+             bygroups(Name.Class, Text, Name.Class), '#pop'),
+            (r'([a-zA-Z$_][\w$]*)', Name.Class, '#pop')
+        ],
+        'root': [
+            (r'(%subclass)(\s+)', bygroups(Keyword, Text),
+             'logos_classname'),
+            (r'(%hook|%group)(\s+)([a-zA-Z$_][\w$]+)',
+             bygroups(Keyword, Text, Name.Class)),
+            (r'(%config)(\s*\(\s*)(\w+)(\s*=)(.*?)(\)\s*)',
+             bygroups(Keyword, Text, Name.Variable, Text, String, Text)),
+            (r'(%ctor)(\s*)(\{)', bygroups(Keyword, Text, Punctuation),
+             'function'),
+            (r'(%new)(\s*)(\()(.*?)(\))',
+             bygroups(Keyword, Text, Keyword, String, Keyword)),
+            (r'(\s*)(%end)(\s*)', bygroups(Text, Keyword, Text)),
+            inherit,
+        ],
+    }
+
+    _logos_keywords = re.compile(r'%(?:hook|ctor|init|c\()')
+
+    def analyse_text(text):
+        if LogosLexer._logos_keywords.search(text):
+            return 1.0
+        return 0
+
+
+class SwiftLexer(RegexLexer):
+    """
+    For Swift source.
+    """
+    name = 'Swift'
+    url = 'https://www.swift.org/'
+    filenames = ['*.swift']
+    aliases = ['swift']
+    mimetypes = ['text/x-swift']
+    version_added = '2.0'
+
+    tokens = {
+        'root': [
+            # Whitespace and Comments
+            (r'\n', Text),
+            (r'\s+', Whitespace),
+            (r'//', Comment.Single, 'comment-single'),
+            (r'/\*', Comment.Multiline, 'comment-multi'),
+            (r'#(if|elseif|else|endif|available)\b', Comment.Preproc, 'preproc'),
+
+            # Keywords
+            include('keywords'),
+
+            # Global Types
+            (words((
+                'Array', 'AutoreleasingUnsafeMutablePointer', 'BidirectionalReverseView',
+                'Bit', 'Bool', 'CFunctionPointer', 'COpaquePointer', 'CVaListPointer',
+                'Character', 'ClosedInterval', 'CollectionOfOne', 'ContiguousArray',
+                'Dictionary', 'DictionaryGenerator', 'DictionaryIndex', 'Double',
+                'EmptyCollection', 'EmptyGenerator', 'EnumerateGenerator',
+                'EnumerateSequence', 'FilterCollectionView',
+                'FilterCollectionViewIndex', 'FilterGenerator', 'FilterSequenceView',
+                'Float', 'Float80', 'FloatingPointClassification', 'GeneratorOf',
+                'GeneratorOfOne', 'GeneratorSequence', 'HalfOpenInterval', 'HeapBuffer',
+                'HeapBufferStorage', 'ImplicitlyUnwrappedOptional', 'IndexingGenerator',
+                'Int', 'Int16', 'Int32', 'Int64', 'Int8', 'LazyBidirectionalCollection',
+                'LazyForwardCollection', 'LazyRandomAccessCollection',
+                'LazySequence', 'MapCollectionView', 'MapSequenceGenerator',
+                'MapSequenceView', 'MirrorDisposition', 'ObjectIdentifier', 'OnHeap',
+                'Optional', 'PermutationGenerator', 'QuickLookObject',
+                'RandomAccessReverseView', 'Range', 'RangeGenerator', 'RawByte', 'Repeat',
+                'ReverseBidirectionalIndex', 'ReverseRandomAccessIndex', 'SequenceOf',
+                'SinkOf', 'Slice', 'StaticString', 'StrideThrough', 'StrideThroughGenerator',
+                'StrideTo', 'StrideToGenerator', 'String', 'UInt', 'UInt16', 'UInt32',
+                'UInt64', 'UInt8', 'UTF16', 'UTF32', 'UTF8', 'UnicodeDecodingResult',
+                'UnicodeScalar', 'Unmanaged', 'UnsafeBufferPointer',
+                'UnsafeBufferPointerGenerator', 'UnsafeMutableBufferPointer',
+                'UnsafeMutablePointer', 'UnsafePointer', 'Zip2', 'ZipGenerator2',
+                # Protocols
+                'AbsoluteValuable', 'AnyObject', 'ArrayLiteralConvertible',
+                'BidirectionalIndexType', 'BitwiseOperationsType',
+                'BooleanLiteralConvertible', 'BooleanType', 'CVarArgType',
+                'CollectionType', 'Comparable', 'DebugPrintable',
+                'DictionaryLiteralConvertible', 'Equatable',
+                'ExtendedGraphemeClusterLiteralConvertible',
+                'ExtensibleCollectionType', 'FloatLiteralConvertible',
+                'FloatingPointType', 'ForwardIndexType', 'GeneratorType', 'Hashable',
+                'IntegerArithmeticType', 'IntegerLiteralConvertible', 'IntegerType',
+                'IntervalType', 'MirrorType', 'MutableCollectionType', 'MutableSliceable',
+                'NilLiteralConvertible', 'OutputStreamType', 'Printable',
+                'RandomAccessIndexType', 'RangeReplaceableCollectionType',
+                'RawOptionSetType', 'RawRepresentable', 'Reflectable', 'SequenceType',
+                'SignedIntegerType', 'SignedNumberType', 'SinkType', 'Sliceable',
+                'Streamable', 'Strideable', 'StringInterpolationConvertible',
+                'StringLiteralConvertible', 'UnicodeCodecType',
+                'UnicodeScalarLiteralConvertible', 'UnsignedIntegerType',
+                '_ArrayBufferType', '_BidirectionalIndexType', '_CocoaStringType',
+                '_CollectionType', '_Comparable', '_ExtensibleCollectionType',
+                '_ForwardIndexType', '_Incrementable', '_IntegerArithmeticType',
+                '_IntegerType', '_ObjectiveCBridgeable', '_RandomAccessIndexType',
+                '_RawOptionSetType', '_SequenceType', '_Sequence_Type',
+                '_SignedIntegerType', '_SignedNumberType', '_Sliceable', '_Strideable',
+                '_SwiftNSArrayRequiredOverridesType', '_SwiftNSArrayType',
+                '_SwiftNSCopyingType', '_SwiftNSDictionaryRequiredOverridesType',
+                '_SwiftNSDictionaryType', '_SwiftNSEnumeratorType',
+                '_SwiftNSFastEnumerationType', '_SwiftNSStringRequiredOverridesType',
+                '_SwiftNSStringType', '_UnsignedIntegerType',
+                # Variables
+                'C_ARGC', 'C_ARGV', 'Process',
+                # Typealiases
+                'Any', 'AnyClass', 'BooleanLiteralType', 'CBool', 'CChar', 'CChar16',
+                'CChar32', 'CDouble', 'CFloat', 'CInt', 'CLong', 'CLongLong', 'CShort',
+                'CSignedChar', 'CUnsignedInt', 'CUnsignedLong', 'CUnsignedShort',
+                'CWideChar', 'ExtendedGraphemeClusterType', 'Float32', 'Float64',
+                'FloatLiteralType', 'IntMax', 'IntegerLiteralType', 'StringLiteralType',
+                'UIntMax', 'UWord', 'UnicodeScalarType', 'Void', 'Word',
+                # Foundation/Cocoa
+                'NSErrorPointer', 'NSObjectProtocol', 'Selector'), suffix=r'\b'),
+             Name.Builtin),
+            # Functions
+            (words((
+                'abs', 'advance', 'alignof', 'alignofValue', 'assert', 'assertionFailure',
+                'contains', 'count', 'countElements', 'debugPrint', 'debugPrintln',
+                'distance', 'dropFirst', 'dropLast', 'dump', 'enumerate', 'equal',
+                'extend', 'fatalError', 'filter', 'find', 'first', 'getVaList', 'indices',
+                'insert', 'isEmpty', 'join', 'last', 'lazy', 'lexicographicalCompare',
+                'map', 'max', 'maxElement', 'min', 'minElement', 'numericCast', 'overlaps',
+                'partition', 'precondition', 'preconditionFailure', 'prefix', 'print',
+                'println', 'reduce', 'reflect', 'removeAll', 'removeAtIndex', 'removeLast',
+                'removeRange', 'reverse', 'sizeof', 'sizeofValue', 'sort', 'sorted',
+                'splice', 'split', 'startsWith', 'stride', 'strideof', 'strideofValue',
+                'suffix', 'swap', 'toDebugString', 'toString', 'transcode',
+                'underestimateCount', 'unsafeAddressOf', 'unsafeBitCast', 'unsafeDowncast',
+                'withExtendedLifetime', 'withUnsafeMutablePointer',
+                'withUnsafeMutablePointers', 'withUnsafePointer', 'withUnsafePointers',
+                'withVaList'), suffix=r'\b'),
+             Name.Builtin.Pseudo),
+
+            # Implicit Block Variables
+            (r'\$\d+', Name.Variable),
+
+            # Binary Literal
+            (r'0b[01_]+', Number.Bin),
+            # Octal Literal
+            (r'0o[0-7_]+', Number.Oct),
+            # Hexadecimal Literal
+            (r'0x[0-9a-fA-F_]+', Number.Hex),
+            # Decimal Literal
+            (r'[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|'
+             r'\.[0-9_]*|[eE][+\-]?[0-9_]+)', Number.Float),
+            (r'[0-9][0-9_]*', Number.Integer),
+            # String Literal
+            (r'"""', String, 'string-multi'),
+            (r'"', String, 'string'),
+
+            # Operators and Punctuation
+            (r'[(){}\[\].,:;=@#`?]|->|[<&?](?=\w)|(?<=\w)[>!?]', Punctuation),
+            (r'[/=\-+!*%<>&|^?~]+', Operator),
+
+            # Identifier
+            (r'[a-zA-Z_]\w*', Name)
+        ],
+        'keywords': [
+            (words((
+                'as', 'async', 'await', 'break', 'case', 'catch', 'continue', 'default', 'defer',
+                'do', 'else', 'fallthrough', 'for', 'guard', 'if', 'in', 'is',
+                'repeat', 'return', '#selector', 'switch', 'throw', 'try',
+                'where', 'while'), suffix=r'\b'),
+             Keyword),
+            (r'@availability\([^)]+\)', Keyword.Reserved),
+            (words((
+                'associativity', 'convenience', 'dynamic', 'didSet', 'final',
+                'get', 'indirect', 'infix', 'inout', 'lazy', 'left', 'mutating',
+                'none', 'nonmutating', 'optional', 'override', 'postfix',
+                'precedence', 'prefix', 'Protocol', 'required', 'rethrows',
+                'right', 'set', 'throws', 'Type', 'unowned', 'weak', 'willSet',
+                '@availability', '@autoclosure', '@noreturn',
+                '@NSApplicationMain', '@NSCopying', '@NSManaged', '@objc',
+                '@UIApplicationMain', '@IBAction', '@IBDesignable',
+                '@IBInspectable', '@IBOutlet'), suffix=r'\b'),
+             Keyword.Reserved),
+            (r'(as|dynamicType|false|is|nil|self|Self|super|true|__COLUMN__'
+             r'|__FILE__|__FUNCTION__|__LINE__|_'
+             r'|#(?:file|line|column|function))\b', Keyword.Constant),
+            (r'import\b', Keyword.Declaration, 'module'),
+            (r'(class|enum|extension|struct|protocol)(\s+)([a-zA-Z_]\w*)',
+             bygroups(Keyword.Declaration, Whitespace, Name.Class)),
+            (r'(func)(\s+)([a-zA-Z_]\w*)',
+             bygroups(Keyword.Declaration, Whitespace, Name.Function)),
+            (r'(var|let)(\s+)([a-zA-Z_]\w*)', bygroups(Keyword.Declaration,
+             Whitespace, Name.Variable)),
+            (words((
+                'actor', 'associatedtype', 'class', 'deinit', 'enum', 'extension', 'func', 'import',
+                'init', 'internal', 'let', 'operator', 'private', 'protocol', 'public',
+                'static', 'struct', 'subscript', 'typealias', 'var'), suffix=r'\b'),
+             Keyword.Declaration)
+        ],
+        'comment': [
+            (r':param: [a-zA-Z_]\w*|:returns?:|(FIXME|MARK|TODO):',
+             Comment.Special)
+        ],
+
+        # Nested
+        'comment-single': [
+            (r'\n', Whitespace, '#pop'),
+            include('comment'),
+            (r'[^\n]+', Comment.Single)
+        ],
+        'comment-multi': [
+            include('comment'),
+            (r'[^*/]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[*/]+', Comment.Multiline)
+        ],
+        'module': [
+            (r'\n', Whitespace, '#pop'),
+            (r'[a-zA-Z_]\w*', Name.Class),
+            include('root')
+        ],
+        'preproc': [
+            (r'\n', Whitespace, '#pop'),
+            include('keywords'),
+            (r'[A-Za-z]\w*', Comment.Preproc),
+            include('root')
+        ],
+        'string': [
+            (r'"', String, '#pop'),
+            include("string-common"),
+        ],
+        'string-multi': [
+            (r'"""', String, '#pop'),
+            include("string-common"),
+        ],
+        'string-common': [
+            (r'\\\(', String.Interpol, 'string-intp'),
+            (r"""\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}"""
+             r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}""", String.Escape),
+            (r'[^\\"]+', String),
+            (r'\\', String)
+        ],
+        'string-intp': [
+            (r'\(', String.Interpol, '#push'),
+            (r'\)', String.Interpol, '#pop'),
+            include('root')
+        ]
+    }
+
+    def get_tokens_unprocessed(self, text):
+        from pygments.lexers._cocoa_builtins import COCOA_INTERFACES, \
+            COCOA_PROTOCOLS, COCOA_PRIMITIVES
+
+        for index, token, value in \
+                RegexLexer.get_tokens_unprocessed(self, text):
+            if token is Name or token is Name.Class:
+                if value in COCOA_INTERFACES or value in COCOA_PROTOCOLS \
+                   or value in COCOA_PRIMITIVES:
+                    token = Name.Builtin.Pseudo
+
+            yield index, token, value
diff --git a/.venv/Lib/site-packages/pygments/lexers/ooc.py b/.venv/Lib/site-packages/pygments/lexers/ooc.py
new file mode 100644
index 0000000..8a99080
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/ooc.py
@@ -0,0 +1,84 @@
+"""
+    pygments.lexers.ooc
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the Ooc language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['OocLexer']
+
+
+class OocLexer(RegexLexer):
+    """
+    For Ooc source code
+    """
+    name = 'Ooc'
+    url = 'https://ooc-lang.github.io/'
+    aliases = ['ooc']
+    filenames = ['*.ooc']
+    mimetypes = ['text/x-ooc']
+    version_added = '1.2'
+
+    tokens = {
+        'root': [
+            (words((
+                'class', 'interface', 'implement', 'abstract', 'extends', 'from',
+                'this', 'super', 'new', 'const', 'final', 'static', 'import',
+                'use', 'extern', 'inline', 'proto', 'break', 'continue',
+                'fallthrough', 'operator', 'if', 'else', 'for', 'while', 'do',
+                'switch', 'case', 'as', 'in', 'version', 'return', 'true',
+                'false', 'null'), prefix=r'\b', suffix=r'\b'),
+             Keyword),
+            (r'include\b', Keyword, 'include'),
+            (r'(cover)([ \t]+)(from)([ \t]+)(\w+[*@]?)',
+             bygroups(Keyword, Text, Keyword, Text, Name.Class)),
+            (r'(func)((?:[ \t]|\\\n)+)(~[a-z_]\w*)',
+             bygroups(Keyword, Text, Name.Function)),
+            (r'\bfunc\b', Keyword),
+            # Note: %= not listed on https://ooc-lang.github.io/docs/lang/operators/
+            (r'//.*', Comment),
+            (r'(?s)/\*.*?\*/', Comment.Multiline),
+            (r'(==?|\+=?|-[=>]?|\*=?|/=?|:=|!=?|%=?|\?|>{1,3}=?|<{1,3}=?|\.\.|'
+             r'&&?|\|\|?|\^=?)', Operator),
+            (r'(\.)([ \t]*)([a-z]\w*)', bygroups(Operator, Text,
+                                                 Name.Function)),
+            (r'[A-Z][A-Z0-9_]+', Name.Constant),
+            (r'[A-Z]\w*([@*]|\[[ \t]*\])?', Name.Class),
+
+            (r'([a-z]\w*(?:~[a-z]\w*)?)((?:[ \t]|\\\n)*)(?=\()',
+             bygroups(Name.Function, Text)),
+            (r'[a-z]\w*', Name.Variable),
+
+            # : introduces types
+            (r'[:(){}\[\];,]', Punctuation),
+
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'0c[0-9]+', Number.Oct),
+            (r'0b[01]+', Number.Bin),
+            (r'[0-9_]\.[0-9_]*(?!\.)', Number.Float),
+            (r'[0-9_]+', Number.Decimal),
+
+            (r'"(?:\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\"])*"',
+             String.Double),
+            (r"'(?:\\.|\\[0-9]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'",
+             String.Char),
+            (r'@', Punctuation),  # pointer dereference
+            (r'\.', Punctuation),  # imports or chain operator
+
+            (r'\\[ \t\n]', Text),
+            (r'[ \t]+', Text),
+        ],
+        'include': [
+            (r'[\w/]+', Name),
+            (r',', Punctuation),
+            (r'[ \t]', Text),
+            (r'[;\n]', Text, '#pop'),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/openscad.py b/.venv/Lib/site-packages/pygments/lexers/openscad.py
new file mode 100644
index 0000000..b06de22
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/openscad.py
@@ -0,0 +1,96 @@
+"""
+    pygments.lexers.openscad
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the OpenSCAD languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, words, include
+from pygments.token import Text, Comment, Punctuation, Operator, Keyword, Name, Number, Whitespace, Literal, String
+
+__all__ = ['OpenScadLexer']
+
+
+class OpenScadLexer(RegexLexer):
+    """For openSCAD code.
+    """
+    name = "OpenSCAD"
+    url = "https://openscad.org/"
+    aliases = ["openscad"]
+    filenames = ["*.scad"]
+    mimetypes = ["application/x-openscad"]
+    version_added = '2.16'
+
+    tokens = {
+        "root": [
+            (r"[^\S\n]+", Whitespace),
+            (r'//', Comment.Single, 'comment-single'),
+            (r'/\*', Comment.Multiline, 'comment-multi'),
+            (r"[{}\[\]\(\),;:]", Punctuation),
+            (r"[*!#%\-+=?/]", Operator),
+            (r"<=|<|==|!=|>=|>|&&|\|\|", Operator),
+            (r"\$(f[asn]|t|vp[rtd]|children)", Operator),
+            (r"(undef|PI)\b", Keyword.Constant),
+            (
+                r"(use|include)((?:\s|\\\\s)+)",
+                bygroups(Keyword.Namespace, Text),
+                "includes",
+            ),
+            (r"(module)(\s*)([^\s\(]+)",
+             bygroups(Keyword.Namespace, Whitespace, Name.Namespace)),
+            (r"(function)(\s*)([^\s\(]+)",
+             bygroups(Keyword.Declaration, Whitespace, Name.Function)),
+            (words(("true", "false"), prefix=r"\b", suffix=r"\b"), Literal),
+            (words((
+                "function", "module", "include", "use", "for",
+                "intersection_for", "if", "else", "return"
+                ), prefix=r"\b", suffix=r"\b"), Keyword
+            ),
+            (words((
+                "circle", "square", "polygon", "text", "sphere", "cube",
+                "cylinder", "polyhedron", "translate", "rotate", "scale",
+                "resize", "mirror", "multmatrix", "color", "offset", "hull",
+                "minkowski", "union", "difference", "intersection", "abs",
+                "sign", "sin", "cos", "tan", "acos", "asin", "atan", "atan2",
+                "floor", "round", "ceil", "ln", "log", "pow", "sqrt", "exp",
+                "rands", "min", "max", "concat", "lookup", "str", "chr",
+                "search", "version", "version_num", "norm", "cross",
+                "parent_module", "echo", "import", "import_dxf",
+                "dxf_linear_extrude", "linear_extrude", "rotate_extrude",
+                "surface", "projection", "render", "dxf_cross",
+                "dxf_dim", "let", "assign", "len"
+                ), prefix=r"\b", suffix=r"\b"),
+                Name.Builtin
+            ),
+            (r"\bchildren\b", Name.Builtin.Pseudo),
+            (r'""".*?"""', String.Double),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (r"-?\d+(\.\d+)?(e[+-]?\d+)?", Number),
+            (r"\w+", Name),
+        ],
+        "includes": [
+            (
+                r"(<)([^>]*)(>)",
+                bygroups(Punctuation, Comment.PreprocFile, Punctuation),
+            ),
+        ],
+        'comment': [
+            (r':param: [a-zA-Z_]\w*|:returns?:|(FIXME|MARK|TODO):',
+             Comment.Special)
+        ],
+        'comment-single': [
+            (r'\n', Text, '#pop'),
+            include('comment'),
+            (r'[^\n]+', Comment.Single)
+        ],
+        'comment-multi': [
+            include('comment'),
+            (r'[^*/]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[*/]', Comment.Multiline)
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/other.py b/.venv/Lib/site-packages/pygments/lexers/other.py
new file mode 100644
index 0000000..2b7dfb4
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/other.py
@@ -0,0 +1,41 @@
+"""
+    pygments.lexers.other
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Just export lexer classes previously contained in this module.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+# ruff: noqa: F401
+from pygments.lexers.sql import SqlLexer, MySqlLexer, SqliteConsoleLexer
+from pygments.lexers.shell import BashLexer, BashSessionLexer, BatchLexer, \
+    TcshLexer
+from pygments.lexers.robotframework import RobotFrameworkLexer
+from pygments.lexers.testing import GherkinLexer
+from pygments.lexers.esoteric import BrainfuckLexer, BefungeLexer, RedcodeLexer
+from pygments.lexers.prolog import LogtalkLexer
+from pygments.lexers.snobol import SnobolLexer
+from pygments.lexers.rebol import RebolLexer
+from pygments.lexers.configs import KconfigLexer, Cfengine3Lexer
+from pygments.lexers.modeling import ModelicaLexer
+from pygments.lexers.scripting import AppleScriptLexer, MOOCodeLexer, \
+    HybrisLexer
+from pygments.lexers.graphics import PostScriptLexer, GnuplotLexer, \
+    AsymptoteLexer, PovrayLexer
+from pygments.lexers.business import ABAPLexer, OpenEdgeLexer, \
+    GoodDataCLLexer, MaqlLexer
+from pygments.lexers.automation import AutoItLexer, AutohotkeyLexer
+from pygments.lexers.dsls import ProtoBufLexer, BroLexer, PuppetLexer, \
+    MscgenLexer, VGLLexer
+from pygments.lexers.basic import CbmBasicV2Lexer
+from pygments.lexers.pawn import SourcePawnLexer, PawnLexer
+from pygments.lexers.ecl import ECLLexer
+from pygments.lexers.urbi import UrbiscriptLexer
+from pygments.lexers.smalltalk import SmalltalkLexer, NewspeakLexer
+from pygments.lexers.installers import NSISLexer, RPMSpecLexer
+from pygments.lexers.textedit import AwkLexer
+from pygments.lexers.smv import NuSMVLexer
+
+__all__ = []
diff --git a/.venv/Lib/site-packages/pygments/lexers/parasail.py b/.venv/Lib/site-packages/pygments/lexers/parasail.py
new file mode 100644
index 0000000..150d6a9
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/parasail.py
@@ -0,0 +1,78 @@
+"""
+    pygments.lexers.parasail
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for ParaSail.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Literal
+
+__all__ = ['ParaSailLexer']
+
+
+class ParaSailLexer(RegexLexer):
+    """
+    For ParaSail source code.
+    """
+
+    name = 'ParaSail'
+    url = 'http://www.parasail-lang.org'
+    aliases = ['parasail']
+    filenames = ['*.psi', '*.psl']
+    mimetypes = ['text/x-parasail']
+    version_added = '2.1'
+
+    flags = re.MULTILINE
+
+    tokens = {
+        'root': [
+            (r'[^\S\n]+', Text),
+            (r'//.*?\n', Comment.Single),
+            (r'\b(and|or|xor)=', Operator.Word),
+            (r'\b(and(\s+then)?|or(\s+else)?|xor|rem|mod|'
+             r'(is|not)\s+null)\b',
+             Operator.Word),
+            # Keywords
+            (r'\b(abs|abstract|all|block|class|concurrent|const|continue|'
+             r'each|end|exit|extends|exports|forward|func|global|implements|'
+             r'import|in|interface|is|lambda|locked|new|not|null|of|op|'
+             r'optional|private|queued|ref|return|reverse|separate|some|'
+             r'type|until|var|with|'
+             # Control flow
+             r'if|then|else|elsif|case|for|while|loop)\b',
+             Keyword.Reserved),
+            (r'(abstract\s+)?(interface|class|op|func|type)',
+             Keyword.Declaration),
+            # Literals
+            (r'"[^"]*"', String),
+            (r'\\[\'ntrf"0]', String.Escape),
+            (r'#[a-zA-Z]\w*', Literal),       # Enumeration
+            include('numbers'),
+            (r"'[^']'", String.Char),
+            (r'[a-zA-Z]\w*', Name),
+            # Operators and Punctuation
+            (r'(<==|==>|<=>|\*\*=|<\|=|<<=|>>=|==|!=|=\?|<=|>=|'
+             r'\*\*|<<|>>|=>|:=|\+=|-=|\*=|\|=|\||/=|\+|-|\*|/|'
+             r'\.\.|<\.\.|\.\.<|<\.\.<)',
+             Operator),
+            (r'(<|>|\[|\]|\(|\)|\||:|;|,|.|\{|\}|->)',
+             Punctuation),
+            (r'\n+', Text),
+        ],
+        'numbers': [
+            (r'\d[0-9_]*#[0-9a-fA-F][0-9a-fA-F_]*#', Number.Hex),  # any base
+            (r'0[xX][0-9a-fA-F][0-9a-fA-F_]*', Number.Hex),        # C-like hex
+            (r'0[bB][01][01_]*', Number.Bin),                      # C-like bin
+            (r'\d[0-9_]*\.\d[0-9_]*[eE][+-]\d[0-9_]*',             # float exp
+             Number.Float),
+            (r'\d[0-9_]*\.\d[0-9_]*', Number.Float),               # float
+            (r'\d[0-9_]*', Number.Integer),                        # integer
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/parsers.py b/.venv/Lib/site-packages/pygments/lexers/parsers.py
new file mode 100644
index 0000000..7a4ed9d
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/parsers.py
@@ -0,0 +1,798 @@
+"""
+    pygments.lexers.parsers
+    ~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for parser generators.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, DelegatingLexer, \
+    include, bygroups, using
+from pygments.token import Punctuation, Other, Text, Comment, Operator, \
+    Keyword, Name, String, Number, Whitespace
+from pygments.lexers.jvm import JavaLexer
+from pygments.lexers.c_cpp import CLexer, CppLexer
+from pygments.lexers.objective import ObjectiveCLexer
+from pygments.lexers.d import DLexer
+from pygments.lexers.dotnet import CSharpLexer
+from pygments.lexers.ruby import RubyLexer
+from pygments.lexers.python import PythonLexer
+from pygments.lexers.perl import PerlLexer
+
+__all__ = ['RagelLexer', 'RagelEmbeddedLexer', 'RagelCLexer', 'RagelDLexer',
+           'RagelCppLexer', 'RagelObjectiveCLexer', 'RagelRubyLexer',
+           'RagelJavaLexer', 'AntlrLexer', 'AntlrPythonLexer',
+           'AntlrPerlLexer', 'AntlrRubyLexer', 'AntlrCppLexer',
+           'AntlrCSharpLexer', 'AntlrObjectiveCLexer',
+           'AntlrJavaLexer', 'AntlrActionScriptLexer',
+           'TreetopLexer', 'EbnfLexer']
+
+
+class RagelLexer(RegexLexer):
+    """A pure `Ragel `_ lexer.  Use this
+    for fragments of Ragel.  For ``.rl`` files, use
+    :class:`RagelEmbeddedLexer` instead (or one of the
+    language-specific subclasses).
+
+    """
+
+    name = 'Ragel'
+    url = 'http://www.colm.net/open-source/ragel/'
+    aliases = ['ragel']
+    filenames = []
+    version_added = '1.1'
+
+    tokens = {
+        'whitespace': [
+            (r'\s+', Whitespace)
+        ],
+        'comments': [
+            (r'\#.*$', Comment),
+        ],
+        'keywords': [
+            (r'(access|action|alphtype)\b', Keyword),
+            (r'(getkey|write|machine|include)\b', Keyword),
+            (r'(any|ascii|extend|alpha|digit|alnum|lower|upper)\b', Keyword),
+            (r'(xdigit|cntrl|graph|print|punct|space|zlen|empty)\b', Keyword)
+        ],
+        'numbers': [
+            (r'0x[0-9A-Fa-f]+', Number.Hex),
+            (r'[+-]?[0-9]+', Number.Integer),
+        ],
+        'literals': [
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
+            (r'\[(\\\\|\\[^\\]|[^\\\]])*\]', String),          # square bracket literals
+            (r'/(?!\*)(\\\\|\\[^\\]|[^/\\])*/', String.Regex),  # regular expressions
+        ],
+        'identifiers': [
+            (r'[a-zA-Z_]\w*', Name.Variable),
+        ],
+        'operators': [
+            (r',', Operator),                           # Join
+            (r'\||&|--?', Operator),                    # Union, Intersection and Subtraction
+            (r'\.|<:|:>>?', Operator),                  # Concatention
+            (r':', Operator),                           # Label
+            (r'->', Operator),                          # Epsilon Transition
+            (r'(>|\$|%|<|@|<>)(/|eof\b)', Operator),    # EOF Actions
+            (r'(>|\$|%|<|@|<>)(!|err\b)', Operator),    # Global Error Actions
+            (r'(>|\$|%|<|@|<>)(\^|lerr\b)', Operator),  # Local Error Actions
+            (r'(>|\$|%|<|@|<>)(~|to\b)', Operator),     # To-State Actions
+            (r'(>|\$|%|<|@|<>)(\*|from\b)', Operator),  # From-State Actions
+            (r'>|@|\$|%', Operator),                    # Transition Actions and Priorities
+            (r'\*|\?|\+|\{[0-9]*,[0-9]*\}', Operator),  # Repetition
+            (r'!|\^', Operator),                        # Negation
+            (r'\(|\)', Operator),                       # Grouping
+        ],
+        'root': [
+            include('literals'),
+            include('whitespace'),
+            include('comments'),
+            include('keywords'),
+            include('numbers'),
+            include('identifiers'),
+            include('operators'),
+            (r'\{', Punctuation, 'host'),
+            (r'=', Operator),
+            (r';', Punctuation),
+        ],
+        'host': [
+            (r'(' + r'|'.join((  # keep host code in largest possible chunks
+                r'[^{}\'"/#]+',  # exclude unsafe characters
+                r'[^\\]\\[{}]',  # allow escaped { or }
+
+                # strings and comments may safely contain unsafe characters
+                r'"(\\\\|\\[^\\]|[^"\\])*"',
+                r"'(\\\\|\\[^\\]|[^'\\])*'",
+                r'//.*$\n?',            # single line comment
+                r'/\*(.|\n)*?\*/',      # multi-line javadoc-style comment
+                r'\#.*$\n?',            # ruby comment
+
+                # regular expression: There's no reason for it to start
+                # with a * and this stops confusion with comments.
+                r'/(?!\*)(\\\\|\\[^\\]|[^/\\])*/',
+
+                # / is safe now that we've handled regex and javadoc comments
+                r'/',
+            )) + r')+', Other),
+
+            (r'\{', Punctuation, '#push'),
+            (r'\}', Punctuation, '#pop'),
+        ],
+    }
+
+
+class RagelEmbeddedLexer(RegexLexer):
+    """
+    A lexer for Ragel embedded in a host language file.
+
+    This will only highlight Ragel statements. If you want host language
+    highlighting then call the language-specific Ragel lexer.
+    """
+
+    name = 'Embedded Ragel'
+    aliases = ['ragel-em']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    tokens = {
+        'root': [
+            (r'(' + r'|'.join((   # keep host code in largest possible chunks
+                r'[^%\'"/#]+',    # exclude unsafe characters
+                r'%(?=[^%]|$)',   # a single % sign is okay, just not 2 of them
+
+                # strings and comments may safely contain unsafe characters
+                r'"(\\\\|\\[^\\]|[^"\\])*"',
+                r"'(\\\\|\\[^\\]|[^'\\])*'",
+                r'/\*(.|\n)*?\*/',      # multi-line javadoc-style comment
+                r'//.*$\n?',  # single line comment
+                r'\#.*$\n?',  # ruby/ragel comment
+                r'/(?!\*)(\\\\|\\[^\\]|[^/\\])*/',  # regular expression
+
+                # / is safe now that we've handled regex and javadoc comments
+                r'/',
+            )) + r')+', Other),
+
+            # Single Line FSM.
+            # Please don't put a quoted newline in a single line FSM.
+            # That's just mean. It will break this.
+            (r'(%%)(?![{%])(.*)($|;)(\n?)', bygroups(Punctuation,
+                                                     using(RagelLexer),
+                                                     Punctuation, Text)),
+
+            # Multi Line FSM.
+            (r'(%%%%|%%)\{', Punctuation, 'multi-line-fsm'),
+        ],
+        'multi-line-fsm': [
+            (r'(' + r'|'.join((  # keep ragel code in largest possible chunks.
+                r'(' + r'|'.join((
+                    r'[^}\'"\[/#]',   # exclude unsafe characters
+                    r'\}(?=[^%]|$)',   # } is okay as long as it's not followed by %
+                    r'\}%(?=[^%]|$)',  # ...well, one %'s okay, just not two...
+                    r'[^\\]\\[{}]',   # ...and } is okay if it's escaped
+
+                    # allow / if it's preceded with one of these symbols
+                    # (ragel EOF actions)
+                    r'(>|\$|%|<|@|<>)/',
+
+                    # specifically allow regex followed immediately by *
+                    # so it doesn't get mistaken for a comment
+                    r'/(?!\*)(\\\\|\\[^\\]|[^/\\])*/\*',
+
+                    # allow / as long as it's not followed by another / or by a *
+                    r'/(?=[^/*]|$)',
+
+                    # We want to match as many of these as we can in one block.
+                    # Not sure if we need the + sign here,
+                    # does it help performance?
+                )) + r')+',
+
+                # strings and comments may safely contain unsafe characters
+                r'"(\\\\|\\[^\\]|[^"\\])*"',
+                r"'(\\\\|\\[^\\]|[^'\\])*'",
+                r"\[(\\\\|\\[^\\]|[^\]\\])*\]",  # square bracket literal
+                r'/\*(.|\n)*?\*/',          # multi-line javadoc-style comment
+                r'//.*$\n?',                # single line comment
+                r'\#.*$\n?',                # ruby/ragel comment
+            )) + r')+', using(RagelLexer)),
+
+            (r'\}%%', Punctuation, '#pop'),
+        ]
+    }
+
+    def analyse_text(text):
+        return '@LANG: indep' in text
+
+
+class RagelRubyLexer(DelegatingLexer):
+    """
+    A lexer for Ragel in a Ruby host file.
+    """
+
+    name = 'Ragel in Ruby Host'
+    aliases = ['ragel-ruby', 'ragel-rb']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(RubyLexer, RagelEmbeddedLexer, **options)
+
+    def analyse_text(text):
+        return '@LANG: ruby' in text
+
+
+class RagelCLexer(DelegatingLexer):
+    """
+    A lexer for Ragel in a C host file.
+    """
+
+    name = 'Ragel in C Host'
+    aliases = ['ragel-c']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(CLexer, RagelEmbeddedLexer, **options)
+
+    def analyse_text(text):
+        return '@LANG: c' in text
+
+
+class RagelDLexer(DelegatingLexer):
+    """
+    A lexer for Ragel in a D host file.
+    """
+
+    name = 'Ragel in D Host'
+    aliases = ['ragel-d']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(DLexer, RagelEmbeddedLexer, **options)
+
+    def analyse_text(text):
+        return '@LANG: d' in text
+
+
+class RagelCppLexer(DelegatingLexer):
+    """
+    A lexer for Ragel in a C++ host file.
+    """
+
+    name = 'Ragel in CPP Host'
+    aliases = ['ragel-cpp']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(CppLexer, RagelEmbeddedLexer, **options)
+
+    def analyse_text(text):
+        return '@LANG: c++' in text
+
+
+class RagelObjectiveCLexer(DelegatingLexer):
+    """
+    A lexer for Ragel in an Objective C host file.
+    """
+
+    name = 'Ragel in Objective C Host'
+    aliases = ['ragel-objc']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(ObjectiveCLexer, RagelEmbeddedLexer, **options)
+
+    def analyse_text(text):
+        return '@LANG: objc' in text
+
+
+class RagelJavaLexer(DelegatingLexer):
+    """
+    A lexer for Ragel in a Java host file.
+    """
+
+    name = 'Ragel in Java Host'
+    aliases = ['ragel-java']
+    filenames = ['*.rl']
+    url = 'http://www.colm.net/open-source/ragel/'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(JavaLexer, RagelEmbeddedLexer, **options)
+
+    def analyse_text(text):
+        return '@LANG: java' in text
+
+
+class AntlrLexer(RegexLexer):
+    """
+    Generic ANTLR Lexer.
+    Should not be called directly, instead
+    use DelegatingLexer for your target language.
+    """
+
+    name = 'ANTLR'
+    aliases = ['antlr']
+    filenames = []
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    _id = r'[A-Za-z]\w*'
+    _TOKEN_REF = r'[A-Z]\w*'
+    _RULE_REF = r'[a-z]\w*'
+    _STRING_LITERAL = r'\'(?:\\\\|\\\'|[^\']*)\''
+    _INT = r'[0-9]+'
+
+    tokens = {
+        'whitespace': [
+            (r'\s+', Whitespace),
+        ],
+        'comments': [
+            (r'//.*$', Comment),
+            (r'/\*(.|\n)*?\*/', Comment),
+        ],
+        'root': [
+            include('whitespace'),
+            include('comments'),
+
+            (r'(lexer|parser|tree)?(\s*)(grammar\b)(\s*)(' + _id + ')(;)',
+             bygroups(Keyword, Whitespace, Keyword, Whitespace, Name.Class,
+                      Punctuation)),
+            # optionsSpec
+            (r'options\b', Keyword, 'options'),
+            # tokensSpec
+            (r'tokens\b', Keyword, 'tokens'),
+            # attrScope
+            (r'(scope)(\s*)(' + _id + r')(\s*)(\{)',
+             bygroups(Keyword, Whitespace, Name.Variable, Whitespace,
+                      Punctuation), 'action'),
+            # exception
+            (r'(catch|finally)\b', Keyword, 'exception'),
+            # action
+            (r'(@' + _id + r')(\s*)(::)?(\s*)(' + _id + r')(\s*)(\{)',
+             bygroups(Name.Label, Whitespace, Punctuation, Whitespace,
+                      Name.Label, Whitespace, Punctuation), 'action'),
+            # rule
+            (r'((?:protected|private|public|fragment)\b)?(\s*)(' + _id + ')(!)?',
+             bygroups(Keyword, Whitespace, Name.Label, Punctuation),
+             ('rule-alts', 'rule-prelims')),
+        ],
+        'exception': [
+            (r'\n', Whitespace, '#pop'),
+            (r'\s', Whitespace),
+            include('comments'),
+
+            (r'\[', Punctuation, 'nested-arg-action'),
+            (r'\{', Punctuation, 'action'),
+        ],
+        'rule-prelims': [
+            include('whitespace'),
+            include('comments'),
+
+            (r'returns\b', Keyword),
+            (r'\[', Punctuation, 'nested-arg-action'),
+            (r'\{', Punctuation, 'action'),
+            # throwsSpec
+            (r'(throws)(\s+)(' + _id + ')',
+             bygroups(Keyword, Whitespace, Name.Label)),
+            (r'(,)(\s*)(' + _id + ')',
+             bygroups(Punctuation, Whitespace, Name.Label)),  # Additional throws
+            # optionsSpec
+            (r'options\b', Keyword, 'options'),
+            # ruleScopeSpec - scope followed by target language code or name of action
+            # TODO finish implementing other possibilities for scope
+            # L173 ANTLRv3.g from ANTLR book
+            (r'(scope)(\s+)(\{)', bygroups(Keyword, Whitespace, Punctuation),
+             'action'),
+            (r'(scope)(\s+)(' + _id + r')(\s*)(;)',
+             bygroups(Keyword, Whitespace, Name.Label, Whitespace, Punctuation)),
+            # ruleAction
+            (r'(@' + _id + r')(\s*)(\{)',
+             bygroups(Name.Label, Whitespace, Punctuation), 'action'),
+            # finished prelims, go to rule alts!
+            (r':', Punctuation, '#pop')
+        ],
+        'rule-alts': [
+            include('whitespace'),
+            include('comments'),
+
+            # These might need to go in a separate 'block' state triggered by (
+            (r'options\b', Keyword, 'options'),
+            (r':', Punctuation),
+
+            # literals
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
+            (r'<<([^>]|>[^>])>>', String),
+            # identifiers
+            # Tokens start with capital letter.
+            (r'\$?[A-Z_]\w*', Name.Constant),
+            # Rules start with small letter.
+            (r'\$?[a-z_]\w*', Name.Variable),
+            # operators
+            (r'(\+|\||->|=>|=|\(|\)|\.\.|\.|\?|\*|\^|!|\#|~)', Operator),
+            (r',', Punctuation),
+            (r'\[', Punctuation, 'nested-arg-action'),
+            (r'\{', Punctuation, 'action'),
+            (r';', Punctuation, '#pop')
+        ],
+        'tokens': [
+            include('whitespace'),
+            include('comments'),
+            (r'\{', Punctuation),
+            (r'(' + _TOKEN_REF + r')(\s*)(=)?(\s*)(' + _STRING_LITERAL
+             + r')?(\s*)(;)',
+             bygroups(Name.Label, Whitespace, Punctuation, Whitespace,
+                      String, Whitespace, Punctuation)),
+            (r'\}', Punctuation, '#pop'),
+        ],
+        'options': [
+            include('whitespace'),
+            include('comments'),
+            (r'\{', Punctuation),
+            (r'(' + _id + r')(\s*)(=)(\s*)(' +
+             '|'.join((_id, _STRING_LITERAL, _INT, r'\*')) + r')(\s*)(;)',
+             bygroups(Name.Variable, Whitespace, Punctuation, Whitespace,
+                      Text, Whitespace, Punctuation)),
+            (r'\}', Punctuation, '#pop'),
+        ],
+        'action': [
+            (r'(' + r'|'.join((    # keep host code in largest possible chunks
+                r'[^${}\'"/\\]+',  # exclude unsafe characters
+
+                # strings and comments may safely contain unsafe characters
+                r'"(\\\\|\\[^\\]|[^"\\])*"',
+                r"'(\\\\|\\[^\\]|[^'\\])*'",
+                r'//.*$\n?',            # single line comment
+                r'/\*(.|\n)*?\*/',      # multi-line javadoc-style comment
+
+                # regular expression: There's no reason for it to start
+                # with a * and this stops confusion with comments.
+                r'/(?!\*)(\\\\|\\[^\\]|[^/\\])*/',
+
+                # backslashes are okay, as long as we are not backslashing a %
+                r'\\(?!%)',
+
+                # Now that we've handled regex and javadoc comments
+                # it's safe to let / through.
+                r'/',
+            )) + r')+', Other),
+            (r'(\\)(%)', bygroups(Punctuation, Other)),
+            (r'(\$[a-zA-Z]+)(\.?)(text|value)?',
+             bygroups(Name.Variable, Punctuation, Name.Property)),
+            (r'\{', Punctuation, '#push'),
+            (r'\}', Punctuation, '#pop'),
+        ],
+        'nested-arg-action': [
+            (r'(' + r'|'.join((    # keep host code in largest possible chunks.
+                r'[^$\[\]\'"/]+',  # exclude unsafe characters
+
+                # strings and comments may safely contain unsafe characters
+                r'"(\\\\|\\[^\\]|[^"\\])*"',
+                r"'(\\\\|\\[^\\]|[^'\\])*'",
+                r'//.*$\n?',            # single line comment
+                r'/\*(.|\n)*?\*/',      # multi-line javadoc-style comment
+
+                # regular expression: There's no reason for it to start
+                # with a * and this stops confusion with comments.
+                r'/(?!\*)(\\\\|\\[^\\]|[^/\\])*/',
+
+                # Now that we've handled regex and javadoc comments
+                # it's safe to let / through.
+                r'/',
+            )) + r')+', Other),
+
+
+            (r'\[', Punctuation, '#push'),
+            (r'\]', Punctuation, '#pop'),
+            (r'(\$[a-zA-Z]+)(\.?)(text|value)?',
+             bygroups(Name.Variable, Punctuation, Name.Property)),
+            (r'(\\\\|\\\]|\\\[|[^\[\]])+', Other),
+        ]
+    }
+
+    def analyse_text(text):
+        return re.search(r'^\s*grammar\s+[a-zA-Z0-9]+\s*;', text, re.M)
+
+
+# http://www.antlr.org/wiki/display/ANTLR3/Code+Generation+Targets
+
+class AntlrCppLexer(DelegatingLexer):
+    """
+    ANTLR with C++ Target
+    """
+
+    name = 'ANTLR With CPP Target'
+    aliases = ['antlr-cpp']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(CppLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*C\s*;', text, re.M)
+
+
+class AntlrObjectiveCLexer(DelegatingLexer):
+    """
+    ANTLR with Objective-C Target
+    """
+
+    name = 'ANTLR With ObjectiveC Target'
+    aliases = ['antlr-objc']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(ObjectiveCLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*ObjC\s*;', text)
+
+
+class AntlrCSharpLexer(DelegatingLexer):
+    """
+    ANTLR with C# Target
+    """
+
+    name = 'ANTLR With C# Target'
+    aliases = ['antlr-csharp', 'antlr-c#']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(CSharpLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*CSharp2\s*;', text, re.M)
+
+
+class AntlrPythonLexer(DelegatingLexer):
+    """
+    ANTLR with Python Target
+    """
+
+    name = 'ANTLR With Python Target'
+    aliases = ['antlr-python']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(PythonLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*Python\s*;', text, re.M)
+
+
+class AntlrJavaLexer(DelegatingLexer):
+    """
+    ANTLR with Java Target
+    """
+
+    name = 'ANTLR With Java Target'
+    aliases = ['antlr-java']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(JavaLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        # Antlr language is Java by default
+        return AntlrLexer.analyse_text(text) and 0.9
+
+
+class AntlrRubyLexer(DelegatingLexer):
+    """
+    ANTLR with Ruby Target
+    """
+
+    name = 'ANTLR With Ruby Target'
+    aliases = ['antlr-ruby', 'antlr-rb']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(RubyLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*Ruby\s*;', text, re.M)
+
+
+class AntlrPerlLexer(DelegatingLexer):
+    """
+    ANTLR with Perl Target
+    """
+
+    name = 'ANTLR With Perl Target'
+    aliases = ['antlr-perl']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        super().__init__(PerlLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*Perl5\s*;', text, re.M)
+
+
+class AntlrActionScriptLexer(DelegatingLexer):
+    """
+    ANTLR with ActionScript Target
+    """
+
+    name = 'ANTLR With ActionScript Target'
+    aliases = ['antlr-actionscript', 'antlr-as']
+    filenames = ['*.G', '*.g']
+    url = 'https://www.antlr.org'
+    version_added = '1.1'
+
+    def __init__(self, **options):
+        from pygments.lexers.actionscript import ActionScriptLexer
+        super().__init__(ActionScriptLexer, AntlrLexer, **options)
+
+    def analyse_text(text):
+        return AntlrLexer.analyse_text(text) and \
+            re.search(r'^\s*language\s*=\s*ActionScript\s*;', text, re.M)
+
+
+class TreetopBaseLexer(RegexLexer):
+    """
+    A base lexer for `Treetop `_ grammars.
+    Not for direct use; use :class:`TreetopLexer` instead.
+
+    .. versionadded:: 1.6
+    """
+
+    tokens = {
+        'root': [
+            include('space'),
+            (r'require[ \t]+[^\n\r]+[\n\r]', Other),
+            (r'module\b', Keyword.Namespace, 'module'),
+            (r'grammar\b', Keyword, 'grammar'),
+        ],
+        'module': [
+            include('space'),
+            include('end'),
+            (r'module\b', Keyword, '#push'),
+            (r'grammar\b', Keyword, 'grammar'),
+            (r'[A-Z]\w*(?:::[A-Z]\w*)*', Name.Namespace),
+        ],
+        'grammar': [
+            include('space'),
+            include('end'),
+            (r'rule\b', Keyword, 'rule'),
+            (r'include\b', Keyword, 'include'),
+            (r'[A-Z]\w*', Name),
+        ],
+        'include': [
+            include('space'),
+            (r'[A-Z]\w*(?:::[A-Z]\w*)*', Name.Class, '#pop'),
+        ],
+        'rule': [
+            include('space'),
+            include('end'),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
+            (r'([A-Za-z_]\w*)(:)', bygroups(Name.Label, Punctuation)),
+            (r'[A-Za-z_]\w*', Name),
+            (r'[()]', Punctuation),
+            (r'[?+*/&!~]', Operator),
+            (r'\[(?:\\.|\[:\^?[a-z]+:\]|[^\\\]])+\]', String.Regex),
+            (r'([0-9]*)(\.\.)([0-9]*)',
+             bygroups(Number.Integer, Operator, Number.Integer)),
+            (r'(<)([^>]+)(>)', bygroups(Punctuation, Name.Class, Punctuation)),
+            (r'\{', Punctuation, 'inline_module'),
+            (r'\.', String.Regex),
+        ],
+        'inline_module': [
+            (r'\{', Other, 'ruby'),
+            (r'\}', Punctuation, '#pop'),
+            (r'[^{}]+', Other),
+        ],
+        'ruby': [
+            (r'\{', Other, '#push'),
+            (r'\}', Other, '#pop'),
+            (r'[^{}]+', Other),
+        ],
+        'space': [
+            (r'[ \t\n\r]+', Whitespace),
+            (r'#[^\n]*', Comment.Single),
+        ],
+        'end': [
+            (r'end\b', Keyword, '#pop'),
+        ],
+    }
+
+
+class TreetopLexer(DelegatingLexer):
+    """
+    A lexer for Treetop grammars.
+    """
+
+    name = 'Treetop'
+    aliases = ['treetop']
+    filenames = ['*.treetop', '*.tt']
+    url = 'https://cjheath.github.io/treetop'
+    version_added = '1.6'
+
+    def __init__(self, **options):
+        super().__init__(RubyLexer, TreetopBaseLexer, **options)
+
+
+class EbnfLexer(RegexLexer):
+    """
+    Lexer for `ISO/IEC 14977 EBNF
+    `_
+    grammars.
+    """
+
+    name = 'EBNF'
+    aliases = ['ebnf']
+    filenames = ['*.ebnf']
+    mimetypes = ['text/x-ebnf']
+    url = 'https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form'
+    version_added = '2.0'
+
+    tokens = {
+        'root': [
+            include('whitespace'),
+            include('comment_start'),
+            include('identifier'),
+            (r'=', Operator, 'production'),
+        ],
+        'production': [
+            include('whitespace'),
+            include('comment_start'),
+            include('identifier'),
+            (r'"[^"]*"', String.Double),
+            (r"'[^']*'", String.Single),
+            (r'(\?[^?]*\?)', Name.Entity),
+            (r'[\[\]{}(),|]', Punctuation),
+            (r'-', Operator),
+            (r';', Punctuation, '#pop'),
+            (r'\.', Punctuation, '#pop'),
+        ],
+        'whitespace': [
+            (r'\s+', Text),
+        ],
+        'comment_start': [
+            (r'\(\*', Comment.Multiline, 'comment'),
+        ],
+        'comment': [
+            (r'[^*)]', Comment.Multiline),
+            include('comment_start'),
+            (r'\*\)', Comment.Multiline, '#pop'),
+            (r'[*)]', Comment.Multiline),
+        ],
+        'identifier': [
+            (r'([a-zA-Z][\w \-]*)', Keyword),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/pascal.py b/.venv/Lib/site-packages/pygments/lexers/pascal.py
new file mode 100644
index 0000000..5f40dcc
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/pascal.py
@@ -0,0 +1,644 @@
+"""
+    pygments.lexers.pascal
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Pascal family languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import Lexer
+from pygments.util import get_bool_opt, get_list_opt
+from pygments.token import Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Error, Whitespace
+from pygments.scanner import Scanner
+
+# compatibility import
+from pygments.lexers.modula2 import Modula2Lexer # noqa: F401
+
+__all__ = ['DelphiLexer', 'PortugolLexer']
+
+
+class PortugolLexer(Lexer):
+    """For Portugol, a Pascal dialect with keywords in Portuguese."""
+    name = 'Portugol'
+    aliases = ['portugol']
+    filenames = ['*.alg', '*.portugol']
+    mimetypes = []
+    url = "https://www.apoioinformatica.inf.br/produtos/visualg/linguagem"
+    version_added = ''
+
+    def __init__(self, **options):
+        Lexer.__init__(self, **options)
+        self.lexer = DelphiLexer(**options, portugol=True)
+
+    def get_tokens_unprocessed(self, text):
+        return self.lexer.get_tokens_unprocessed(text)
+
+
+class DelphiLexer(Lexer):
+    """
+    For Delphi (Borland Object Pascal),
+    Turbo Pascal and Free Pascal source code.
+
+    Additional options accepted:
+
+    `turbopascal`
+        Highlight Turbo Pascal specific keywords (default: ``True``).
+    `delphi`
+        Highlight Borland Delphi specific keywords (default: ``True``).
+    `freepascal`
+        Highlight Free Pascal specific keywords (default: ``True``).
+    `units`
+        A list of units that should be considered builtin, supported are
+        ``System``, ``SysUtils``, ``Classes`` and ``Math``.
+        Default is to consider all of them builtin.
+    """
+    name = 'Delphi'
+    aliases = ['delphi', 'pas', 'pascal', 'objectpascal']
+    filenames = ['*.pas', '*.dpr']
+    mimetypes = ['text/x-pascal']
+    url = 'https://www.embarcadero.com/products/delphi'
+    version_added = ''
+
+    TURBO_PASCAL_KEYWORDS = (
+        'absolute', 'and', 'array', 'asm', 'begin', 'break', 'case',
+        'const', 'constructor', 'continue', 'destructor', 'div', 'do',
+        'downto', 'else', 'end', 'file', 'for', 'function', 'goto',
+        'if', 'implementation', 'in', 'inherited', 'inline', 'interface',
+        'label', 'mod', 'nil', 'not', 'object', 'of', 'on', 'operator',
+        'or', 'packed', 'procedure', 'program', 'record', 'reintroduce',
+        'repeat', 'self', 'set', 'shl', 'shr', 'string', 'then', 'to',
+        'type', 'unit', 'until', 'uses', 'var', 'while', 'with', 'xor'
+    )
+
+    DELPHI_KEYWORDS = (
+        'as', 'class', 'except', 'exports', 'finalization', 'finally',
+        'initialization', 'is', 'library', 'on', 'property', 'raise',
+        'threadvar', 'try'
+    )
+
+    FREE_PASCAL_KEYWORDS = (
+        'dispose', 'exit', 'false', 'new', 'true'
+    )
+
+    BLOCK_KEYWORDS = {
+        'begin', 'class', 'const', 'constructor', 'destructor', 'end',
+        'finalization', 'function', 'implementation', 'initialization',
+        'label', 'library', 'operator', 'procedure', 'program', 'property',
+        'record', 'threadvar', 'type', 'unit', 'uses', 'var'
+    }
+
+    FUNCTION_MODIFIERS = {
+        'alias', 'cdecl', 'export', 'inline', 'interrupt', 'nostackframe',
+        'pascal', 'register', 'safecall', 'softfloat', 'stdcall',
+        'varargs', 'name', 'dynamic', 'near', 'virtual', 'external',
+        'override', 'assembler'
+    }
+
+    # XXX: those aren't global. but currently we know no way for defining
+    #      them just for the type context.
+    DIRECTIVES = {
+        'absolute', 'abstract', 'assembler', 'cppdecl', 'default', 'far',
+        'far16', 'forward', 'index', 'oldfpccall', 'private', 'protected',
+        'published', 'public'
+    }
+
+    BUILTIN_TYPES = {
+        'ansichar', 'ansistring', 'bool', 'boolean', 'byte', 'bytebool',
+        'cardinal', 'char', 'comp', 'currency', 'double', 'dword',
+        'extended', 'int64', 'integer', 'iunknown', 'longbool', 'longint',
+        'longword', 'pansichar', 'pansistring', 'pbool', 'pboolean',
+        'pbyte', 'pbytearray', 'pcardinal', 'pchar', 'pcomp', 'pcurrency',
+        'pdate', 'pdatetime', 'pdouble', 'pdword', 'pextended', 'phandle',
+        'pint64', 'pinteger', 'plongint', 'plongword', 'pointer',
+        'ppointer', 'pshortint', 'pshortstring', 'psingle', 'psmallint',
+        'pstring', 'pvariant', 'pwidechar', 'pwidestring', 'pword',
+        'pwordarray', 'pwordbool', 'real', 'real48', 'shortint',
+        'shortstring', 'single', 'smallint', 'string', 'tclass', 'tdate',
+        'tdatetime', 'textfile', 'thandle', 'tobject', 'ttime', 'variant',
+        'widechar', 'widestring', 'word', 'wordbool'
+    }
+
+    BUILTIN_UNITS = {
+        'System': (
+            'abs', 'acquireexceptionobject', 'addr', 'ansitoutf8',
+            'append', 'arctan', 'assert', 'assigned', 'assignfile',
+            'beginthread', 'blockread', 'blockwrite', 'break', 'chdir',
+            'chr', 'close', 'closefile', 'comptocurrency', 'comptodouble',
+            'concat', 'continue', 'copy', 'cos', 'dec', 'delete',
+            'dispose', 'doubletocomp', 'endthread', 'enummodules',
+            'enumresourcemodules', 'eof', 'eoln', 'erase', 'exceptaddr',
+            'exceptobject', 'exclude', 'exit', 'exp', 'filepos', 'filesize',
+            'fillchar', 'finalize', 'findclasshinstance', 'findhinstance',
+            'findresourcehinstance', 'flush', 'frac', 'freemem',
+            'get8087cw', 'getdir', 'getlasterror', 'getmem',
+            'getmemorymanager', 'getmodulefilename', 'getvariantmanager',
+            'halt', 'hi', 'high', 'inc', 'include', 'initialize', 'insert',
+            'int', 'ioresult', 'ismemorymanagerset', 'isvariantmanagerset',
+            'length', 'ln', 'lo', 'low', 'mkdir', 'move', 'new', 'odd',
+            'olestrtostring', 'olestrtostrvar', 'ord', 'paramcount',
+            'paramstr', 'pi', 'pos', 'pred', 'ptr', 'pucs4chars', 'random',
+            'randomize', 'read', 'readln', 'reallocmem',
+            'releaseexceptionobject', 'rename', 'reset', 'rewrite', 'rmdir',
+            'round', 'runerror', 'seek', 'seekeof', 'seekeoln',
+            'set8087cw', 'setlength', 'setlinebreakstyle',
+            'setmemorymanager', 'setstring', 'settextbuf',
+            'setvariantmanager', 'sin', 'sizeof', 'slice', 'sqr', 'sqrt',
+            'str', 'stringofchar', 'stringtoolestr', 'stringtowidechar',
+            'succ', 'swap', 'trunc', 'truncate', 'typeinfo',
+            'ucs4stringtowidestring', 'unicodetoutf8', 'uniquestring',
+            'upcase', 'utf8decode', 'utf8encode', 'utf8toansi',
+            'utf8tounicode', 'val', 'vararrayredim', 'varclear',
+            'widecharlentostring', 'widecharlentostrvar',
+            'widechartostring', 'widechartostrvar',
+            'widestringtoucs4string', 'write', 'writeln'
+        ),
+        'SysUtils': (
+            'abort', 'addexitproc', 'addterminateproc', 'adjustlinebreaks',
+            'allocmem', 'ansicomparefilename', 'ansicomparestr',
+            'ansicomparetext', 'ansidequotedstr', 'ansiextractquotedstr',
+            'ansilastchar', 'ansilowercase', 'ansilowercasefilename',
+            'ansipos', 'ansiquotedstr', 'ansisamestr', 'ansisametext',
+            'ansistrcomp', 'ansistricomp', 'ansistrlastchar', 'ansistrlcomp',
+            'ansistrlicomp', 'ansistrlower', 'ansistrpos', 'ansistrrscan',
+            'ansistrscan', 'ansistrupper', 'ansiuppercase',
+            'ansiuppercasefilename', 'appendstr', 'assignstr', 'beep',
+            'booltostr', 'bytetocharindex', 'bytetocharlen', 'bytetype',
+            'callterminateprocs', 'changefileext', 'charlength',
+            'chartobyteindex', 'chartobytelen', 'comparemem', 'comparestr',
+            'comparetext', 'createdir', 'createguid', 'currentyear',
+            'currtostr', 'currtostrf', 'date', 'datetimetofiledate',
+            'datetimetostr', 'datetimetostring', 'datetimetosystemtime',
+            'datetimetotimestamp', 'datetostr', 'dayofweek', 'decodedate',
+            'decodedatefully', 'decodetime', 'deletefile', 'directoryexists',
+            'diskfree', 'disksize', 'disposestr', 'encodedate', 'encodetime',
+            'exceptionerrormessage', 'excludetrailingbackslash',
+            'excludetrailingpathdelimiter', 'expandfilename',
+            'expandfilenamecase', 'expanduncfilename', 'extractfiledir',
+            'extractfiledrive', 'extractfileext', 'extractfilename',
+            'extractfilepath', 'extractrelativepath', 'extractshortpathname',
+            'fileage', 'fileclose', 'filecreate', 'filedatetodatetime',
+            'fileexists', 'filegetattr', 'filegetdate', 'fileisreadonly',
+            'fileopen', 'fileread', 'filesearch', 'fileseek', 'filesetattr',
+            'filesetdate', 'filesetreadonly', 'filewrite', 'finalizepackage',
+            'findclose', 'findcmdlineswitch', 'findfirst', 'findnext',
+            'floattocurr', 'floattodatetime', 'floattodecimal', 'floattostr',
+            'floattostrf', 'floattotext', 'floattotextfmt', 'fmtloadstr',
+            'fmtstr', 'forcedirectories', 'format', 'formatbuf', 'formatcurr',
+            'formatdatetime', 'formatfloat', 'freeandnil', 'getcurrentdir',
+            'getenvironmentvariable', 'getfileversion', 'getformatsettings',
+            'getlocaleformatsettings', 'getmodulename', 'getpackagedescription',
+            'getpackageinfo', 'gettime', 'guidtostring', 'incamonth',
+            'includetrailingbackslash', 'includetrailingpathdelimiter',
+            'incmonth', 'initializepackage', 'interlockeddecrement',
+            'interlockedexchange', 'interlockedexchangeadd',
+            'interlockedincrement', 'inttohex', 'inttostr', 'isdelimiter',
+            'isequalguid', 'isleapyear', 'ispathdelimiter', 'isvalidident',
+            'languages', 'lastdelimiter', 'loadpackage', 'loadstr',
+            'lowercase', 'msecstotimestamp', 'newstr', 'nextcharindex', 'now',
+            'outofmemoryerror', 'quotedstr', 'raiselastoserror',
+            'raiselastwin32error', 'removedir', 'renamefile', 'replacedate',
+            'replacetime', 'safeloadlibrary', 'samefilename', 'sametext',
+            'setcurrentdir', 'showexception', 'sleep', 'stralloc', 'strbufsize',
+            'strbytetype', 'strcat', 'strcharlength', 'strcomp', 'strcopy',
+            'strdispose', 'strecopy', 'strend', 'strfmt', 'stricomp',
+            'stringreplace', 'stringtoguid', 'strlcat', 'strlcomp', 'strlcopy',
+            'strlen', 'strlfmt', 'strlicomp', 'strlower', 'strmove', 'strnew',
+            'strnextchar', 'strpas', 'strpcopy', 'strplcopy', 'strpos',
+            'strrscan', 'strscan', 'strtobool', 'strtobooldef', 'strtocurr',
+            'strtocurrdef', 'strtodate', 'strtodatedef', 'strtodatetime',
+            'strtodatetimedef', 'strtofloat', 'strtofloatdef', 'strtoint',
+            'strtoint64', 'strtoint64def', 'strtointdef', 'strtotime',
+            'strtotimedef', 'strupper', 'supports', 'syserrormessage',
+            'systemtimetodatetime', 'texttofloat', 'time', 'timestamptodatetime',
+            'timestamptomsecs', 'timetostr', 'trim', 'trimleft', 'trimright',
+            'tryencodedate', 'tryencodetime', 'tryfloattocurr', 'tryfloattodatetime',
+            'trystrtobool', 'trystrtocurr', 'trystrtodate', 'trystrtodatetime',
+            'trystrtofloat', 'trystrtoint', 'trystrtoint64', 'trystrtotime',
+            'unloadpackage', 'uppercase', 'widecomparestr', 'widecomparetext',
+            'widefmtstr', 'wideformat', 'wideformatbuf', 'widelowercase',
+            'widesamestr', 'widesametext', 'wideuppercase', 'win32check',
+            'wraptext'
+        ),
+        'Classes': (
+            'activateclassgroup', 'allocatehwnd', 'bintohex', 'checksynchronize',
+            'collectionsequal', 'countgenerations', 'deallocatehwnd', 'equalrect',
+            'extractstrings', 'findclass', 'findglobalcomponent', 'getclass',
+            'groupdescendantswith', 'hextobin', 'identtoint',
+            'initinheritedcomponent', 'inttoident', 'invalidpoint',
+            'isuniqueglobalcomponentname', 'linestart', 'objectbinarytotext',
+            'objectresourcetotext', 'objecttexttobinary', 'objecttexttoresource',
+            'pointsequal', 'readcomponentres', 'readcomponentresex',
+            'readcomponentresfile', 'rect', 'registerclass', 'registerclassalias',
+            'registerclasses', 'registercomponents', 'registerintegerconsts',
+            'registernoicon', 'registernonactivex', 'smallpoint', 'startclassgroup',
+            'teststreamformat', 'unregisterclass', 'unregisterclasses',
+            'unregisterintegerconsts', 'unregistermoduleclasses',
+            'writecomponentresfile'
+        ),
+        'Math': (
+            'arccos', 'arccosh', 'arccot', 'arccoth', 'arccsc', 'arccsch', 'arcsec',
+            'arcsech', 'arcsin', 'arcsinh', 'arctan2', 'arctanh', 'ceil',
+            'comparevalue', 'cosecant', 'cosh', 'cot', 'cotan', 'coth', 'csc',
+            'csch', 'cycletodeg', 'cycletograd', 'cycletorad', 'degtocycle',
+            'degtograd', 'degtorad', 'divmod', 'doubledecliningbalance',
+            'ensurerange', 'floor', 'frexp', 'futurevalue', 'getexceptionmask',
+            'getprecisionmode', 'getroundmode', 'gradtocycle', 'gradtodeg',
+            'gradtorad', 'hypot', 'inrange', 'interestpayment', 'interestrate',
+            'internalrateofreturn', 'intpower', 'isinfinite', 'isnan', 'iszero',
+            'ldexp', 'lnxp1', 'log10', 'log2', 'logn', 'max', 'maxintvalue',
+            'maxvalue', 'mean', 'meanandstddev', 'min', 'minintvalue', 'minvalue',
+            'momentskewkurtosis', 'netpresentvalue', 'norm', 'numberofperiods',
+            'payment', 'periodpayment', 'poly', 'popnstddev', 'popnvariance',
+            'power', 'presentvalue', 'radtocycle', 'radtodeg', 'radtograd',
+            'randg', 'randomrange', 'roundto', 'samevalue', 'sec', 'secant',
+            'sech', 'setexceptionmask', 'setprecisionmode', 'setroundmode',
+            'sign', 'simpleroundto', 'sincos', 'sinh', 'slndepreciation', 'stddev',
+            'sum', 'sumint', 'sumofsquares', 'sumsandsquares', 'syddepreciation',
+            'tan', 'tanh', 'totalvariance', 'variance'
+        )
+    }
+
+    ASM_REGISTERS = {
+        'ah', 'al', 'ax', 'bh', 'bl', 'bp', 'bx', 'ch', 'cl', 'cr0',
+        'cr1', 'cr2', 'cr3', 'cr4', 'cs', 'cx', 'dh', 'di', 'dl', 'dr0',
+        'dr1', 'dr2', 'dr3', 'dr4', 'dr5', 'dr6', 'dr7', 'ds', 'dx',
+        'eax', 'ebp', 'ebx', 'ecx', 'edi', 'edx', 'es', 'esi', 'esp',
+        'fs', 'gs', 'mm0', 'mm1', 'mm2', 'mm3', 'mm4', 'mm5', 'mm6',
+        'mm7', 'si', 'sp', 'ss', 'st0', 'st1', 'st2', 'st3', 'st4', 'st5',
+        'st6', 'st7', 'xmm0', 'xmm1', 'xmm2', 'xmm3', 'xmm4', 'xmm5',
+        'xmm6', 'xmm7'
+    }
+
+    ASM_INSTRUCTIONS = {
+        'aaa', 'aad', 'aam', 'aas', 'adc', 'add', 'and', 'arpl', 'bound',
+        'bsf', 'bsr', 'bswap', 'bt', 'btc', 'btr', 'bts', 'call', 'cbw',
+        'cdq', 'clc', 'cld', 'cli', 'clts', 'cmc', 'cmova', 'cmovae',
+        'cmovb', 'cmovbe', 'cmovc', 'cmovcxz', 'cmove', 'cmovg',
+        'cmovge', 'cmovl', 'cmovle', 'cmovna', 'cmovnae', 'cmovnb',
+        'cmovnbe', 'cmovnc', 'cmovne', 'cmovng', 'cmovnge', 'cmovnl',
+        'cmovnle', 'cmovno', 'cmovnp', 'cmovns', 'cmovnz', 'cmovo',
+        'cmovp', 'cmovpe', 'cmovpo', 'cmovs', 'cmovz', 'cmp', 'cmpsb',
+        'cmpsd', 'cmpsw', 'cmpxchg', 'cmpxchg486', 'cmpxchg8b', 'cpuid',
+        'cwd', 'cwde', 'daa', 'das', 'dec', 'div', 'emms', 'enter', 'hlt',
+        'ibts', 'icebp', 'idiv', 'imul', 'in', 'inc', 'insb', 'insd',
+        'insw', 'int', 'int01', 'int03', 'int1', 'int3', 'into', 'invd',
+        'invlpg', 'iret', 'iretd', 'iretw', 'ja', 'jae', 'jb', 'jbe',
+        'jc', 'jcxz', 'jcxz', 'je', 'jecxz', 'jg', 'jge', 'jl', 'jle',
+        'jmp', 'jna', 'jnae', 'jnb', 'jnbe', 'jnc', 'jne', 'jng', 'jnge',
+        'jnl', 'jnle', 'jno', 'jnp', 'jns', 'jnz', 'jo', 'jp', 'jpe',
+        'jpo', 'js', 'jz', 'lahf', 'lar', 'lcall', 'lds', 'lea', 'leave',
+        'les', 'lfs', 'lgdt', 'lgs', 'lidt', 'ljmp', 'lldt', 'lmsw',
+        'loadall', 'loadall286', 'lock', 'lodsb', 'lodsd', 'lodsw',
+        'loop', 'loope', 'loopne', 'loopnz', 'loopz', 'lsl', 'lss', 'ltr',
+        'mov', 'movd', 'movq', 'movsb', 'movsd', 'movsw', 'movsx',
+        'movzx', 'mul', 'neg', 'nop', 'not', 'or', 'out', 'outsb', 'outsd',
+        'outsw', 'pop', 'popa', 'popad', 'popaw', 'popf', 'popfd', 'popfw',
+        'push', 'pusha', 'pushad', 'pushaw', 'pushf', 'pushfd', 'pushfw',
+        'rcl', 'rcr', 'rdmsr', 'rdpmc', 'rdshr', 'rdtsc', 'rep', 'repe',
+        'repne', 'repnz', 'repz', 'ret', 'retf', 'retn', 'rol', 'ror',
+        'rsdc', 'rsldt', 'rsm', 'sahf', 'sal', 'salc', 'sar', 'sbb',
+        'scasb', 'scasd', 'scasw', 'seta', 'setae', 'setb', 'setbe',
+        'setc', 'setcxz', 'sete', 'setg', 'setge', 'setl', 'setle',
+        'setna', 'setnae', 'setnb', 'setnbe', 'setnc', 'setne', 'setng',
+        'setnge', 'setnl', 'setnle', 'setno', 'setnp', 'setns', 'setnz',
+        'seto', 'setp', 'setpe', 'setpo', 'sets', 'setz', 'sgdt', 'shl',
+        'shld', 'shr', 'shrd', 'sidt', 'sldt', 'smi', 'smint', 'smintold',
+        'smsw', 'stc', 'std', 'sti', 'stosb', 'stosd', 'stosw', 'str',
+        'sub', 'svdc', 'svldt', 'svts', 'syscall', 'sysenter', 'sysexit',
+        'sysret', 'test', 'ud1', 'ud2', 'umov', 'verr', 'verw', 'wait',
+        'wbinvd', 'wrmsr', 'wrshr', 'xadd', 'xbts', 'xchg', 'xlat',
+        'xlatb', 'xor'
+    }
+
+    PORTUGOL_KEYWORDS = (
+        'aleatorio',
+        'algoritmo',
+        'arquivo',
+        'ate',
+        'caso',
+        'cronometro',
+        'debug',
+        'e',
+        'eco',
+        'enquanto',
+        'entao',
+        'escolha',
+        'escreva',
+        'escreval',
+        'faca',
+        'falso',
+        'fimalgoritmo',
+        'fimenquanto',
+        'fimescolha',
+        'fimfuncao',
+        'fimpara',
+        'fimprocedimento',
+        'fimrepita',
+        'fimse',
+        'funcao',
+        'inicio',
+        'int',
+        'interrompa',
+        'leia',
+        'limpatela',
+        'mod',
+        'nao',
+        'ou',
+        'outrocaso',
+        'para',
+        'passo',
+        'pausa',
+        'procedimento',
+        'repita',
+        'retorne',
+        'se',
+        'senao',
+        'timer',
+        'var',
+        'vetor',
+        'verdadeiro',
+        'xou',
+        'div',
+        'mod',
+        'abs',
+        'arccos',
+        'arcsen',
+        'arctan',
+        'cos',
+        'cotan',
+        'Exp',
+        'grauprad',
+        'int',
+        'log',
+        'logn',
+        'pi',
+        'quad',
+        'radpgrau',
+        'raizq',
+        'rand',
+        'randi',
+        'sen',
+        'Tan',
+        'asc',
+        'carac',
+        'caracpnum',
+        'compr',
+        'copia',
+        'maiusc',
+        'minusc',
+        'numpcarac',
+        'pos',
+    )
+
+    PORTUGOL_BUILTIN_TYPES = {
+        'inteiro', 'real', 'caractere', 'logico'
+    }
+
+    def __init__(self, **options):
+        Lexer.__init__(self, **options)
+        self.keywords = set()
+        self.builtins = set()
+        if get_bool_opt(options, 'portugol', False):
+            self.keywords.update(self.PORTUGOL_KEYWORDS)
+            self.builtins.update(self.PORTUGOL_BUILTIN_TYPES)
+            self.is_portugol = True
+        else:
+            self.is_portugol = False
+
+            if get_bool_opt(options, 'turbopascal', True):
+                self.keywords.update(self.TURBO_PASCAL_KEYWORDS)
+            if get_bool_opt(options, 'delphi', True):
+                self.keywords.update(self.DELPHI_KEYWORDS)
+            if get_bool_opt(options, 'freepascal', True):
+                self.keywords.update(self.FREE_PASCAL_KEYWORDS)
+            for unit in get_list_opt(options, 'units', list(self.BUILTIN_UNITS)):
+                self.builtins.update(self.BUILTIN_UNITS[unit])
+
+    def get_tokens_unprocessed(self, text):
+        scanner = Scanner(text, re.DOTALL | re.MULTILINE | re.IGNORECASE)
+        stack = ['initial']
+        in_function_block = False
+        in_property_block = False
+        was_dot = False
+        next_token_is_function = False
+        next_token_is_property = False
+        collect_labels = False
+        block_labels = set()
+        brace_balance = [0, 0]
+
+        while not scanner.eos:
+            token = Error
+
+            if stack[-1] == 'initial':
+                if scanner.scan(r'\s+'):
+                    token = Whitespace
+                elif not self.is_portugol and scanner.scan(r'\{.*?\}|\(\*.*?\*\)'):
+                    if scanner.match.startswith('$'):
+                        token = Comment.Preproc
+                    else:
+                        token = Comment.Multiline
+                elif scanner.scan(r'//.*?$'):
+                    token = Comment.Single
+                elif self.is_portugol and scanner.scan(r'(<\-)|(>=)|(<=)|%|<|>|-|\+|\*|\=|(<>)|\/|\.|:|,'):
+                    token = Operator
+                elif not self.is_portugol and scanner.scan(r'[-+*\/=<>:;,.@\^]'):
+                    token = Operator
+                    # stop label highlighting on next ";"
+                    if collect_labels and scanner.match == ';':
+                        collect_labels = False
+                elif scanner.scan(r'[\(\)\[\]]+'):
+                    token = Punctuation
+                    # abort function naming ``foo = Function(...)``
+                    next_token_is_function = False
+                    # if we are in a function block we count the open
+                    # braces because ootherwise it's impossible to
+                    # determine the end of the modifier context
+                    if in_function_block or in_property_block:
+                        if scanner.match == '(':
+                            brace_balance[0] += 1
+                        elif scanner.match == ')':
+                            brace_balance[0] -= 1
+                        elif scanner.match == '[':
+                            brace_balance[1] += 1
+                        elif scanner.match == ']':
+                            brace_balance[1] -= 1
+                elif scanner.scan(r'[A-Za-z_][A-Za-z_0-9]*'):
+                    lowercase_name = scanner.match.lower()
+                    if lowercase_name == 'result':
+                        token = Name.Builtin.Pseudo
+                    elif lowercase_name in self.keywords:
+                        token = Keyword
+                        # if we are in a special block and a
+                        # block ending keyword occurs (and the parenthesis
+                        # is balanced) we end the current block context
+                        if self.is_portugol:
+                            if lowercase_name in ('funcao', 'procedimento'):
+                                in_function_block = True
+                                next_token_is_function = True
+                        else:
+                            if (in_function_block or in_property_block) and \
+                                    lowercase_name in self.BLOCK_KEYWORDS and \
+                                    brace_balance[0] <= 0 and \
+                                    brace_balance[1] <= 0:
+                                in_function_block = False
+                                in_property_block = False
+                                brace_balance = [0, 0]
+                                block_labels = set()
+                            if lowercase_name in ('label', 'goto'):
+                                collect_labels = True
+                            elif lowercase_name == 'asm':
+                                stack.append('asm')
+                            elif lowercase_name == 'property':
+                                in_property_block = True
+                                next_token_is_property = True
+                            elif lowercase_name in ('procedure', 'operator',
+                                                    'function', 'constructor',
+                                                    'destructor'):
+                                in_function_block = True
+                                next_token_is_function = True
+                    # we are in a function block and the current name
+                    # is in the set of registered modifiers. highlight
+                    # it as pseudo keyword
+                    elif not self.is_portugol and in_function_block and \
+                            lowercase_name in self.FUNCTION_MODIFIERS:
+                        token = Keyword.Pseudo
+                    # if we are in a property highlight some more
+                    # modifiers
+                    elif not self.is_portugol and in_property_block and \
+                            lowercase_name in ('read', 'write'):
+                        token = Keyword.Pseudo
+                        next_token_is_function = True
+                    # if the last iteration set next_token_is_function
+                    # to true we now want this name highlighted as
+                    # function. so do that and reset the state
+                    elif next_token_is_function:
+                        # Look if the next token is a dot. If yes it's
+                        # not a function, but a class name and the
+                        # part after the dot a function name
+                        if not self.is_portugol and scanner.test(r'\s*\.\s*'):
+                            token = Name.Class
+                        # it's not a dot, our job is done
+                        else:
+                            token = Name.Function
+                            next_token_is_function = False
+
+                            if self.is_portugol:
+                                block_labels.add(scanner.match.lower())
+
+                    # same for properties
+                    elif not self.is_portugol and next_token_is_property:
+                        token = Name.Property
+                        next_token_is_property = False
+                    # Highlight this token as label and add it
+                    # to the list of known labels
+                    elif not self.is_portugol and collect_labels:
+                        token = Name.Label
+                        block_labels.add(scanner.match.lower())
+                    # name is in list of known labels
+                    elif lowercase_name in block_labels:
+                        token = Name.Label
+                    elif self.is_portugol and lowercase_name in self.PORTUGOL_BUILTIN_TYPES:
+                        token = Keyword.Type
+                    elif not self.is_portugol and lowercase_name in self.BUILTIN_TYPES:
+                        token = Keyword.Type
+                    elif not self.is_portugol and lowercase_name in self.DIRECTIVES:
+                        token = Keyword.Pseudo
+                    # builtins are just builtins if the token
+                    # before isn't a dot
+                    elif not self.is_portugol and not was_dot and lowercase_name in self.builtins:
+                        token = Name.Builtin
+                    else:
+                        token = Name
+                elif self.is_portugol and scanner.scan(r"\""):
+                    token = String
+                    stack.append('string')
+                elif not self.is_portugol and scanner.scan(r"'"):
+                    token = String
+                    stack.append('string')
+                elif not self.is_portugol and scanner.scan(r'\#(\d+|\$[0-9A-Fa-f]+)'):
+                    token = String.Char
+                elif not self.is_portugol and scanner.scan(r'\$[0-9A-Fa-f]+'):
+                    token = Number.Hex
+                elif scanner.scan(r'\d+(?![eE]|\.[^.])'):
+                    token = Number.Integer
+                elif scanner.scan(r'\d+(\.\d+([eE][+-]?\d+)?|[eE][+-]?\d+)'):
+                    token = Number.Float
+                else:
+                    # if the stack depth is deeper than once, pop
+                    if len(stack) > 1:
+                        stack.pop()
+                    scanner.get_char()
+
+            elif stack[-1] == 'string':
+                if self.is_portugol:
+                    if scanner.scan(r"''"):
+                        token = String.Escape
+                    elif scanner.scan(r"\""):
+                        token = String
+                        stack.pop()
+                    elif scanner.scan(r"[^\"]*"):
+                        token = String
+                    else:
+                        scanner.get_char()
+                        stack.pop()
+                else:
+                    if scanner.scan(r"''"):
+                        token = String.Escape
+                    elif scanner.scan(r"'"):
+                        token = String
+                        stack.pop()
+                    elif scanner.scan(r"[^']*"):
+                        token = String
+                    else:
+                        scanner.get_char()
+                        stack.pop()
+            elif not self.is_portugol and stack[-1] == 'asm':
+                if scanner.scan(r'\s+'):
+                    token = Whitespace
+                elif scanner.scan(r'end'):
+                    token = Keyword
+                    stack.pop()
+                elif scanner.scan(r'\{.*?\}|\(\*.*?\*\)'):
+                    if scanner.match.startswith('$'):
+                        token = Comment.Preproc
+                    else:
+                        token = Comment.Multiline
+                elif scanner.scan(r'//.*?$'):
+                    token = Comment.Single
+                elif scanner.scan(r"'"):
+                    token = String
+                    stack.append('string')
+                elif scanner.scan(r'@@[A-Za-z_][A-Za-z_0-9]*'):
+                    token = Name.Label
+                elif scanner.scan(r'[A-Za-z_][A-Za-z_0-9]*'):
+                    lowercase_name = scanner.match.lower()
+                    if lowercase_name in self.ASM_INSTRUCTIONS:
+                        token = Keyword
+                    elif lowercase_name in self.ASM_REGISTERS:
+                        token = Name.Builtin
+                    else:
+                        token = Name
+                elif scanner.scan(r'[-+*\/=<>:;,.@\^]+'):
+                    token = Operator
+                elif scanner.scan(r'[\(\)\[\]]+'):
+                    token = Punctuation
+                elif scanner.scan(r'\$[0-9A-Fa-f]+'):
+                    token = Number.Hex
+                elif scanner.scan(r'\d+(?![eE]|\.[^.])'):
+                    token = Number.Integer
+                elif scanner.scan(r'\d+(\.\d+([eE][+-]?\d+)?|[eE][+-]?\d+)'):
+                    token = Number.Float
+                else:
+                    scanner.get_char()
+                    stack.pop()
+
+            # save the dot!!!11
+            if not self.is_portugol and scanner.match.strip():
+                was_dot = scanner.match == '.'
+
+            yield scanner.start_pos, token, scanner.match or ''
diff --git a/.venv/Lib/site-packages/pygments/lexers/pawn.py b/.venv/Lib/site-packages/pygments/lexers/pawn.py
new file mode 100644
index 0000000..99d9c96
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/pawn.py
@@ -0,0 +1,202 @@
+"""
+    pygments.lexers.pawn
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the Pawn languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+from pygments.util import get_bool_opt
+
+__all__ = ['SourcePawnLexer', 'PawnLexer']
+
+
+class SourcePawnLexer(RegexLexer):
+    """
+    For SourcePawn source code with preprocessor directives.
+    """
+    name = 'SourcePawn'
+    aliases = ['sp']
+    filenames = ['*.sp']
+    mimetypes = ['text/x-sourcepawn']
+    url = 'https://github.com/alliedmodders/sourcepawn'
+    version_added = '1.6'
+
+    #: optional Comment or Whitespace
+    _ws = r'(?:\s|//.*?\n|/\*.*?\*/)+'
+    #: only one /* */ style comment
+    _ws1 = r'\s*(?:/[*].*?[*]/\s*)*'
+
+    tokens = {
+        'root': [
+            # preprocessor directives: without whitespace
+            (r'^#if\s+0', Comment.Preproc, 'if0'),
+            ('^#', Comment.Preproc, 'macro'),
+            # or with whitespace
+            ('^' + _ws1 + r'#if\s+0', Comment.Preproc, 'if0'),
+            ('^' + _ws1 + '#', Comment.Preproc, 'macro'),
+            (r'\n', Text),
+            (r'\s+', Text),
+            (r'\\\n', Text),  # line continuation
+            (r'/(\\\n)?/(\n|(.|\n)*?[^\\]\n)', Comment.Single),
+            (r'/(\\\n)?\*(.|\n)*?\*(\\\n)?/', Comment.Multiline),
+            (r'[{}]', Punctuation),
+            (r'L?"', String, 'string'),
+            (r"L?'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char),
+            (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[LlUu]*', Number.Float),
+            (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
+            (r'0x[0-9a-fA-F]+[LlUu]*', Number.Hex),
+            (r'0[0-7]+[LlUu]*', Number.Oct),
+            (r'\d+[LlUu]*', Number.Integer),
+            (r'[~!%^&*+=|?:<>/-]', Operator),
+            (r'[()\[\],.;]', Punctuation),
+            (r'(case|const|continue|native|'
+             r'default|else|enum|for|if|new|operator|'
+             r'public|return|sizeof|static|decl|struct|switch)\b', Keyword),
+            (r'(bool|Float)\b', Keyword.Type),
+            (r'(true|false)\b', Keyword.Constant),
+            (r'[a-zA-Z_]\w*', Name),
+        ],
+        'string': [
+            (r'"', String, '#pop'),
+            (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape),
+            (r'[^\\"\n]+', String),  # all other characters
+            (r'\\\n', String),       # line continuation
+            (r'\\', String),         # stray backslash
+        ],
+        'macro': [
+            (r'[^/\n]+', Comment.Preproc),
+            (r'/\*(.|\n)*?\*/', Comment.Multiline),
+            (r'//.*?\n', Comment.Single, '#pop'),
+            (r'/', Comment.Preproc),
+            (r'(?<=\\)\n', Comment.Preproc),
+            (r'\n', Comment.Preproc, '#pop'),
+        ],
+        'if0': [
+            (r'^\s*#if.*?(?/-]', Operator),
+            (r'[()\[\],.;]', Punctuation),
+            (r'(switch|case|default|const|new|static|char|continue|break|'
+             r'if|else|for|while|do|operator|enum|'
+             r'public|return|sizeof|tagof|state|goto)\b', Keyword),
+            (r'(bool|Float)\b', Keyword.Type),
+            (r'(true|false)\b', Keyword.Constant),
+            (r'[a-zA-Z_]\w*', Name),
+        ],
+        'string': [
+            (r'"', String, '#pop'),
+            (r'\\([\\abfnrtv"\']|x[a-fA-F0-9]{2,4}|[0-7]{1,3})', String.Escape),
+            (r'[^\\"\n]+', String),  # all other characters
+            (r'\\\n', String),       # line continuation
+            (r'\\', String),         # stray backslash
+        ],
+        'macro': [
+            (r'[^/\n]+', Comment.Preproc),
+            (r'/\*(.|\n)*?\*/', Comment.Multiline),
+            (r'//.*?\n', Comment.Single, '#pop'),
+            (r'/', Comment.Preproc),
+            (r'(?<=\\)\n', Comment.Preproc),
+            (r'\n', Comment.Preproc, '#pop'),
+        ],
+        'if0': [
+            (r'^\s*#if.*?(?<-]', Operator),
+            (r'[a-zA-Z][a-zA-Z0-9_-]*', Name),
+            (r'\?[a-zA-Z][a-zA-Z0-9_-]*', Name.Variable),
+            (r'[0-9]+\.[0-9]+', Number.Float),
+            (r'[0-9]+', Number.Integer),
+        ],
+        'keywords': [
+            (words((
+                ':requirements', ':types', ':constants',
+                ':predicates', ':functions', ':action', ':agent',
+                ':parameters', ':precondition', ':effect',
+                ':durative-action', ':duration', ':condition',
+                ':derived', ':domain', ':objects', ':init',
+                ':goal', ':metric', ':length', ':serial', ':parallel',
+                # the following are requirements
+                ':strips', ':typing', ':negative-preconditions',
+                ':disjunctive-preconditions', ':equality',
+                ':existential-preconditions', ':universal-preconditions',
+                ':conditional-effects', ':fluents', ':numeric-fluents',
+                ':object-fluents', ':adl', ':durative-actions',
+                ':continuous-effects', ':derived-predicates',
+                ':time-intial-literals', ':preferences',
+                ':constraints', ':action-costs', ':multi-agent',
+                ':unfactored-privacy', ':factored-privacy',
+                ':non-deterministic'
+                ), suffix=r'\b'), Keyword)
+        ],
+        'builtins': [
+            (words((
+                'define', 'domain', 'object', 'either', 'and',
+                'forall', 'preference', 'imply', 'or', 'exists',
+                'not', 'when', 'assign', 'scale-up', 'scale-down',
+                'increase', 'decrease', 'at', 'over', 'start',
+                'end', 'all', 'problem', 'always', 'sometime',
+                'within', 'at-most-once', 'sometime-after',
+                'sometime-before', 'always-within', 'hold-during',
+                'hold-after', 'minimize', 'maximize',
+                'total-time', 'is-violated'), suffix=r'\b'),
+                Name.Builtin)
+        ]
+    }
+
diff --git a/.venv/Lib/site-packages/pygments/lexers/perl.py b/.venv/Lib/site-packages/pygments/lexers/perl.py
new file mode 100644
index 0000000..33f91f5
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/perl.py
@@ -0,0 +1,733 @@
+"""
+    pygments.lexers.perl
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Perl, Raku and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, ExtendedRegexLexer, include, bygroups, \
+    using, this, default, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Whitespace
+from pygments.util import shebang_matches
+
+__all__ = ['PerlLexer', 'Perl6Lexer']
+
+
+class PerlLexer(RegexLexer):
+    """
+    For Perl source code.
+    """
+
+    name = 'Perl'
+    url = 'https://www.perl.org'
+    aliases = ['perl', 'pl']
+    filenames = ['*.pl', '*.pm', '*.t', '*.perl']
+    mimetypes = ['text/x-perl', 'application/x-perl']
+    version_added = ''
+
+    flags = re.DOTALL | re.MULTILINE
+    # TODO: give this to a perl guy who knows how to parse perl...
+    tokens = {
+        'balanced-regex': [
+            (r'/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*', String.Regex, '#pop'),
+            (r'!(\\\\|\\[^\\]|[^\\!])*![egimosx]*', String.Regex, '#pop'),
+            (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
+            (r'\{(\\\\|\\[^\\]|[^\\}])*\}[egimosx]*', String.Regex, '#pop'),
+            (r'<(\\\\|\\[^\\]|[^\\>])*>[egimosx]*', String.Regex, '#pop'),
+            (r'\[(\\\\|\\[^\\]|[^\\\]])*\][egimosx]*', String.Regex, '#pop'),
+            (r'\((\\\\|\\[^\\]|[^\\)])*\)[egimosx]*', String.Regex, '#pop'),
+            (r'@(\\\\|\\[^\\]|[^\\@])*@[egimosx]*', String.Regex, '#pop'),
+            (r'%(\\\\|\\[^\\]|[^\\%])*%[egimosx]*', String.Regex, '#pop'),
+            (r'\$(\\\\|\\[^\\]|[^\\$])*\$[egimosx]*', String.Regex, '#pop'),
+        ],
+        'root': [
+            (r'\A\#!.+?$', Comment.Hashbang),
+            (r'\#.*?$', Comment.Single),
+            (r'^=[a-zA-Z0-9]+\s+.*?\n=cut', Comment.Multiline),
+            (words((
+                'case', 'continue', 'do', 'else', 'elsif', 'for', 'foreach',
+                'if', 'last', 'my', 'next', 'our', 'redo', 'reset', 'then',
+                'unless', 'until', 'while', 'print', 'new', 'BEGIN',
+                'CHECK', 'INIT', 'END', 'return'), suffix=r'\b'),
+             Keyword),
+            (r'(format)(\s+)(\w+)(\s*)(=)(\s*\n)',
+             bygroups(Keyword, Whitespace, Name, Whitespace, Punctuation, Whitespace), 'format'),
+            (r'(eq|lt|gt|le|ge|ne|not|and|or|cmp)\b', Operator.Word),
+            # common delimiters
+            (r's/(\\\\|\\[^\\]|[^\\/])*/(\\\\|\\[^\\]|[^\\/])*/[egimosx]*',
+                String.Regex),
+            (r's!(\\\\|\\!|[^!])*!(\\\\|\\!|[^!])*![egimosx]*', String.Regex),
+            (r's\\(\\\\|[^\\])*\\(\\\\|[^\\])*\\[egimosx]*', String.Regex),
+            (r's@(\\\\|\\[^\\]|[^\\@])*@(\\\\|\\[^\\]|[^\\@])*@[egimosx]*',
+                String.Regex),
+            (r's%(\\\\|\\[^\\]|[^\\%])*%(\\\\|\\[^\\]|[^\\%])*%[egimosx]*',
+                String.Regex),
+            # balanced delimiters
+            (r's\{(\\\\|\\[^\\]|[^\\}])*\}\s*', String.Regex, 'balanced-regex'),
+            (r's<(\\\\|\\[^\\]|[^\\>])*>\s*', String.Regex, 'balanced-regex'),
+            (r's\[(\\\\|\\[^\\]|[^\\\]])*\]\s*', String.Regex,
+                'balanced-regex'),
+            (r's\((\\\\|\\[^\\]|[^\\)])*\)\s*', String.Regex,
+                'balanced-regex'),
+
+            (r'm?/(\\\\|\\[^\\]|[^\\/\n])*/[gcimosx]*', String.Regex),
+            (r'm(?=[/!\\{<\[(@%$])', String.Regex, 'balanced-regex'),
+            (r'((?<==~)|(?<=\())\s*/(\\\\|\\[^\\]|[^\\/])*/[gcimosx]*',
+                String.Regex),
+            (r'\s+', Whitespace),
+            (words((
+                'abs', 'accept', 'alarm', 'atan2', 'bind', 'binmode', 'bless', 'caller', 'chdir',
+                'chmod', 'chomp', 'chop', 'chown', 'chr', 'chroot', 'close', 'closedir', 'connect',
+                'continue', 'cos', 'crypt', 'dbmclose', 'dbmopen', 'defined', 'delete', 'die',
+                'dump', 'each', 'endgrent', 'endhostent', 'endnetent', 'endprotoent',
+                'endpwent', 'endservent', 'eof', 'eval', 'exec', 'exists', 'exit', 'exp', 'fcntl',
+                'fileno', 'flock', 'fork', 'format', 'formline', 'getc', 'getgrent', 'getgrgid',
+                'getgrnam', 'gethostbyaddr', 'gethostbyname', 'gethostent', 'getlogin',
+                'getnetbyaddr', 'getnetbyname', 'getnetent', 'getpeername', 'getpgrp',
+                'getppid', 'getpriority', 'getprotobyname', 'getprotobynumber',
+                'getprotoent', 'getpwent', 'getpwnam', 'getpwuid', 'getservbyname',
+                'getservbyport', 'getservent', 'getsockname', 'getsockopt', 'glob', 'gmtime',
+                'goto', 'grep', 'hex', 'import', 'index', 'int', 'ioctl', 'join', 'keys', 'kill', 'last',
+                'lc', 'lcfirst', 'length', 'link', 'listen', 'local', 'localtime', 'log', 'lstat',
+                'map', 'mkdir', 'msgctl', 'msgget', 'msgrcv', 'msgsnd', 'my', 'next', 'oct', 'open',
+                'opendir', 'ord', 'our', 'pack', 'pipe', 'pop', 'pos', 'printf',
+                'prototype', 'push', 'quotemeta', 'rand', 'read', 'readdir',
+                'readline', 'readlink', 'readpipe', 'recv', 'redo', 'ref', 'rename',
+                'reverse', 'rewinddir', 'rindex', 'rmdir', 'scalar', 'seek', 'seekdir',
+                'select', 'semctl', 'semget', 'semop', 'send', 'setgrent', 'sethostent', 'setnetent',
+                'setpgrp', 'setpriority', 'setprotoent', 'setpwent', 'setservent',
+                'setsockopt', 'shift', 'shmctl', 'shmget', 'shmread', 'shmwrite', 'shutdown',
+                'sin', 'sleep', 'socket', 'socketpair', 'sort', 'splice', 'split', 'sprintf', 'sqrt',
+                'srand', 'stat', 'study', 'substr', 'symlink', 'syscall', 'sysopen', 'sysread',
+                'sysseek', 'system', 'syswrite', 'tell', 'telldir', 'tie', 'tied', 'time', 'times', 'tr',
+                'truncate', 'uc', 'ucfirst', 'umask', 'undef', 'unlink', 'unpack', 'unshift', 'untie',
+                'utime', 'values', 'vec', 'wait', 'waitpid', 'wantarray', 'warn', 'write'), suffix=r'\b'),
+             Name.Builtin),
+            (r'((__(DATA|DIE|WARN)__)|(STD(IN|OUT|ERR)))\b', Name.Builtin.Pseudo),
+            (r'(<<)([\'"]?)([a-zA-Z_]\w*)(\2;?\n.*?\n)(\3)(\n)',
+             bygroups(String, String, String.Delimiter, String, String.Delimiter, Whitespace)),
+            (r'__END__', Comment.Preproc, 'end-part'),
+            (r'\$\^[ADEFHILMOPSTWX]', Name.Variable.Global),
+            (r"\$[\\\"\[\]'&`+*.,;=%~?@$!<>(^|/-](?!\w)", Name.Variable.Global),
+            (r'[$@%#]+', Name.Variable, 'varname'),
+            (r'0_?[0-7]+(_[0-7]+)*', Number.Oct),
+            (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex),
+            (r'0b[01]+(_[01]+)*', Number.Bin),
+            (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?',
+             Number.Float),
+            (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float),
+            (r'\d+(_\d+)*', Number.Integer),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
+            (r'`(\\\\|\\[^\\]|[^`\\])*`', String.Backtick),
+            (r'<([^\s>]+)>', String.Regex),
+            (r'(q|qq|qw|qr|qx)\{', String.Other, 'cb-string'),
+            (r'(q|qq|qw|qr|qx)\(', String.Other, 'rb-string'),
+            (r'(q|qq|qw|qr|qx)\[', String.Other, 'sb-string'),
+            (r'(q|qq|qw|qr|qx)\<', String.Other, 'lt-string'),
+            (r'(q|qq|qw|qr|qx)([\W_])(.|\n)*?\2', String.Other),
+            (r'(package)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)',
+             bygroups(Keyword, Whitespace, Name.Namespace)),
+            (r'(use|require|no)(\s+)([a-zA-Z_]\w*(?:::[a-zA-Z_]\w*)*)',
+             bygroups(Keyword, Whitespace, Name.Namespace)),
+            (r'(sub)(\s+)', bygroups(Keyword, Whitespace), 'funcname'),
+            (words((
+                'no', 'package', 'require', 'use'), suffix=r'\b'),
+             Keyword),
+            (r'(\[\]|\*\*|::|<<|>>|>=|<=>|<=|={3}|!=|=~|'
+             r'!~|&&?|\|\||\.{1,3})', Operator),
+            (r'[-+/*%=<>&^|!\\~]=?', Operator),
+            (r'[()\[\]:;,<>/?{}]', Punctuation),  # yes, there's no shortage
+                                                  # of punctuation in Perl!
+            (r'(?=\w)', Name, 'name'),
+        ],
+        'format': [
+            (r'\.\n', String.Interpol, '#pop'),
+            (r'[^\n]*\n', String.Interpol),
+        ],
+        'varname': [
+            (r'\s+', Whitespace),
+            (r'\{', Punctuation, '#pop'),    # hash syntax?
+            (r'\)|,', Punctuation, '#pop'),  # argument specifier
+            (r'\w+::', Name.Namespace),
+            (r'[\w:]+', Name.Variable, '#pop'),
+        ],
+        'name': [
+            (r'[a-zA-Z_]\w*(::[a-zA-Z_]\w*)*(::)?(?=\s*->)', Name.Namespace, '#pop'),
+            (r'[a-zA-Z_]\w*(::[a-zA-Z_]\w*)*::', Name.Namespace, '#pop'),
+            (r'[\w:]+', Name, '#pop'),
+            (r'[A-Z_]+(?=\W)', Name.Constant, '#pop'),
+            (r'(?=\W)', Text, '#pop'),
+        ],
+        'funcname': [
+            (r'[a-zA-Z_]\w*[!?]?', Name.Function),
+            (r'\s+', Whitespace),
+            # argument declaration
+            (r'(\([$@%]*\))(\s*)', bygroups(Punctuation, Whitespace)),
+            (r';', Punctuation, '#pop'),
+            (r'.*?\{', Punctuation, '#pop'),
+        ],
+        'cb-string': [
+            (r'\\[{}\\]', String.Other),
+            (r'\\', String.Other),
+            (r'\{', String.Other, 'cb-string'),
+            (r'\}', String.Other, '#pop'),
+            (r'[^{}\\]+', String.Other)
+        ],
+        'rb-string': [
+            (r'\\[()\\]', String.Other),
+            (r'\\', String.Other),
+            (r'\(', String.Other, 'rb-string'),
+            (r'\)', String.Other, '#pop'),
+            (r'[^()]+', String.Other)
+        ],
+        'sb-string': [
+            (r'\\[\[\]\\]', String.Other),
+            (r'\\', String.Other),
+            (r'\[', String.Other, 'sb-string'),
+            (r'\]', String.Other, '#pop'),
+            (r'[^\[\]]+', String.Other)
+        ],
+        'lt-string': [
+            (r'\\[<>\\]', String.Other),
+            (r'\\', String.Other),
+            (r'\<', String.Other, 'lt-string'),
+            (r'\>', String.Other, '#pop'),
+            (r'[^<>]+', String.Other)
+        ],
+        'end-part': [
+            (r'.+', Comment.Preproc, '#pop')
+        ]
+    }
+
+    def analyse_text(text):
+        if shebang_matches(text, r'perl'):
+            return True
+
+        result = 0
+
+        if re.search(r'(?:my|our)\s+[$@%(]', text):
+            result += 0.9
+
+        if ':=' in text:
+            # := is not valid Perl, but it appears in unicon, so we should
+            # become less confident if we think we found Perl with :=
+            result /= 2
+
+        return result
+
+
+class Perl6Lexer(ExtendedRegexLexer):
+    """
+    For Raku (a.k.a. Perl 6) source code.
+    """
+
+    name = 'Perl6'
+    url = 'https://www.raku.org'
+    aliases = ['perl6', 'pl6', 'raku']
+    filenames = ['*.pl', '*.pm', '*.nqp', '*.p6', '*.6pl', '*.p6l', '*.pl6',
+                 '*.6pm', '*.p6m', '*.pm6', '*.t', '*.raku', '*.rakumod',
+                 '*.rakutest', '*.rakudoc']
+    mimetypes = ['text/x-perl6', 'application/x-perl6']
+    version_added = '2.0'
+    flags = re.MULTILINE | re.DOTALL
+
+    PERL6_IDENTIFIER_RANGE = r"['\w:-]"
+
+    PERL6_KEYWORDS = (
+        #Phasers
+        'BEGIN','CATCH','CHECK','CLOSE','CONTROL','DOC','END','ENTER','FIRST',
+        'INIT','KEEP','LAST','LEAVE','NEXT','POST','PRE','QUIT','UNDO',
+        #Keywords
+        'anon','augment','but','class','constant','default','does','else',
+        'elsif','enum','for','gather','given','grammar','has','if','import',
+        'is','let','loop','made','make','method','module','multi','my','need',
+        'orwith','our','proceed','proto','repeat','require','return',
+        'return-rw','returns','role','rule','state','sub','submethod','subset',
+        'succeed','supersede','token','try','unit','unless','until','use',
+        'when','while','with','without',
+        #Traits
+        'export','native','repr','required','rw','symbol',
+    )
+
+    PERL6_BUILTINS = (
+        'ACCEPTS','abs','abs2rel','absolute','accept','accessed','acos',
+        'acosec','acosech','acosh','acotan','acotanh','acquire','act','action',
+        'actions','add','add_attribute','add_enum_value','add_fallback',
+        'add_method','add_parent','add_private_method','add_role','add_trustee',
+        'adverb','after','all','allocate','allof','allowed','alternative-names',
+        'annotations','antipair','antipairs','any','anyof','app_lifetime',
+        'append','arch','archname','args','arity','Array','asec','asech','asin',
+        'asinh','ASSIGN-KEY','ASSIGN-POS','assuming','ast','at','atan','atan2',
+        'atanh','AT-KEY','atomic-assign','atomic-dec-fetch','atomic-fetch',
+        'atomic-fetch-add','atomic-fetch-dec','atomic-fetch-inc',
+        'atomic-fetch-sub','atomic-inc-fetch','AT-POS','attributes','auth',
+        'await','backtrace','Bag','BagHash','bail-out','base','basename',
+        'base-repeating','batch','BIND-KEY','BIND-POS','bind-stderr',
+        'bind-stdin','bind-stdout','bind-udp','bits','bless','block','Bool',
+        'bool-only','bounds','break','Bridge','broken','BUILD','build-date',
+        'bytes','cache','callframe','calling-package','CALL-ME','callsame',
+        'callwith','can','cancel','candidates','cando','can-ok','canonpath',
+        'caps','caption','Capture','cas','catdir','categorize','categorize-list',
+        'catfile','catpath','cause','ceiling','cglobal','changed','Channel',
+        'chars','chdir','child','child-name','child-typename','chmod','chomp',
+        'chop','chr','chrs','chunks','cis','classify','classify-list','cleanup',
+        'clone','close','closed','close-stdin','cmp-ok','code','codes','collate',
+        'column','comb','combinations','command','comment','compiler','Complex',
+        'compose','compose_type','composer','condition','config',
+        'configure_destroy','configure_type_checking','conj','connect',
+        'constraints','construct','contains','contents','copy','cos','cosec',
+        'cosech','cosh','cotan','cotanh','count','count-only','cpu-cores',
+        'cpu-usage','CREATE','create_type','cross','cue','curdir','curupdir','d',
+        'Date','DateTime','day','daycount','day-of-month','day-of-week',
+        'day-of-year','days-in-month','declaration','decode','decoder','deepmap',
+        'default','defined','DEFINITE','delayed','DELETE-KEY','DELETE-POS',
+        'denominator','desc','DESTROY','destroyers','devnull','diag',
+        'did-you-mean','die','dies-ok','dir','dirname','dir-sep','DISTROnames',
+        'do','does','does-ok','done','done-testing','duckmap','dynamic','e',
+        'eager','earlier','elems','emit','enclosing','encode','encoder',
+        'encoding','end','ends-with','enum_from_value','enum_value_list',
+        'enum_values','enums','eof','EVAL','eval-dies-ok','EVALFILE',
+        'eval-lives-ok','exception','excludes-max','excludes-min','EXISTS-KEY',
+        'EXISTS-POS','exit','exitcode','exp','expected','explicitly-manage',
+        'expmod','extension','f','fail','fails-like','fc','feature','file',
+        'filename','find_method','find_method_qualified','finish','first','flat',
+        'flatmap','flip','floor','flunk','flush','fmt','format','formatter',
+        'freeze','from','from-list','from-loop','from-posix','full',
+        'full-barrier','get','get_value','getc','gist','got','grab','grabpairs',
+        'grep','handle','handled','handles','hardware','has_accessor','Hash',
+        'head','headers','hh-mm-ss','hidden','hides','hour','how','hyper','id',
+        'illegal','im','in','indent','index','indices','indir','infinite',
+        'infix','infix:<+>','infix:<->','install_method_cache','Instant',
+        'instead','Int','int-bounds','interval','in-timezone','invalid-str',
+        'invert','invocant','IO','IO::Notification.watch-path','is_trusted',
+        'is_type','isa','is-absolute','isa-ok','is-approx','is-deeply',
+        'is-hidden','is-initial-thread','is-int','is-lazy','is-leap-year',
+        'isNaN','isnt','is-prime','is-relative','is-routine','is-setting',
+        'is-win','item','iterator','join','keep','kept','KERNELnames','key',
+        'keyof','keys','kill','kv','kxxv','l','lang','last','lastcall','later',
+        'lazy','lc','leading','level','like','line','lines','link','List',
+        'listen','live','lives-ok','local','lock','log','log10','lookup','lsb',
+        'made','MAIN','make','Map','match','max','maxpairs','merge','message',
+        'method','method_table','methods','migrate','min','minmax','minpairs',
+        'minute','misplaced','Mix','MixHash','mkdir','mode','modified','month',
+        'move','mro','msb','multi','multiness','my','name','named','named_names',
+        'narrow','nativecast','native-descriptor','nativesizeof','new','new_type',
+        'new-from-daycount','new-from-pairs','next','nextcallee','next-handle',
+        'nextsame','nextwith','NFC','NFD','NFKC','NFKD','nl-in','nl-out',
+        'nodemap','nok','none','norm','not','note','now','nude','Num',
+        'numerator','Numeric','of','offset','offset-in-hours','offset-in-minutes',
+        'ok','old','on-close','one','on-switch','open','opened','operation',
+        'optional','ord','ords','orig','os-error','osname','out-buffer','pack',
+        'package','package-kind','package-name','packages','pair','pairs',
+        'pairup','parameter','params','parent','parent-name','parents','parse',
+        'parse-base','parsefile','parse-names','parts','pass','path','path-sep',
+        'payload','peer-host','peer-port','periods','perl','permutations','phaser',
+        'pick','pickpairs','pid','placeholder','plan','plus','polar','poll',
+        'polymod','pop','pos','positional','posix','postfix','postmatch',
+        'precomp-ext','precomp-target','pred','prefix','prematch','prepend',
+        'print','printf','print-nl','print-to','private','private_method_table',
+        'proc','produce','Promise','prompt','protect','pull-one','push',
+        'push-all','push-at-least','push-exactly','push-until-lazy','put',
+        'qualifier-type','quit','r','race','radix','rand','range','Rat','raw',
+        're','read','readchars','readonly','ready','Real','reallocate','reals',
+        'reason','rebless','receive','recv','redispatcher','redo','reduce',
+        'rel2abs','relative','release','rename','repeated','replacement',
+        'report','reserved','resolve','restore','result','resume','rethrow',
+        'reverse','right','rindex','rmdir','role','roles_to_compose','rolish',
+        'roll','rootdir','roots','rotate','rotor','round','roundrobin',
+        'routine-type','run','rwx','s','samecase','samemark','samewith','say',
+        'schedule-on','scheduler','scope','sec','sech','second','seek','self',
+        'send','Set','set_hidden','set_name','set_package','set_rw','set_value',
+        'SetHash','set-instruments','setup_finalization','shape','share','shell',
+        'shift','sibling','sigil','sign','signal','signals','signature','sin',
+        'sinh','sink','sink-all','skip','skip-at-least','skip-at-least-pull-one',
+        'skip-one','skip-rest','sleep','sleep-timer','sleep-until','Slip','slurp',
+        'slurp-rest','slurpy','snap','snapper','so','socket-host','socket-port',
+        'sort','source','source-package','spawn','SPEC','splice','split',
+        'splitdir','splitpath','sprintf','spurt','sqrt','squish','srand','stable',
+        'start','started','starts-with','status','stderr','stdout','Str',
+        'sub_signature','subbuf','subbuf-rw','subname','subparse','subst',
+        'subst-mutate','substr','substr-eq','substr-rw','subtest','succ','sum',
+        'Supply','symlink','t','tail','take','take-rw','tan','tanh','tap',
+        'target','target-name','tc','tclc','tell','then','throttle','throw',
+        'throws-like','timezone','tmpdir','to','today','todo','toggle','to-posix',
+        'total','trailing','trans','tree','trim','trim-leading','trim-trailing',
+        'truncate','truncated-to','trusts','try_acquire','trying','twigil','type',
+        'type_captures','typename','uc','udp','uncaught_handler','unimatch',
+        'uniname','uninames','uniparse','uniprop','uniprops','unique','unival',
+        'univals','unlike','unlink','unlock','unpack','unpolar','unshift',
+        'unwrap','updir','USAGE','use-ok','utc','val','value','values','VAR',
+        'variable','verbose-config','version','VMnames','volume','vow','w','wait',
+        'warn','watch','watch-path','week','weekday-of-month','week-number',
+        'week-year','WHAT','when','WHERE','WHEREFORE','WHICH','WHO',
+        'whole-second','WHY','wordcase','words','workaround','wrap','write',
+        'write-to','x','yada','year','yield','yyyy-mm-dd','z','zip','zip-latest',
+
+    )
+
+    PERL6_BUILTIN_CLASSES = (
+        #Booleans
+        'False','True',
+        #Classes
+        'Any','Array','Associative','AST','atomicint','Attribute','Backtrace',
+        'Backtrace::Frame','Bag','Baggy','BagHash','Blob','Block','Bool','Buf',
+        'Callable','CallFrame','Cancellation','Capture','CArray','Channel','Code',
+        'compiler','Complex','ComplexStr','Cool','CurrentThreadScheduler',
+        'Cursor','Date','Dateish','DateTime','Distro','Duration','Encoding',
+        'Exception','Failure','FatRat','Grammar','Hash','HyperWhatever','Instant',
+        'Int','int16','int32','int64','int8','IntStr','IO','IO::ArgFiles',
+        'IO::CatHandle','IO::Handle','IO::Notification','IO::Path',
+        'IO::Path::Cygwin','IO::Path::QNX','IO::Path::Unix','IO::Path::Win32',
+        'IO::Pipe','IO::Socket','IO::Socket::Async','IO::Socket::INET','IO::Spec',
+        'IO::Spec::Cygwin','IO::Spec::QNX','IO::Spec::Unix','IO::Spec::Win32',
+        'IO::Special','Iterable','Iterator','Junction','Kernel','Label','List',
+        'Lock','Lock::Async','long','longlong','Macro','Map','Match',
+        'Metamodel::AttributeContainer','Metamodel::C3MRO','Metamodel::ClassHOW',
+        'Metamodel::EnumHOW','Metamodel::Finalization','Metamodel::MethodContainer',
+        'Metamodel::MROBasedMethodDispatch','Metamodel::MultipleInheritance',
+        'Metamodel::Naming','Metamodel::Primitives','Metamodel::PrivateMethodContainer',
+        'Metamodel::RoleContainer','Metamodel::Trusting','Method','Mix','MixHash',
+        'Mixy','Mu','NFC','NFD','NFKC','NFKD','Nil','Num','num32','num64',
+        'Numeric','NumStr','ObjAt','Order','Pair','Parameter','Perl','Pod::Block',
+        'Pod::Block::Code','Pod::Block::Comment','Pod::Block::Declarator',
+        'Pod::Block::Named','Pod::Block::Para','Pod::Block::Table','Pod::Heading',
+        'Pod::Item','Pointer','Positional','PositionalBindFailover','Proc',
+        'Proc::Async','Promise','Proxy','PseudoStash','QuantHash','Range','Rat',
+        'Rational','RatStr','Real','Regex','Routine','Scalar','Scheduler',
+        'Semaphore','Seq','Set','SetHash','Setty','Signature','size_t','Slip',
+        'Stash','Str','StrDistance','Stringy','Sub','Submethod','Supplier',
+        'Supplier::Preserving','Supply','Systemic','Tap','Telemetry',
+        'Telemetry::Instrument::Thread','Telemetry::Instrument::Usage',
+        'Telemetry::Period','Telemetry::Sampler','Thread','ThreadPoolScheduler',
+        'UInt','uint16','uint32','uint64','uint8','Uni','utf8','Variable',
+        'Version','VM','Whatever','WhateverCode','WrapHandle'
+    )
+
+    PERL6_OPERATORS = (
+        'X', 'Z', 'after', 'also', 'and', 'andthen', 'before', 'cmp', 'div',
+        'eq', 'eqv', 'extra', 'ff', 'fff', 'ge', 'gt', 'le', 'leg', 'lt', 'm',
+        'mm', 'mod', 'ne', 'or', 'orelse', 'rx', 's', 'tr', 'x', 'xor', 'xx',
+        '++', '--', '**', '!', '+', '-', '~', '?', '|', '||', '+^', '~^', '?^',
+        '^', '*', '/', '%', '%%', '+&', '+<', '+>', '~&', '~<', '~>', '?&',
+        'gcd', 'lcm', '+', '-', '+|', '+^', '~|', '~^', '?|', '?^',
+        '~', '&', '^', 'but', 'does', '<=>', '..', '..^', '^..', '^..^',
+        '!=', '==', '<', '<=', '>', '>=', '~~', '===', '!eqv',
+        '&&', '||', '^^', '//', 'min', 'max', '??', '!!', 'ff', 'fff', 'so',
+        'not', '<==', '==>', '<<==', '==>>','unicmp',
+    )
+
+    # Perl 6 has a *lot* of possible bracketing characters
+    # this list was lifted from STD.pm6 (https://github.com/perl6/std)
+    PERL6_BRACKETS = {
+        '\u0028': '\u0029', '\u003c': '\u003e', '\u005b': '\u005d',
+        '\u007b': '\u007d', '\u00ab': '\u00bb', '\u0f3a': '\u0f3b',
+        '\u0f3c': '\u0f3d', '\u169b': '\u169c', '\u2018': '\u2019',
+        '\u201a': '\u2019', '\u201b': '\u2019', '\u201c': '\u201d',
+        '\u201e': '\u201d', '\u201f': '\u201d', '\u2039': '\u203a',
+        '\u2045': '\u2046', '\u207d': '\u207e', '\u208d': '\u208e',
+        '\u2208': '\u220b', '\u2209': '\u220c', '\u220a': '\u220d',
+        '\u2215': '\u29f5', '\u223c': '\u223d', '\u2243': '\u22cd',
+        '\u2252': '\u2253', '\u2254': '\u2255', '\u2264': '\u2265',
+        '\u2266': '\u2267', '\u2268': '\u2269', '\u226a': '\u226b',
+        '\u226e': '\u226f', '\u2270': '\u2271', '\u2272': '\u2273',
+        '\u2274': '\u2275', '\u2276': '\u2277', '\u2278': '\u2279',
+        '\u227a': '\u227b', '\u227c': '\u227d', '\u227e': '\u227f',
+        '\u2280': '\u2281', '\u2282': '\u2283', '\u2284': '\u2285',
+        '\u2286': '\u2287', '\u2288': '\u2289', '\u228a': '\u228b',
+        '\u228f': '\u2290', '\u2291': '\u2292', '\u2298': '\u29b8',
+        '\u22a2': '\u22a3', '\u22a6': '\u2ade', '\u22a8': '\u2ae4',
+        '\u22a9': '\u2ae3', '\u22ab': '\u2ae5', '\u22b0': '\u22b1',
+        '\u22b2': '\u22b3', '\u22b4': '\u22b5', '\u22b6': '\u22b7',
+        '\u22c9': '\u22ca', '\u22cb': '\u22cc', '\u22d0': '\u22d1',
+        '\u22d6': '\u22d7', '\u22d8': '\u22d9', '\u22da': '\u22db',
+        '\u22dc': '\u22dd', '\u22de': '\u22df', '\u22e0': '\u22e1',
+        '\u22e2': '\u22e3', '\u22e4': '\u22e5', '\u22e6': '\u22e7',
+        '\u22e8': '\u22e9', '\u22ea': '\u22eb', '\u22ec': '\u22ed',
+        '\u22f0': '\u22f1', '\u22f2': '\u22fa', '\u22f3': '\u22fb',
+        '\u22f4': '\u22fc', '\u22f6': '\u22fd', '\u22f7': '\u22fe',
+        '\u2308': '\u2309', '\u230a': '\u230b', '\u2329': '\u232a',
+        '\u23b4': '\u23b5', '\u2768': '\u2769', '\u276a': '\u276b',
+        '\u276c': '\u276d', '\u276e': '\u276f', '\u2770': '\u2771',
+        '\u2772': '\u2773', '\u2774': '\u2775', '\u27c3': '\u27c4',
+        '\u27c5': '\u27c6', '\u27d5': '\u27d6', '\u27dd': '\u27de',
+        '\u27e2': '\u27e3', '\u27e4': '\u27e5', '\u27e6': '\u27e7',
+        '\u27e8': '\u27e9', '\u27ea': '\u27eb', '\u2983': '\u2984',
+        '\u2985': '\u2986', '\u2987': '\u2988', '\u2989': '\u298a',
+        '\u298b': '\u298c', '\u298d': '\u298e', '\u298f': '\u2990',
+        '\u2991': '\u2992', '\u2993': '\u2994', '\u2995': '\u2996',
+        '\u2997': '\u2998', '\u29c0': '\u29c1', '\u29c4': '\u29c5',
+        '\u29cf': '\u29d0', '\u29d1': '\u29d2', '\u29d4': '\u29d5',
+        '\u29d8': '\u29d9', '\u29da': '\u29db', '\u29f8': '\u29f9',
+        '\u29fc': '\u29fd', '\u2a2b': '\u2a2c', '\u2a2d': '\u2a2e',
+        '\u2a34': '\u2a35', '\u2a3c': '\u2a3d', '\u2a64': '\u2a65',
+        '\u2a79': '\u2a7a', '\u2a7d': '\u2a7e', '\u2a7f': '\u2a80',
+        '\u2a81': '\u2a82', '\u2a83': '\u2a84', '\u2a8b': '\u2a8c',
+        '\u2a91': '\u2a92', '\u2a93': '\u2a94', '\u2a95': '\u2a96',
+        '\u2a97': '\u2a98', '\u2a99': '\u2a9a', '\u2a9b': '\u2a9c',
+        '\u2aa1': '\u2aa2', '\u2aa6': '\u2aa7', '\u2aa8': '\u2aa9',
+        '\u2aaa': '\u2aab', '\u2aac': '\u2aad', '\u2aaf': '\u2ab0',
+        '\u2ab3': '\u2ab4', '\u2abb': '\u2abc', '\u2abd': '\u2abe',
+        '\u2abf': '\u2ac0', '\u2ac1': '\u2ac2', '\u2ac3': '\u2ac4',
+        '\u2ac5': '\u2ac6', '\u2acd': '\u2ace', '\u2acf': '\u2ad0',
+        '\u2ad1': '\u2ad2', '\u2ad3': '\u2ad4', '\u2ad5': '\u2ad6',
+        '\u2aec': '\u2aed', '\u2af7': '\u2af8', '\u2af9': '\u2afa',
+        '\u2e02': '\u2e03', '\u2e04': '\u2e05', '\u2e09': '\u2e0a',
+        '\u2e0c': '\u2e0d', '\u2e1c': '\u2e1d', '\u2e20': '\u2e21',
+        '\u3008': '\u3009', '\u300a': '\u300b', '\u300c': '\u300d',
+        '\u300e': '\u300f', '\u3010': '\u3011', '\u3014': '\u3015',
+        '\u3016': '\u3017', '\u3018': '\u3019', '\u301a': '\u301b',
+        '\u301d': '\u301e', '\ufd3e': '\ufd3f', '\ufe17': '\ufe18',
+        '\ufe35': '\ufe36', '\ufe37': '\ufe38', '\ufe39': '\ufe3a',
+        '\ufe3b': '\ufe3c', '\ufe3d': '\ufe3e', '\ufe3f': '\ufe40',
+        '\ufe41': '\ufe42', '\ufe43': '\ufe44', '\ufe47': '\ufe48',
+        '\ufe59': '\ufe5a', '\ufe5b': '\ufe5c', '\ufe5d': '\ufe5e',
+        '\uff08': '\uff09', '\uff1c': '\uff1e', '\uff3b': '\uff3d',
+        '\uff5b': '\uff5d', '\uff5f': '\uff60', '\uff62': '\uff63',
+    }
+
+    def _build_word_match(words, boundary_regex_fragment=None, prefix='', suffix=''):
+        if boundary_regex_fragment is None:
+            return r'\b(' + prefix + r'|'.join(re.escape(x) for x in words) + \
+                suffix + r')\b'
+        else:
+            return r'(? 0:
+                    next_open_pos = text.find(opening_chars, search_pos + n_chars)
+                    next_close_pos = text.find(closing_chars, search_pos + n_chars)
+
+                    if next_close_pos == -1:
+                        next_close_pos = len(text)
+                        nesting_level = 0
+                    elif next_open_pos != -1 and next_open_pos < next_close_pos:
+                        nesting_level += 1
+                        search_pos = next_open_pos
+                    else:  # next_close_pos < next_open_pos
+                        nesting_level -= 1
+                        search_pos = next_close_pos
+
+                end_pos = next_close_pos
+
+            if end_pos < 0:     # if we didn't find a closer, just highlight the
+                                # rest of the text in this class
+                end_pos = len(text)
+
+            if adverbs is not None and re.search(r':to\b', adverbs):
+                heredoc_terminator = text[match.start('delimiter') + n_chars:end_pos]
+                end_heredoc = re.search(r'^\s*' + re.escape(heredoc_terminator) +
+                                        r'\s*$', text[end_pos:], re.MULTILINE)
+
+                if end_heredoc:
+                    end_pos += end_heredoc.end()
+                else:
+                    end_pos = len(text)
+
+            yield match.start(), token_class, text[match.start():end_pos + n_chars]
+            context.pos = end_pos + n_chars
+
+        return callback
+
+    def opening_brace_callback(lexer, match, context):
+        stack = context.stack
+
+        yield match.start(), Text, context.text[match.start():match.end()]
+        context.pos = match.end()
+
+        # if we encounter an opening brace and we're one level
+        # below a token state, it means we need to increment
+        # the nesting level for braces so we know later when
+        # we should return to the token rules.
+        if len(stack) > 2 and stack[-2] == 'token':
+            context.perl6_token_nesting_level += 1
+
+    def closing_brace_callback(lexer, match, context):
+        stack = context.stack
+
+        yield match.start(), Text, context.text[match.start():match.end()]
+        context.pos = match.end()
+
+        # if we encounter a free closing brace and we're one level
+        # below a token state, it means we need to check the nesting
+        # level to see if we need to return to the token state.
+        if len(stack) > 2 and stack[-2] == 'token':
+            context.perl6_token_nesting_level -= 1
+            if context.perl6_token_nesting_level == 0:
+                stack.pop()
+
+    def embedded_perl6_callback(lexer, match, context):
+        context.perl6_token_nesting_level = 1
+        yield match.start(), Text, context.text[match.start():match.end()]
+        context.pos = match.end()
+        context.stack.append('root')
+
+    # If you're modifying these rules, be careful if you need to process '{' or '}'
+    # characters. We have special logic for processing these characters (due to the fact
+    # that you can nest Perl 6 code in regex blocks), so if you need to process one of
+    # them, make sure you also process the corresponding one!
+    tokens = {
+        'common': [
+            (r'#[`|=](?P(?P[' + ''.join(PERL6_BRACKETS) + r'])(?P=first_char)*)',
+             brackets_callback(Comment.Multiline)),
+            (r'#[^\n]*$', Comment.Single),
+            (r'^(\s*)=begin\s+(\w+)\b.*?^\1=end\s+\2', Comment.Multiline),
+            (r'^(\s*)=for.*?\n\s*?\n', Comment.Multiline),
+            (r'^=.*?\n\s*?\n', Comment.Multiline),
+            (r'(regex|token|rule)(\s*' + PERL6_IDENTIFIER_RANGE + '+:sym)',
+             bygroups(Keyword, Name), 'token-sym-brackets'),
+            (r'(regex|token|rule)(?!' + PERL6_IDENTIFIER_RANGE + r')(\s*' + PERL6_IDENTIFIER_RANGE + '+)?',
+             bygroups(Keyword, Name), 'pre-token'),
+            # deal with a special case in the Perl 6 grammar (role q { ... })
+            (r'(role)(\s+)(q)(\s*)', bygroups(Keyword, Whitespace, Name, Whitespace)),
+            (_build_word_match(PERL6_KEYWORDS, PERL6_IDENTIFIER_RANGE), Keyword),
+            (_build_word_match(PERL6_BUILTIN_CLASSES, PERL6_IDENTIFIER_RANGE, suffix='(?::[UD])?'),
+             Name.Builtin),
+            (_build_word_match(PERL6_BUILTINS, PERL6_IDENTIFIER_RANGE), Name.Builtin),
+            # copied from PerlLexer
+            (r'[$@%&][.^:?=!~]?' + PERL6_IDENTIFIER_RANGE + '+(?:<<.*?>>|<.*?>|«.*?»)*',
+             Name.Variable),
+            (r'\$[!/](?:<<.*?>>|<.*?>|«.*?»)*', Name.Variable.Global),
+            (r'::\?\w+', Name.Variable.Global),
+            (r'[$@%&]\*' + PERL6_IDENTIFIER_RANGE + '+(?:<<.*?>>|<.*?>|«.*?»)*',
+             Name.Variable.Global),
+            (r'\$(?:<.*?>)+', Name.Variable),
+            (r'(?:q|qq|Q)[a-zA-Z]?\s*(?P:[\w\s:]+)?\s*(?P(?P[^0-9a-zA-Z:\s])'
+             r'(?P=first_char)*)', brackets_callback(String)),
+            # copied from PerlLexer
+            (r'0_?[0-7]+(_[0-7]+)*', Number.Oct),
+            (r'0x[0-9A-Fa-f]+(_[0-9A-Fa-f]+)*', Number.Hex),
+            (r'0b[01]+(_[01]+)*', Number.Bin),
+            (r'(?i)(\d*(_\d*)*\.\d+(_\d*)*|\d+(_\d*)*\.\d+(_\d*)*)(e[+-]?\d+)?',
+             Number.Float),
+            (r'(?i)\d+(_\d*)*e[+-]?\d+(_\d*)*', Number.Float),
+            (r'\d+(_\d+)*', Number.Integer),
+            (r'(?<=~~)\s*/(?:\\\\|\\/|.)*?/', String.Regex),
+            (r'(?<=[=(,])\s*/(?:\\\\|\\/|.)*?/', String.Regex),
+            (r'm\w+(?=\()', Name),
+            (r'(?:m|ms|rx)\s*(?P:[\w\s:]+)?\s*(?P(?P[^\w:\s])'
+             r'(?P=first_char)*)', brackets_callback(String.Regex)),
+            (r'(?:s|ss|tr)\s*(?::[\w\s:]+)?\s*/(?:\\\\|\\/|.)*?/(?:\\\\|\\/|.)*?/',
+             String.Regex),
+            (r'<[^\s=].*?\S>', String),
+            (_build_word_match(PERL6_OPERATORS), Operator),
+            (r'\w' + PERL6_IDENTIFIER_RANGE + '*', Name),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
+        ],
+        'root': [
+            include('common'),
+            (r'\{', opening_brace_callback),
+            (r'\}', closing_brace_callback),
+            (r'.+?', Text),
+        ],
+        'pre-token': [
+            include('common'),
+            (r'\{', Text, ('#pop', 'token')),
+            (r'.+?', Text),
+        ],
+        'token-sym-brackets': [
+            (r'(?P(?P[' + ''.join(PERL6_BRACKETS) + '])(?P=first_char)*)',
+             brackets_callback(Name), ('#pop', 'pre-token')),
+            default(('#pop', 'pre-token')),
+        ],
+        'token': [
+            (r'\}', Text, '#pop'),
+            (r'(?<=:)(?:my|our|state|constant|temp|let).*?;', using(this)),
+            # make sure that quotes in character classes aren't treated as strings
+            (r'<(?:[-!?+.]\s*)?\[.*?\]>', String.Regex),
+            # make sure that '#' characters in quotes aren't treated as comments
+            (r"(?my|our)\s+)?(?:module|class|role|enum|grammar)', line)
+            if class_decl:
+                if saw_perl_decl or class_decl.group('scope') is not None:
+                    return True
+                rating = 0.05
+                continue
+            break
+
+        if ':=' in text:
+            # Same logic as above for PerlLexer
+            rating /= 2
+
+        return rating
+
+    def __init__(self, **options):
+        super().__init__(**options)
+        self.encoding = options.get('encoding', 'utf-8')
diff --git a/.venv/Lib/site-packages/pygments/lexers/phix.py b/.venv/Lib/site-packages/pygments/lexers/phix.py
new file mode 100644
index 0000000..f0b0377
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/phix.py
@@ -0,0 +1,363 @@
+"""
+    pygments.lexers.phix
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Phix.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Whitespace
+
+__all__ = ['PhixLexer']
+
+
+class PhixLexer(RegexLexer):
+    """
+    Pygments Lexer for Phix files (.exw).
+    See http://phix.x10.mx
+    """
+
+    name = 'Phix'
+    url = 'http://phix.x10.mx'
+    aliases = ['phix']
+    filenames = ['*.exw']
+    mimetypes = ['text/x-phix']
+    version_added = '2.14'
+
+    flags = re.MULTILINE    # nb: **NOT** re.DOTALL! (totally spanners comment handling)
+
+    preproc = (
+        'ifdef', 'elsifdef', 'elsedef'
+    )
+    # Note these lists are auto-generated by pwa/p2js.exw, when pwa\src\p2js_keywords.e (etc)
+    #     change, though of course subsequent copy/commit/pull requests are all manual steps.
+    types = (
+        'string', 'nullable_string', 'atom_string', 'atom', 'bool', 'boolean',
+        'cdCanvan', 'cdCanvas', 'complex', 'CURLcode', 'dictionary', 'int',
+        'integer', 'Ihandle', 'Ihandles', 'Ihandln', 'mpfr', 'mpq', 'mpz',
+        'mpz_or_string', 'number', 'rid_string', 'seq', 'sequence', 'timedate',
+        'object'
+    )
+    keywords = (
+        'abstract', 'class', 'continue', 'export', 'extends', 'nullable',
+        'private', 'public', 'static', 'struct', 'trace',
+        'and', 'break', 'by', 'case', 'catch', 'const', 'constant', 'debug',
+        'default', 'do', 'else', 'elsif', 'end', 'enum', 'exit', 'fallthru',
+        'fallthrough', 'for', 'forward', 'function', 'global', 'if', 'in',
+        'include', 'js', 'javascript', 'javascript_semantics', 'let', 'not',
+        'or', 'procedure', 'profile', 'profile_time', 'return', 'safe_mode',
+        'switch', 'then', 'to', 'try', 'type', 'type_check', 'until', 'warning',
+        'while', 'with', 'without', 'xor'
+    )
+    routines = (
+        'abort', 'abs', 'adjust_timedate', 'and_bits', 'and_bitsu', 'apply',
+        'append', 'arccos', 'arcsin', 'arctan', 'assert', 'atan2',
+        'atom_to_float32', 'atom_to_float64', 'bankers_rounding', 'beep',
+        'begins', 'binary_search', 'bits_to_int', 'bk_color', 'bytes_to_int',
+        'call_func', 'call_proc', 'cdCanvasActivate', 'cdCanvasArc',
+        'cdCanvasBegin', 'cdCanvasBox', 'cdCanvasChord', 'cdCanvasCircle',
+        'cdCanvasClear', 'cdCanvasEnd', 'cdCanvasFlush', 'cdCanvasFont',
+        'cdCanvasGetImageRGB', 'cdCanvasGetSize', 'cdCanvasGetTextAlignment',
+        'cdCanvasGetTextSize', 'cdCanvasLine', 'cdCanvasMark',
+        'cdCanvasMarkSize', 'cdCanvasMultiLineVectorText', 'cdCanvasPixel',
+        'cdCanvasRect', 'cdCanvasRoundedBox', 'cdCanvasRoundedRect',
+        'cdCanvasSector', 'cdCanvasSetAttribute', 'cdCanvasSetBackground',
+        'cdCanvasSetFillMode', 'cdCanvasSetForeground',
+        'cdCanvasSetInteriorStyle', 'cdCanvasSetLineStyle',
+        'cdCanvasSetLineWidth', 'cdCanvasSetTextAlignment', 'cdCanvasText',
+        'cdCanvasSetTextOrientation', 'cdCanvasGetTextOrientation',
+        'cdCanvasVectorText', 'cdCanvasVectorTextDirection',
+        'cdCanvasVectorTextSize', 'cdCanvasVertex', 'cdCreateCanvas',
+        'cdDecodeAlpha', 'cdDecodeColor', 'cdDecodeColorAlpha', 'cdEncodeAlpha',
+        'cdEncodeColor', 'cdEncodeColorAlpha', 'cdKillCanvas', 'cdVersion',
+        'cdVersionDate', 'ceil', 'change_timezone', 'choose', 'clear_screen',
+        'columnize', 'command_line', 'compare', 'complex_abs', 'complex_add',
+        'complex_arg', 'complex_conjugate', 'complex_cos', 'complex_cosh',
+        'complex_div', 'complex_exp', 'complex_imag', 'complex_inv',
+        'complex_log', 'complex_mul', 'complex_neg', 'complex_new',
+        'complex_norm', 'complex_power', 'complex_rho', 'complex_real',
+        'complex_round', 'complex_sin', 'complex_sinh', 'complex_sprint',
+        'complex_sqrt', 'complex_sub', 'complex_theta', 'concat', 'cos',
+        'crash', 'custom_sort', 'date', 'day_of_week', 'day_of_year',
+        'days_in_month', 'decode_base64', 'decode_flags', 'deep_copy', 'deld',
+        'deserialize', 'destroy_dict', 'destroy_queue', 'destroy_stack',
+        'dict_name', 'dict_size', 'elapsed', 'elapsed_short', 'encode_base64',
+        'equal', 'even', 'exp', 'extract', 'factorial', 'factors',
+        'file_size_k', 'find', 'find_all', 'find_any', 'find_replace', 'filter',
+        'flatten', 'float32_to_atom', 'float64_to_atom', 'floor',
+        'format_timedate', 'free_console', 'from_polar', 'gcd', 'get_file_base',
+        'get_file_extension', 'get_file_name', 'get_file_name_and_path',
+        'get_file_path', 'get_file_path_and_name', 'get_maxprime', 'get_prime',
+        'get_primes', 'get_primes_le', 'get_proper_dir', 'get_proper_path',
+        'get_rand', 'get_routine_info', 'get_test_abort', 'get_test_logfile',
+        'get_test_pause', 'get_test_verbosity', 'get_tzid', 'getd', 'getdd',
+        'getd_all_keys', 'getd_by_index', 'getd_index', 'getd_partial_key',
+        'glAttachShader', 'glBindBuffer', 'glBindTexture', 'glBufferData',
+        'glCanvasSpecialText', 'glClear', 'glClearColor', 'glColor',
+        'glCompileShader', 'glCreateBuffer', 'glCreateProgram',
+        'glCreateShader', 'glCreateTexture', 'glDeleteProgram',
+        'glDeleteShader', 'glDrawArrays', 'glEnable',
+        'glEnableVertexAttribArray', 'glFloat32Array', 'glInt32Array',
+        'glFlush', 'glGetAttribLocation', 'glGetError', 'glGetProgramInfoLog',
+        'glGetProgramParameter', 'glGetShaderInfoLog', 'glGetShaderParameter',
+        'glGetUniformLocation', 'glLinkProgram', 'glLoadIdentity',
+        'glMatrixMode', 'glOrtho', 'glRotatef', 'glShadeModel',
+        'glShaderSource', 'glSimpleA7texcoords', 'glTexImage2Dc',
+        'glTexParameteri', 'glTranslate', 'glUniform1f', 'glUniform1i',
+        'glUniformMatrix4fv', 'glUseProgram', 'glVertex',
+        'glVertexAttribPointer', 'glViewport', 'head', 'hsv_to_rgb', 'iff',
+        'iif', 'include_file', 'incl0de_file', 'insert', 'instance',
+        'int_to_bits', 'int_to_bytes', 'is_dict', 'is_integer', 's_leap_year',
+        'is_prime', 'is_prime2', 'islower', 'isupper', 'Icallback',
+        'iup_isdouble', 'iup_isprint', 'iup_XkeyBase', 'IupAppend', 'IupAlarm',
+        'IupBackgroundBox', 'IupButton', 'IupCalendar', 'IupCanvas',
+        'IupClipboard', 'IupClose', 'IupCloseOnEscape', 'IupControlsOpen',
+        'IupDatePick', 'IupDestroy', 'IupDialog', 'IupDrawArc', 'IupDrawBegin',
+        'IupDrawEnd', 'IupDrawGetSize', 'IupDrawGetTextSize', 'IupDrawLine',
+        'IupDrawRectangle', 'IupDrawText', 'IupExpander', 'IupFill',
+        'IupFlatLabel', 'IupFlatList', 'IupFlatTree', 'IupFlush', 'IupFrame',
+        'IupGetAttribute', 'IupGetAttributeId', 'IupGetAttributePtr',
+        'IupGetBrother', 'IupGetChild', 'IupGetChildCount', 'IupGetClassName',
+        'IupGetDialog', 'IupGetDialogChild', 'IupGetDouble', 'IupGetFocus',
+        'IupGetGlobal', 'IupGetGlobalInt', 'IupGetGlobalIntInt', 'IupGetInt',
+        'IupGetInt2', 'IupGetIntId', 'IupGetIntInt', 'IupGetParent',
+        'IupGLCanvas', 'IupGLCanvasOpen', 'IupGLMakeCurrent', 'IupGraph',
+        'IupHbox', 'IupHide', 'IupImage', 'IupImageRGBA', 'IupItem',
+        'iupKeyCodeToName', 'IupLabel', 'IupLink', 'IupList', 'IupMap',
+        'IupMenu', 'IupMenuItem', 'IupMessage', 'IupMessageDlg', 'IupMultiBox',
+        'IupMultiLine', 'IupNextField', 'IupNormaliser', 'IupOpen',
+        'IupPlayInput', 'IupPopup', 'IupPreviousField', 'IupProgressBar',
+        'IupRadio', 'IupRecordInput', 'IupRedraw', 'IupRefresh',
+        'IupRefreshChildren', 'IupSeparator', 'IupSetAttribute',
+        'IupSetAttributes', 'IupSetAttributeHandle', 'IupSetAttributeId',
+        'IupSetAttributePtr', 'IupSetCallback', 'IupSetCallbacks',
+        'IupSetDouble', 'IupSetFocus', 'IupSetGlobal', 'IupSetGlobalInt',
+        'IupSetGlobalFunction', 'IupSetHandle', 'IupSetInt',
+        'IupSetStrAttribute', 'IupSetStrGlobal', 'IupShow', 'IupShowXY',
+        'IupSplit', 'IupStoreAttribute', 'IupSubmenu', 'IupTable',
+        'IupTableClearSelected', 'IupTableClick_cb', 'IupTableGetSelected',
+        'IupTableResize_cb', 'IupTableSetData', 'IupTabs', 'IupText',
+        'IupTimer', 'IupToggle', 'IupTreeAddNodes', 'IupTreeView', 'IupUpdate',
+        'IupValuator', 'IupVbox', 'join', 'join_by', 'join_path', 'k_perm',
+        'largest', 'lcm', 'length', 'log', 'log10', 'log2', 'lower',
+        'm4_crossProduct', 'm4_inverse', 'm4_lookAt', 'm4_multiply',
+        'm4_normalize', 'm4_perspective', 'm4_subtractVectors', 'm4_xRotate',
+        'm4_yRotate', 'machine_bits', 'machine_word', 'match', 'match_all',
+        'match_replace', 'max', 'maxsq', 'min', 'minsq', 'mod', 'mpfr_add',
+        'mpfr_ceil', 'mpfr_cmp', 'mpfr_cmp_si', 'mpfr_const_pi', 'mpfr_div',
+        'mpfr_div_si', 'mpfr_div_z', 'mpfr_floor', 'mpfr_free', 'mpfr_get_d',
+        'mpfr_get_default_precision', 'mpfr_get_default_rounding_mode',
+        'mpfr_get_fixed', 'mpfr_get_precision', 'mpfr_get_si', 'mpfr_init',
+        'mpfr_inits', 'mpfr_init_set', 'mpfr_init_set_q', 'mpfr_init_set_z',
+        'mpfr_mul', 'mpfr_mul_si', 'mpfr_pow_si', 'mpfr_set', 'mpfr_set_d',
+        'mpfr_set_default_precision', 'mpfr_set_default_rounding_mode',
+        'mpfr_set_precision', 'mpfr_set_q', 'mpfr_set_si', 'mpfr_set_str',
+        'mpfr_set_z', 'mpfr_si_div', 'mpfr_si_sub', 'mpfr_sqrt', 'mpfr_sub',
+        'mpfr_sub_si', 'mpq_abs', 'mpq_add', 'mpq_add_si', 'mpq_canonicalize',
+        'mpq_cmp', 'mpq_cmp_si', 'mpq_div', 'mpq_div_2exp', 'mpq_free',
+        'mpq_get_den', 'mpq_get_num', 'mpq_get_str', 'mpq_init', 'mpq_init_set',
+        'mpq_init_set_si', 'mpq_init_set_str', 'mpq_init_set_z', 'mpq_inits',
+        'mpq_inv', 'mpq_mul', 'mpq_neg', 'mpq_set', 'mpq_set_si', 'mpq_set_str',
+        'mpq_set_z', 'mpq_sub', 'mpz_abs', 'mpz_add', 'mpz_addmul',
+        'mpz_addmul_ui', 'mpz_addmul_si', 'mpz_add_si', 'mpz_add_ui', 'mpz_and',
+        'mpz_bin_uiui', 'mpz_cdiv_q', 'mpz_cmp', 'mpz_cmp_si', 'mpz_divexact',
+        'mpz_divexact_ui', 'mpz_divisible_p', 'mpz_divisible_ui_p', 'mpz_even',
+        'mpz_fac_ui', 'mpz_factorstring', 'mpz_fdiv_q', 'mpz_fdiv_q_2exp',
+        'mpz_fdiv_q_ui', 'mpz_fdiv_qr', 'mpz_fdiv_r', 'mpz_fdiv_ui',
+        'mpz_fib_ui', 'mpz_fib2_ui', 'mpz_fits_atom', 'mpz_fits_integer',
+        'mpz_free', 'mpz_gcd', 'mpz_gcd_ui', 'mpz_get_atom', 'mpz_get_integer',
+        'mpz_get_short_str', 'mpz_get_str', 'mpz_init', 'mpz_init_set',
+        'mpz_inits', 'mpz_invert', 'mpz_lcm', 'mpz_lcm_ui', 'mpz_max',
+        'mpz_min', 'mpz_mod', 'mpz_mod_ui', 'mpz_mul', 'mpz_mul_2exp',
+        'mpz_mul_d', 'mpz_mul_si', 'mpz_neg', 'mpz_nthroot', 'mpz_odd',
+        'mpz_pollard_rho', 'mpz_pow_ui', 'mpz_powm', 'mpz_powm_ui', 'mpz_prime',
+        'mpz_prime_factors', 'mpz_prime_mr', 'mpz_rand', 'mpz_rand_ui',
+        'mpz_re_compose', 'mpz_remove', 'mpz_scan0', 'mpz_scan1', 'mpz_set',
+        'mpz_set_d', 'mpz_set_si', 'mpz_set_str', 'mpz_set_v', 'mpz_sign',
+        'mpz_sizeinbase', 'mpz_sqrt', 'mpz_sub', 'mpz_sub_si', 'mpz_sub_ui',
+        'mpz_si_sub', 'mpz_tdiv_q_2exp', 'mpz_tdiv_r_2exp', 'mpz_tstbit',
+        'mpz_ui_pow_ui', 'mpz_xor', 'named_dict', 'new_dict', 'new_queue',
+        'new_stack', 'not_bits', 'not_bitsu', 'odd', 'or_all', 'or_allu',
+        'or_bits', 'or_bitsu', 'ord', 'ordinal', 'ordinant',
+        'override_timezone', 'pad', 'pad_head', 'pad_tail', 'parse_date_string',
+        'papply', 'peep', 'peepn', 'peep_dict', 'permute', 'permutes',
+        'platform', 'pop', 'popn', 'pop_dict', 'power', 'pp', 'ppEx', 'ppExf',
+        'ppf', 'ppOpt', 'pq_add', 'pq_destroy', 'pq_empty', 'pq_new', 'pq_peek',
+        'pq_pop', 'pq_pop_data', 'pq_size', 'prepend', 'prime_factors',
+        'printf', 'product', 'proper', 'push', 'pushn', 'putd', 'puts',
+        'queue_empty', 'queue_size', 'rand', 'rand_range', 'reinstate',
+        'remainder', 'remove', 'remove_all', 'repeat', 'repeatch', 'replace',
+        'requires', 'reverse', 'rfind', 'rgb', 'rmatch', 'rmdr', 'rnd', 'round',
+        'routine_id', 'scanf', 'serialize', 'series', 'set_rand',
+        'set_test_abort', 'set_test_logfile', 'set_test_module',
+        'set_test_pause', 'set_test_verbosity', 'set_timedate_formats',
+        'set_timezone', 'setd', 'setd_default', 'shorten', 'sha256',
+        'shift_bits', 'shuffle', 'sign', 'sin', 'smallest', 'sort',
+        'sort_columns', 'speak', 'splice', 'split', 'split_any', 'split_by',
+        'sprint', 'sprintf', 'sq_abs', 'sq_add', 'sq_and', 'sq_and_bits',
+        'sq_arccos', 'sq_arcsin', 'sq_arctan', 'sq_atom', 'sq_ceil', 'sq_cmp',
+        'sq_cos', 'sq_div', 'sq_even', 'sq_eq', 'sq_floor', 'sq_floor_div',
+        'sq_ge', 'sq_gt', 'sq_int', 'sq_le', 'sq_log', 'sq_log10', 'sq_log2',
+        'sq_lt', 'sq_max', 'sq_min', 'sq_mod', 'sq_mul', 'sq_ne', 'sq_not',
+        'sq_not_bits', 'sq_odd', 'sq_or', 'sq_or_bits', 'sq_power', 'sq_rand',
+        'sq_remainder', 'sq_rmdr', 'sq_rnd', 'sq_round', 'sq_seq', 'sq_sign',
+        'sq_sin', 'sq_sqrt', 'sq_str', 'sq_sub', 'sq_tan', 'sq_trunc',
+        'sq_uminus', 'sq_xor', 'sq_xor_bits', 'sqrt', 'square_free',
+        'stack_empty', 'stack_size', 'substitute', 'substitute_all', 'sum',
+        'tail', 'tan', 'test_equal', 'test_fail', 'test_false',
+        'test_not_equal', 'test_pass', 'test_summary', 'test_true',
+        'text_color', 'throw', 'time', 'timedate_diff', 'timedelta',
+        'to_integer', 'to_number', 'to_rgb', 'to_string', 'traverse_dict',
+        'traverse_dict_partial_key', 'trim', 'trim_head', 'trim_tail', 'trunc',
+        'tagset', 'tagstart', 'typeof', 'unique', 'unix_dict', 'upper',
+        'utf8_to_utf32', 'utf32_to_utf8', 'version', 'vlookup', 'vslice',
+        'wglGetProcAddress', 'wildcard_file', 'wildcard_match', 'with_rho',
+        'with_theta', 'xml_new_doc', 'xml_new_element', 'xml_set_attribute',
+        'xml_sprint', 'xor_bits', 'xor_bitsu',
+        'accept', 'allocate', 'allocate_string', 'allow_break', 'ARM',
+        'atom_to_float80', 'c_func', 'c_proc', 'call_back', 'chdir',
+        'check_break', 'clearDib', 'close', 'closesocket', 'console',
+        'copy_file', 'create', 'create_directory', 'create_thread',
+        'curl_easy_cleanup', 'curl_easy_get_file', 'curl_easy_init',
+        'curl_easy_perform', 'curl_easy_perform_ex', 'curl_easy_setopt',
+        'curl_easy_strerror', 'curl_global_cleanup', 'curl_global_init',
+        'curl_slist_append', 'curl_slist_free_all', 'current_dir', 'cursor',
+        'define_c_func', 'define_c_proc', 'delete', 'delete_cs', 'delete_file',
+        'dir', 'DLL', 'drawDib', 'drawShadedPolygonToDib', 'ELF32', 'ELF64',
+        'enter_cs', 'eval', 'exit_thread', 'free', 'file_exists', 'final',
+        'float80_to_atom', 'format', 'get_bytes', 'get_file_date',
+        'get_file_size', 'get_file_type', 'get_interpreter', 'get_key',
+        'get_socket_error', 'get_text', 'get_thread_exitcode', 'get_thread_id',
+        'getc', 'getenv', 'gets', 'getsockaddr', 'glBegin', 'glCallList',
+        'glFrustum', 'glGenLists', 'glGetString', 'glLight', 'glMaterial',
+        'glNewList', 'glNormal', 'glPopMatrix', 'glPushMatrix', 'glRotate',
+        'glEnd', 'glEndList', 'glTexImage2D', 'goto', 'GUI', 'icons', 'ilASM',
+        'include_files', 'include_paths', 'init_cs', 'ip_to_string',
+        'IupConfig', 'IupConfigDialogClosed', 'IupConfigDialogShow',
+        'IupConfigGetVariableInt', 'IupConfigLoad', 'IupConfigSave',
+        'IupConfigSetVariableInt', 'IupExitLoop', 'IupFileDlg', 'IupFileList',
+        'IupGLSwapBuffers', 'IupHelp', 'IupLoopStep', 'IupMainLoop',
+        'IupNormalizer', 'IupPlot', 'IupPlotAdd', 'IupPlotBegin', 'IupPlotEnd',
+        'IupPlotInsert', 'IupSaveImage', 'IupTreeGetUserId', 'IupUser',
+        'IupVersion', 'IupVersionDate', 'IupVersionNumber', 'IupVersionShow',
+        'killDib', 'leave_cs', 'listen', 'manifest', 'mem_copy', 'mem_set',
+        'mpfr_gamma', 'mpfr_printf', 'mpfr_sprintf', 'mpz_export', 'mpz_import',
+        'namespace', 'new', 'newDib', 'open', 'open_dll', 'PE32', 'PE64',
+        'peek', 'peek_string', 'peek1s', 'peek1u', 'peek2s', 'peek2u', 'peek4s',
+        'peek4u', 'peek8s', 'peek8u', 'peekNS', 'peekns', 'peeknu', 'poke',
+        'poke2', 'poke4', 'poke8', 'pokeN', 'poke_string', 'poke_wstring',
+        'position', 'progress', 'prompt_number', 'prompt_string', 'read_file',
+        'read_lines', 'recv', 'resume_thread', 'seek', 'select', 'send',
+        'setHandler', 'shutdown', 'sleep', 'SO', 'sockaddr_in', 'socket',
+        'split_path', 'suspend_thread', 'system', 'system_exec', 'system_open',
+        'system_wait', 'task_clock_start', 'task_clock_stop', 'task_create',
+        'task_delay', 'task_list', 'task_schedule', 'task_self', 'task_status',
+        'task_suspend', 'task_yield', 'thread_safe_string', 'try_cs',
+        'utf8_to_utf16', 'utf16_to_utf8', 'utf16_to_utf32', 'utf32_to_utf16',
+        'video_config', 'WSACleanup', 'wait_thread', 'walk_dir', 'where',
+        'write_lines', 'wait_key'
+    )
+    constants = (
+        'ANY_QUEUE', 'ASCENDING', 'BLACK', 'BLOCK_CURSOR', 'BLUE',
+        'BRIGHT_CYAN', 'BRIGHT_BLUE', 'BRIGHT_GREEN', 'BRIGHT_MAGENTA',
+        'BRIGHT_RED', 'BRIGHT_WHITE', 'BROWN', 'C_DWORD', 'C_INT', 'C_POINTER',
+        'C_USHORT', 'C_WORD', 'CD_AMBER', 'CD_BLACK', 'CD_BLUE', 'CD_BOLD',
+        'CD_BOLD_ITALIC', 'CD_BOX', 'CD_CENTER', 'CD_CIRCLE', 'CD_CLOSED_LINES',
+        'CD_CONTINUOUS', 'CD_CUSTOM', 'CD_CYAN', 'CD_DARK_BLUE', 'CD_DARK_CYAN',
+        'CD_DARK_GRAY', 'CD_DARK_GREY', 'CD_DARK_GREEN', 'CD_DARK_MAGENTA',
+        'CD_DARK_RED', 'CD_DARK_YELLOW', 'CD_DASH_DOT', 'CD_DASH_DOT_DOT',
+        'CD_DASHED', 'CD_DBUFFER', 'CD_DEG2RAD', 'CD_DIAMOND', 'CD_DOTTED',
+        'CD_EAST', 'CD_EVENODD', 'CD_FILL', 'CD_GL', 'CD_GRAY', 'CD_GREY',
+        'CD_GREEN', 'CD_HATCH', 'CD_HOLLOW', 'CD_HOLLOW_BOX',
+        'CD_HOLLOW_CIRCLE', 'CD_HOLLOW_DIAMOND', 'CD_INDIGO', 'CD_ITALIC',
+        'CD_IUP', 'CD_IUPDBUFFER', 'CD_LIGHT_BLUE', 'CD_LIGHT_GRAY',
+        'CD_LIGHT_GREY', 'CD_LIGHT_GREEN', 'CD_LIGHT_PARCHMENT', 'CD_MAGENTA',
+        'CD_NAVY', 'CD_NORTH', 'CD_NORTH_EAST', 'CD_NORTH_WEST', 'CD_OLIVE',
+        'CD_OPEN_LINES', 'CD_ORANGE', 'CD_PARCHMENT', 'CD_PATTERN',
+        'CD_PRINTER', 'CD_PURPLE', 'CD_PLAIN', 'CD_PLUS', 'CD_QUERY',
+        'CD_RAD2DEG', 'CD_RED', 'CD_SILVER', 'CD_SOLID', 'CD_SOUTH_EAST',
+        'CD_SOUTH_WEST', 'CD_STAR', 'CD_STIPPLE', 'CD_STRIKEOUT',
+        'CD_UNDERLINE', 'CD_WEST', 'CD_WHITE', 'CD_WINDING', 'CD_VIOLET',
+        'CD_X', 'CD_YELLOW', 'CURLE_OK', 'CURLOPT_MAIL_FROM',
+        'CURLOPT_MAIL_RCPT', 'CURLOPT_PASSWORD', 'CURLOPT_READDATA',
+        'CURLOPT_READFUNCTION', 'CURLOPT_SSL_VERIFYPEER',
+        'CURLOPT_SSL_VERIFYHOST', 'CURLOPT_UPLOAD', 'CURLOPT_URL',
+        'CURLOPT_USE_SSL', 'CURLOPT_USERNAME', 'CURLOPT_VERBOSE',
+        'CURLOPT_WRITEFUNCTION', 'CURLUSESSL_ALL', 'CYAN', 'D_NAME',
+        'D_ATTRIBUTES', 'D_SIZE', 'D_YEAR', 'D_MONTH', 'D_DAY', 'D_HOUR',
+        'D_MINUTE', 'D_SECOND', 'D_CREATION', 'D_LASTACCESS', 'D_MODIFICATION',
+        'DT_YEAR', 'DT_MONTH', 'DT_DAY', 'DT_HOUR', 'DT_MINUTE', 'DT_SECOND',
+        'DT_DOW', 'DT_MSEC', 'DT_DOY', 'DT_GMT', 'EULER', 'E_CODE', 'E_ADDR',
+        'E_LINE', 'E_RTN', 'E_NAME', 'E_FILE', 'E_PATH', 'E_USER', 'false',
+        'False', 'FALSE', 'FIFO_QUEUE', 'FILETYPE_DIRECTORY', 'FILETYPE_FILE',
+        'GET_EOF', 'GET_FAIL', 'GET_IGNORE', 'GET_SUCCESS',
+        'GL_AMBIENT_AND_DIFFUSE', 'GL_ARRAY_BUFFER', 'GL_CLAMP',
+        'GL_CLAMP_TO_BORDER', 'GL_CLAMP_TO_EDGE', 'GL_COLOR_BUFFER_BIT',
+        'GL_COMPILE', 'GL_COMPILE_STATUS', 'GL_CULL_FACE',
+        'GL_DEPTH_BUFFER_BIT', 'GL_DEPTH_TEST', 'GL_EXTENSIONS', 'GL_FLAT',
+        'GL_FLOAT', 'GL_FRAGMENT_SHADER', 'GL_FRONT', 'GL_LIGHT0',
+        'GL_LIGHTING', 'GL_LINEAR', 'GL_LINK_STATUS', 'GL_MODELVIEW',
+        'GL_NEAREST', 'GL_NO_ERROR', 'GL_NORMALIZE', 'GL_POSITION',
+        'GL_PROJECTION', 'GL_QUAD_STRIP', 'GL_QUADS', 'GL_RENDERER',
+        'GL_REPEAT', 'GL_RGB', 'GL_RGBA', 'GL_SMOOTH', 'GL_STATIC_DRAW',
+        'GL_TEXTURE_2D', 'GL_TEXTURE_MAG_FILTER', 'GL_TEXTURE_MIN_FILTER',
+        'GL_TEXTURE_WRAP_S', 'GL_TEXTURE_WRAP_T', 'GL_TRIANGLES',
+        'GL_UNSIGNED_BYTE', 'GL_VENDOR', 'GL_VERSION', 'GL_VERTEX_SHADER',
+        'GRAY', 'GREEN', 'GT_LF_STRIPPED', 'GT_WHOLE_FILE', 'INVLN10',
+        'IUP_CLOSE', 'IUP_CONTINUE', 'IUP_DEFAULT', 'IUP_BLACK', 'IUP_BLUE',
+        'IUP_BUTTON1', 'IUP_BUTTON3', 'IUP_CENTER', 'IUP_CYAN', 'IUP_DARK_BLUE',
+        'IUP_DARK_CYAN', 'IUP_DARK_GRAY', 'IUP_DARK_GREY', 'IUP_DARK_GREEN',
+        'IUP_DARK_MAGENTA', 'IUP_DARK_RED', 'IUP_GRAY', 'IUP_GREY', 'IUP_GREEN',
+        'IUP_IGNORE', 'IUP_INDIGO', 'IUP_MAGENTA', 'IUP_MASK_INT',
+        'IUP_MASK_UINT', 'IUP_MOUSEPOS', 'IUP_NAVY', 'IUP_OLIVE', 'IUP_RECTEXT',
+        'IUP_RED', 'IUP_LIGHT_BLUE', 'IUP_LIGHT_GRAY', 'IUP_LIGHT_GREY',
+        'IUP_LIGHT_GREEN', 'IUP_ORANGE', 'IUP_PARCHMENT', 'IUP_PURPLE',
+        'IUP_SILVER', 'IUP_TEAL', 'IUP_VIOLET', 'IUP_WHITE', 'IUP_YELLOW',
+        'K_BS', 'K_cA', 'K_cC', 'K_cD', 'K_cF5', 'K_cK', 'K_cM', 'K_cN', 'K_cO',
+        'K_cP', 'K_cR', 'K_cS', 'K_cT', 'K_cW', 'K_CR', 'K_DEL', 'K_DOWN',
+        'K_END', 'K_ESC', 'K_F1', 'K_F2', 'K_F3', 'K_F4', 'K_F5', 'K_F6',
+        'K_F7', 'K_F8', 'K_F9', 'K_F10', 'K_F11', 'K_F12', 'K_HOME', 'K_INS',
+        'K_LEFT', 'K_MIDDLE', 'K_PGDN', 'K_PGUP', 'K_RIGHT', 'K_SP', 'K_TAB',
+        'K_UP', 'K_h', 'K_i', 'K_j', 'K_p', 'K_r', 'K_s', 'JS', 'LIFO_QUEUE',
+        'LINUX', 'MAX_HEAP', 'MAGENTA', 'MIN_HEAP', 'Nan', 'NO_CURSOR', 'null',
+        'NULL', 'PI', 'pp_Ascii', 'pp_Brkt', 'pp_Date', 'pp_File', 'pp_FltFmt',
+        'pp_Indent', 'pp_IntCh', 'pp_IntFmt', 'pp_Maxlen', 'pp_Nest',
+        'pp_Pause', 'pp_Q22', 'pp_StrFmt', 'RED', 'SEEK_OK', 'SLASH',
+        'TEST_ABORT', 'TEST_CRASH', 'TEST_PAUSE', 'TEST_PAUSE_FAIL',
+        'TEST_QUIET', 'TEST_SHOW_ALL', 'TEST_SHOW_FAILED', 'TEST_SUMMARY',
+        'true', 'True', 'TRUE', 'VC_SCRNLINES', 'WHITE', 'WINDOWS', 'YELLOW'
+    )
+
+    tokens = {
+        'root': [
+            (r"\s+", Whitespace),
+            (r'/\*|--/\*|#\[', Comment.Multiline, 'comment'),
+            (r'(?://|--|#!).*$', Comment.Single),
+#Alt:
+#           (r'//.*$|--.*$|#!.*$', Comment.Single),
+            (r'"([^"\\]|\\.)*"', String.Other),
+            (r'\'[^\']*\'', String.Other),
+            (r'`[^`]*`', String.Other),
+
+            (words(types, prefix=r'\b', suffix=r'\b'), Name.Function),
+            (words(routines, prefix=r'\b', suffix=r'\b'), Name.Function),
+            (words(preproc, prefix=r'\b', suffix=r'\b'), Keyword.Declaration),
+            (words(keywords, prefix=r'\b', suffix=r'\b'), Keyword.Declaration),
+            (words(constants, prefix=r'\b', suffix=r'\b'), Name.Constant),
+            # Aside: Phix only supports/uses the ascii/non-unicode tilde
+            (r'!=|==|<<|>>|:=|[-~+/*%=<>&^|\.(){},?:\[\]$\\;#]', Operator),
+            (r'[\w-]+', Text)
+        ],
+        'comment': [
+            (r'[^*/#]+', Comment.Multiline),
+            (r'/\*|#\[', Comment.Multiline, '#push'),
+            (r'\*/|#\]', Comment.Multiline, '#pop'),
+            (r'[*/#]', Comment.Multiline)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/php.py b/.venv/Lib/site-packages/pygments/lexers/php.py
new file mode 100644
index 0000000..82d4aeb
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/php.py
@@ -0,0 +1,334 @@
+"""
+    pygments.lexers.php
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for PHP and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import Lexer, RegexLexer, include, bygroups, default, \
+    using, this, words, do_insertions, line_re
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Other, Generic
+from pygments.util import get_bool_opt, get_list_opt, shebang_matches
+
+__all__ = ['ZephirLexer', 'PsyshConsoleLexer', 'PhpLexer']
+
+
+class ZephirLexer(RegexLexer):
+    """
+    For Zephir language source code.
+
+    Zephir is a compiled high level language aimed
+    to the creation of C-extensions for PHP.
+    """
+
+    name = 'Zephir'
+    url = 'http://zephir-lang.com/'
+    aliases = ['zephir']
+    filenames = ['*.zep']
+    version_added = '2.0'
+
+    zephir_keywords = ['fetch', 'echo', 'isset', 'empty']
+    zephir_type = ['bit', 'bits', 'string']
+
+    flags = re.DOTALL | re.MULTILINE
+
+    tokens = {
+        'commentsandwhitespace': [
+            (r'\s+', Text),
+            (r'//.*?\n', Comment.Single),
+            (r'/\*.*?\*/', Comment.Multiline)
+        ],
+        'slashstartsregex': [
+            include('commentsandwhitespace'),
+            (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
+             r'([gim]+\b|\B)', String.Regex, '#pop'),
+            (r'/', Operator, '#pop'),
+            default('#pop')
+        ],
+        'badregex': [
+            (r'\n', Text, '#pop')
+        ],
+        'root': [
+            (r'^(?=\s|/)', Text, 'slashstartsregex'),
+            include('commentsandwhitespace'),
+            (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|'
+             r'(<<|>>>?|==?|!=?|->|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
+            (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
+            (r'[})\].]', Punctuation),
+            (r'(for|in|while|do|break|return|continue|switch|case|default|if|else|loop|'
+             r'require|inline|throw|try|catch|finally|new|delete|typeof|instanceof|void|'
+             r'namespace|use|extends|this|fetch|isset|unset|echo|fetch|likely|unlikely|'
+             r'empty)\b', Keyword, 'slashstartsregex'),
+            (r'(var|let|with|function)\b', Keyword.Declaration, 'slashstartsregex'),
+            (r'(abstract|boolean|bool|char|class|const|double|enum|export|extends|final|'
+             r'native|goto|implements|import|int|string|interface|long|ulong|char|uchar|'
+             r'float|unsigned|private|protected|public|short|static|self|throws|reverse|'
+             r'transient|volatile|readonly)\b', Keyword.Reserved),
+            (r'(true|false|null|undefined)\b', Keyword.Constant),
+            (r'(Array|Boolean|Date|_REQUEST|_COOKIE|_SESSION|'
+             r'_GET|_POST|_SERVER|this|stdClass|range|count|iterator|'
+             r'window)\b', Name.Builtin),
+            (r'[$a-zA-Z_][\w\\]*', Name.Other),
+            (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'[0-9]+', Number.Integer),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
+        ]
+    }
+
+
+class PsyshConsoleLexer(Lexer):
+    """
+    For PsySH console output, such as:
+
+    .. sourcecode:: psysh
+
+        >>> $greeting = function($name): string {
+        ...     return "Hello, {$name}";
+        ... };
+        => Closure($name): string {#2371 …3}
+        >>> $greeting('World')
+        => "Hello, World"
+    """
+    name = 'PsySH console session for PHP'
+    url = 'https://psysh.org/'
+    aliases = ['psysh']
+    version_added = '2.7'
+
+    def __init__(self, **options):
+        options['startinline'] = True
+        Lexer.__init__(self, **options)
+
+    def get_tokens_unprocessed(self, text):
+        phplexer = PhpLexer(**self.options)
+        curcode = ''
+        insertions = []
+        for match in line_re.finditer(text):
+            line = match.group()
+            if line.startswith('>>> ') or line.startswith('... '):
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt, line[:4])]))
+                curcode += line[4:]
+            elif line.rstrip() == '...':
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt, '...')]))
+                curcode += line[3:]
+            else:
+                if curcode:
+                    yield from do_insertions(
+                        insertions, phplexer.get_tokens_unprocessed(curcode))
+                    curcode = ''
+                    insertions = []
+                yield match.start(), Generic.Output, line
+        if curcode:
+            yield from do_insertions(insertions,
+                                     phplexer.get_tokens_unprocessed(curcode))
+
+
+class PhpLexer(RegexLexer):
+    """
+    For PHP source code.
+    For PHP embedded in HTML, use the `HtmlPhpLexer`.
+
+    Additional options accepted:
+
+    `startinline`
+        If given and ``True`` the lexer starts highlighting with
+        php code (i.e.: no starting ``>> from pygments.lexers._php_builtins import MODULES
+            >>> MODULES.keys()
+            ['PHP Options/Info', 'Zip', 'dba', ...]
+
+        In fact the names of those modules match the module names from
+        the php documentation.
+    """
+
+    name = 'PHP'
+    url = 'https://www.php.net/'
+    aliases = ['php', 'php3', 'php4', 'php5']
+    filenames = ['*.php', '*.php[345]', '*.inc']
+    mimetypes = ['text/x-php']
+    version_added = ''
+
+    # Note that a backslash is included, PHP uses a backslash as a namespace
+    # separator.
+    _ident_inner = r'(?:[\\_a-z]|[^\x00-\x7f])(?:[\\\w]|[^\x00-\x7f])*'
+    # But not inside strings.
+    _ident_nons = r'(?:[_a-z]|[^\x00-\x7f])(?:\w|[^\x00-\x7f])*'
+
+    flags = re.IGNORECASE | re.DOTALL | re.MULTILINE
+    tokens = {
+        'root': [
+            (r'<\?(php)?', Comment.Preproc, 'php'),
+            (r'[^<]+', Other),
+            (r'<', Other)
+        ],
+        'php': [
+            (r'\?>', Comment.Preproc, '#pop'),
+            (r'(<<<)([\'"]?)(' + _ident_nons + r')(\2\n.*?\n\s*)(\3)(;?)(\n)',
+             bygroups(String, String, String.Delimiter, String, String.Delimiter,
+                      Punctuation, Text)),
+            (r'\s+', Text),
+            (r'#\[', Punctuation, 'attribute'),
+            (r'#.*?\n', Comment.Single),
+            (r'//.*?\n', Comment.Single),
+            # put the empty comment here, it is otherwise seen as
+            # the start of a docstring
+            (r'/\*\*/', Comment.Multiline),
+            (r'/\*\*.*?\*/', String.Doc),
+            (r'/\*.*?\*/', Comment.Multiline),
+            (r'(->|::)(\s*)(' + _ident_nons + ')',
+             bygroups(Operator, Text, Name.Attribute)),
+            (r'[~!%^&*+=|:.<>/@-]+', Operator),
+            (r'\?', Operator),  # don't add to the charclass above!
+            (r'[\[\]{}();,]+', Punctuation),
+            (r'(new)(\s+)(class)\b', bygroups(Keyword, Text, Keyword)),
+            (r'(class)(\s+)', bygroups(Keyword, Text), 'classname'),
+            (r'(function)(\s*)(?=\()', bygroups(Keyword, Text)),
+            (r'(function)(\s+)(&?)(\s*)',
+             bygroups(Keyword, Text, Operator, Text), 'functionname'),
+            (r'(const)(\s+)(' + _ident_inner + ')',
+             bygroups(Keyword, Text, Name.Constant)),
+            (r'(and|E_PARSE|old_function|E_ERROR|or|as|E_WARNING|parent|'
+             r'eval|PHP_OS|break|exit|case|extends|PHP_VERSION|cfunction|'
+             r'FALSE|print|for|require|continue|foreach|require_once|'
+             r'declare|return|default|static|do|switch|die|stdClass|'
+             r'echo|else|TRUE|elseif|var|empty|if|xor|enddeclare|include|'
+             r'virtual|endfor|include_once|while|endforeach|global|'
+             r'endif|list|endswitch|new|endwhile|not|'
+             r'array|E_ALL|NULL|final|php_user_filter|interface|'
+             r'implements|public|private|protected|abstract|clone|try|'
+             r'catch|throw|this|use|namespace|trait|yield|'
+             r'finally|match)\b', Keyword),
+            (r'(true|false|null)\b', Keyword.Constant),
+            include('magicconstants'),
+            (r'\$\{', Name.Variable, 'variablevariable'),
+            (r'\$+' + _ident_inner, Name.Variable),
+            (_ident_inner, Name.Other),
+            (r'(\d+\.\d*|\d*\.\d+)(e[+-]?[0-9]+)?', Number.Float),
+            (r'\d+e[+-]?[0-9]+', Number.Float),
+            (r'0[0-7]+', Number.Oct),
+            (r'0x[a-f0-9]+', Number.Hex),
+            (r'\d+', Number.Integer),
+            (r'0b[01]+', Number.Bin),
+            (r"'([^'\\]*(?:\\.[^'\\]*)*)'", String.Single),
+            (r'`([^`\\]*(?:\\.[^`\\]*)*)`', String.Backtick),
+            (r'"', String.Double, 'string'),
+        ],
+        'variablevariable': [
+            (r'\}', Name.Variable, '#pop'),
+            include('php')
+        ],
+        'magicfuncs': [
+            # source: http://php.net/manual/en/language.oop5.magic.php
+            (words((
+                '__construct', '__destruct', '__call', '__callStatic', '__get', '__set',
+                '__isset', '__unset', '__sleep', '__wakeup', '__toString', '__invoke',
+                '__set_state', '__clone', '__debugInfo',), suffix=r'\b'),
+             Name.Function.Magic),
+        ],
+        'magicconstants': [
+            # source: http://php.net/manual/en/language.constants.predefined.php
+            (words((
+                '__LINE__', '__FILE__', '__DIR__', '__FUNCTION__', '__CLASS__',
+                '__TRAIT__', '__METHOD__', '__NAMESPACE__',),
+                suffix=r'\b'),
+             Name.Constant),
+        ],
+        'classname': [
+            (_ident_inner, Name.Class, '#pop')
+        ],
+        'functionname': [
+            include('magicfuncs'),
+            (_ident_inner, Name.Function, '#pop'),
+            default('#pop')
+        ],
+        'string': [
+            (r'"', String.Double, '#pop'),
+            (r'[^{$"\\]+', String.Double),
+            (r'\\([nrt"$\\]|[0-7]{1,3}|x[0-9a-f]{1,2})', String.Escape),
+            (r'\$' + _ident_nons + r'(\[\S+?\]|->' + _ident_nons + ')?',
+             String.Interpol),
+            (r'(\{\$\{)(.*?)(\}\})',
+             bygroups(String.Interpol, using(this, _startinline=True),
+                      String.Interpol)),
+            (r'(\{)(\$.*?)(\})',
+             bygroups(String.Interpol, using(this, _startinline=True),
+                      String.Interpol)),
+            (r'(\$\{)(\S+)(\})',
+             bygroups(String.Interpol, Name.Variable, String.Interpol)),
+            (r'[${\\]', String.Double)
+        ],
+        'attribute': [
+            (r'\]', Punctuation, '#pop'),
+            (r'\(', Punctuation, 'attributeparams'),
+            (_ident_inner, Name.Decorator),
+            include('php')
+        ],
+        'attributeparams': [
+            (r'\)', Punctuation, '#pop'),
+            include('php')
+        ],
+    }
+
+    def __init__(self, **options):
+        self.funcnamehighlighting = get_bool_opt(
+            options, 'funcnamehighlighting', True)
+        self.disabledmodules = get_list_opt(
+            options, 'disabledmodules', ['unknown'])
+        self.startinline = get_bool_opt(options, 'startinline', False)
+
+        # private option argument for the lexer itself
+        if '_startinline' in options:
+            self.startinline = options.pop('_startinline')
+
+        # collect activated functions in a set
+        self._functions = set()
+        if self.funcnamehighlighting:
+            from pygments.lexers._php_builtins import MODULES
+            for key, value in MODULES.items():
+                if key not in self.disabledmodules:
+                    self._functions.update(value)
+        RegexLexer.__init__(self, **options)
+
+    def get_tokens_unprocessed(self, text):
+        stack = ['root']
+        if self.startinline:
+            stack.append('php')
+        for index, token, value in \
+                RegexLexer.get_tokens_unprocessed(self, text, stack):
+            if token is Name.Other:
+                if value in self._functions:
+                    yield index, Name.Builtin, value
+                    continue
+            yield index, token, value
+
+    def analyse_text(text):
+        if shebang_matches(text, r'php'):
+            return True
+        rv = 0.0
+        if re.search(r'<\?(?!xml)', text):
+            rv += 0.3
+        return rv
diff --git a/.venv/Lib/site-packages/pygments/lexers/pointless.py b/.venv/Lib/site-packages/pygments/lexers/pointless.py
new file mode 100644
index 0000000..adedb75
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/pointless.py
@@ -0,0 +1,70 @@
+"""
+    pygments.lexers.pointless
+    ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Pointless.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words
+from pygments.token import Comment, Error, Keyword, Name, Number, Operator, \
+    Punctuation, String, Text
+
+__all__ = ['PointlessLexer']
+
+
+class PointlessLexer(RegexLexer):
+    """
+    For Pointless source code.
+    """
+
+    name = 'Pointless'
+    url = 'https://ptls.dev'
+    aliases = ['pointless']
+    filenames = ['*.ptls']
+    version_added = '2.7'
+
+    ops = words([
+        "+", "-", "*", "/", "**", "%", "+=", "-=", "*=",
+        "/=", "**=", "%=", "|>", "=", "==", "!=", "<", ">",
+        "<=", ">=", "=>", "$", "++",
+    ])
+
+    keywords = words([
+        "if", "then", "else", "where", "with", "cond",
+        "case", "and", "or", "not", "in", "as", "for",
+        "requires", "throw", "try", "catch", "when",
+        "yield", "upval",
+    ], suffix=r'\b')
+
+    tokens = {
+        'root': [
+            (r'[ \n\r]+', Text),
+            (r'--.*$', Comment.Single),
+            (r'"""', String, 'multiString'),
+            (r'"', String, 'string'),
+            (r'[\[\](){}:;,.]', Punctuation),
+            (ops, Operator),
+            (keywords, Keyword),
+            (r'\d+|\d*\.\d+', Number),
+            (r'(true|false)\b', Name.Builtin),
+            (r'[A-Z][a-zA-Z0-9]*\b', String.Symbol),
+            (r'output\b', Name.Variable.Magic),
+            (r'(export|import)\b', Keyword.Namespace),
+            (r'[a-z][a-zA-Z0-9]*\b', Name.Variable)
+        ],
+        'multiString': [
+            (r'\\.', String.Escape),
+            (r'"""', String, '#pop'),
+            (r'"', String),
+            (r'[^\\"]+', String),
+        ],
+        'string': [
+            (r'\\.', String.Escape),
+            (r'"', String, '#pop'),
+            (r'\n', Error),
+            (r'[^\\"]+', String),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/pony.py b/.venv/Lib/site-packages/pygments/lexers/pony.py
new file mode 100644
index 0000000..055423a
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/pony.py
@@ -0,0 +1,93 @@
+"""
+    pygments.lexers.pony
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Pony and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['PonyLexer']
+
+
+class PonyLexer(RegexLexer):
+    """
+    For Pony source code.
+    """
+
+    name = 'Pony'
+    aliases = ['pony']
+    filenames = ['*.pony']
+    url = 'https://www.ponylang.io'
+    version_added = '2.4'
+
+    _caps = r'(iso|trn|ref|val|box|tag)'
+
+    tokens = {
+        'root': [
+            (r'\n', Text),
+            (r'[^\S\n]+', Text),
+            (r'//.*\n', Comment.Single),
+            (r'/\*', Comment.Multiline, 'nested_comment'),
+            (r'"""(?:.|\n)*?"""', String.Doc),
+            (r'"', String, 'string'),
+            (r'\'.*\'', String.Char),
+            (r'=>|[]{}:().~;,|&!^?[]', Punctuation),
+            (words((
+                'addressof', 'and', 'as', 'consume', 'digestof', 'is', 'isnt',
+                'not', 'or'),
+                suffix=r'\b'),
+             Operator.Word),
+            (r'!=|==|<<|>>|[-+/*%=<>]', Operator),
+            (words((
+                'box', 'break', 'compile_error', 'compile_intrinsic',
+                'continue', 'do', 'else', 'elseif', 'embed', 'end', 'error',
+                'for', 'if', 'ifdef', 'in', 'iso', 'lambda', 'let', 'match',
+                'object', 'recover', 'ref', 'repeat', 'return', 'tag', 'then',
+                'this', 'trn', 'try', 'until', 'use', 'var', 'val', 'where',
+                'while', 'with', '#any', '#read', '#send', '#share'),
+                suffix=r'\b'),
+             Keyword),
+            (r'(actor|class|struct|primitive|interface|trait|type)((?:\s)+)',
+             bygroups(Keyword, Text), 'typename'),
+            (r'(new|fun|be)((?:\s)+)', bygroups(Keyword, Text), 'methodname'),
+            (words((
+                'I8', 'U8', 'I16', 'U16', 'I32', 'U32', 'I64', 'U64', 'I128',
+                'U128', 'ILong', 'ULong', 'ISize', 'USize', 'F32', 'F64',
+                'Bool', 'Pointer', 'None', 'Any', 'Array', 'String',
+                'Iterator'),
+                suffix=r'\b'),
+             Name.Builtin.Type),
+            (r'_?[A-Z]\w*', Name.Type),
+            (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+', Number.Float),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'\d+', Number.Integer),
+            (r'(true|false)\b', Name.Builtin),
+            (r'_\d*', Name),
+            (r'_?[a-z][\w\']*', Name)
+        ],
+        'typename': [
+            (_caps + r'?((?:\s)*)(_?[A-Z]\w*)',
+             bygroups(Keyword, Text, Name.Class), '#pop')
+        ],
+        'methodname': [
+            (_caps + r'?((?:\s)*)(_?[a-z]\w*)',
+             bygroups(Keyword, Text, Name.Function), '#pop')
+        ],
+        'nested_comment': [
+            (r'[^*/]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[*/]', Comment.Multiline)
+        ],
+        'string': [
+            (r'"', String, '#pop'),
+            (r'\\"', String),
+            (r'[^\\"]+', String)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/praat.py b/.venv/Lib/site-packages/pygments/lexers/praat.py
new file mode 100644
index 0000000..054f5b6
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/praat.py
@@ -0,0 +1,303 @@
+"""
+    pygments.lexers.praat
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Praat
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words, bygroups, include
+from pygments.token import Name, Text, Comment, Keyword, String, Punctuation, \
+    Number, Operator, Whitespace
+
+__all__ = ['PraatLexer']
+
+
+class PraatLexer(RegexLexer):
+    """
+    For Praat scripts.
+    """
+
+    name = 'Praat'
+    url = 'http://www.praat.org'
+    aliases = ['praat']
+    filenames = ['*.praat', '*.proc', '*.psc']
+    version_added = '2.1'
+
+    keywords = (
+        'if', 'then', 'else', 'elsif', 'elif', 'endif', 'fi', 'for', 'from', 'to',
+        'endfor', 'endproc', 'while', 'endwhile', 'repeat', 'until', 'select', 'plus',
+        'minus', 'demo', 'assert', 'stopwatch', 'nocheck', 'nowarn', 'noprogress',
+        'editor', 'endeditor', 'clearinfo',
+    )
+
+    functions_string = (
+        'backslashTrigraphsToUnicode', 'chooseDirectory', 'chooseReadFile',
+        'chooseWriteFile', 'date', 'demoKey', 'do', 'environment', 'extractLine',
+        'extractWord', 'fixed', 'info', 'left', 'mid', 'percent', 'readFile', 'replace',
+        'replace_regex', 'right', 'selected', 'string', 'unicodeToBackslashTrigraphs',
+    )
+
+    functions_numeric = (
+        'abs', 'appendFile', 'appendFileLine', 'appendInfo', 'appendInfoLine', 'arccos',
+        'arccosh', 'arcsin', 'arcsinh', 'arctan', 'arctan2', 'arctanh', 'barkToHertz',
+        'beginPause', 'beginSendPraat', 'besselI', 'besselK', 'beta', 'beta2',
+        'binomialP', 'binomialQ', 'boolean', 'ceiling', 'chiSquareP', 'chiSquareQ',
+        'choice', 'comment', 'cos', 'cosh', 'createDirectory', 'deleteFile',
+        'demoClicked', 'demoClickedIn', 'demoCommandKeyPressed',
+        'demoExtraControlKeyPressed', 'demoInput', 'demoKeyPressed',
+        'demoOptionKeyPressed', 'demoShiftKeyPressed', 'demoShow', 'demoWaitForInput',
+        'demoWindowTitle', 'demoX', 'demoY', 'differenceLimensToPhon', 'do', 'editor',
+        'endPause', 'endSendPraat', 'endsWith', 'erb', 'erbToHertz', 'erf', 'erfc',
+        'exitScript', 'exp', 'extractNumber', 'fileReadable', 'fisherP', 'fisherQ',
+        'floor', 'gaussP', 'gaussQ', 'hertzToBark', 'hertzToErb', 'hertzToMel',
+        'hertzToSemitones', 'imax', 'imin', 'incompleteBeta', 'incompleteGammaP', 'index',
+        'index_regex', 'integer', 'invBinomialP', 'invBinomialQ', 'invChiSquareQ', 'invFisherQ',
+        'invGaussQ', 'invSigmoid', 'invStudentQ', 'length', 'ln', 'lnBeta', 'lnGamma',
+        'log10', 'log2', 'max', 'melToHertz', 'min', 'minusObject', 'natural', 'number',
+        'numberOfColumns', 'numberOfRows', 'numberOfSelected', 'objectsAreIdentical',
+        'option', 'optionMenu', 'pauseScript', 'phonToDifferenceLimens', 'plusObject',
+        'positive', 'randomBinomial', 'randomGauss', 'randomInteger', 'randomPoisson',
+        'randomUniform', 'real', 'readFile', 'removeObject', 'rindex', 'rindex_regex',
+        'round', 'runScript', 'runSystem', 'runSystem_nocheck', 'selectObject',
+        'selected', 'semitonesToHertz', 'sentence', 'sentencetext', 'sigmoid', 'sin', 'sinc',
+        'sincpi', 'sinh', 'soundPressureToPhon', 'sqrt', 'startsWith', 'studentP',
+        'studentQ', 'tan', 'tanh', 'text', 'variableExists', 'word', 'writeFile', 'writeFileLine',
+        'writeInfo', 'writeInfoLine',
+    )
+
+    functions_array = (
+        'linear', 'randomGauss', 'randomInteger', 'randomUniform', 'zero',
+    )
+
+    objects = (
+        'Activation', 'AffineTransform', 'AmplitudeTier', 'Art', 'Artword',
+        'Autosegment', 'BarkFilter', 'BarkSpectrogram', 'CCA', 'Categories',
+        'Cepstrogram', 'Cepstrum', 'Cepstrumc', 'ChebyshevSeries', 'ClassificationTable',
+        'Cochleagram', 'Collection', 'ComplexSpectrogram', 'Configuration', 'Confusion',
+        'ContingencyTable', 'Corpus', 'Correlation', 'Covariance',
+        'CrossCorrelationTable', 'CrossCorrelationTables', 'DTW', 'DataModeler',
+        'Diagonalizer', 'Discriminant', 'Dissimilarity', 'Distance', 'Distributions',
+        'DurationTier', 'EEG', 'ERP', 'ERPTier', 'EditCostsTable', 'EditDistanceTable',
+        'Eigen', 'Excitation', 'Excitations', 'ExperimentMFC', 'FFNet', 'FeatureWeights',
+        'FileInMemory', 'FilesInMemory', 'Formant', 'FormantFilter', 'FormantGrid',
+        'FormantModeler', 'FormantPoint', 'FormantTier', 'GaussianMixture', 'HMM',
+        'HMM_Observation', 'HMM_ObservationSequence', 'HMM_State', 'HMM_StateSequence',
+        'Harmonicity', 'ISpline', 'Index', 'Intensity', 'IntensityTier', 'IntervalTier',
+        'KNN', 'KlattGrid', 'KlattTable', 'LFCC', 'LPC', 'Label', 'LegendreSeries',
+        'LinearRegression', 'LogisticRegression', 'LongSound', 'Ltas', 'MFCC', 'MSpline',
+        'ManPages', 'Manipulation', 'Matrix', 'MelFilter', 'MelSpectrogram',
+        'MixingMatrix', 'Movie', 'Network', 'Object', 'OTGrammar', 'OTHistory', 'OTMulti',
+        'PCA', 'PairDistribution', 'ParamCurve', 'Pattern', 'Permutation', 'Photo',
+        'Pitch', 'PitchModeler', 'PitchTier', 'PointProcess', 'Polygon', 'Polynomial',
+        'PowerCepstrogram', 'PowerCepstrum', 'Procrustes', 'RealPoint', 'RealTier',
+        'ResultsMFC', 'Roots', 'SPINET', 'SSCP', 'SVD', 'Salience', 'ScalarProduct',
+        'Similarity', 'SimpleString', 'SortedSetOfString', 'Sound', 'Speaker',
+        'Spectrogram', 'Spectrum', 'SpectrumTier', 'SpeechSynthesizer', 'SpellingChecker',
+        'Strings', 'StringsIndex', 'Table', 'TableOfReal', 'TextGrid', 'TextInterval',
+        'TextPoint', 'TextTier', 'Tier', 'Transition', 'VocalTract', 'VocalTractTier',
+        'Weight', 'WordList',
+    )
+
+    variables_numeric = (
+        'macintosh', 'windows', 'unix', 'praatVersion', 'pi', 'e', 'undefined',
+    )
+
+    variables_string = (
+        'praatVersion', 'tab', 'shellDirectory', 'homeDirectory',
+        'preferencesDirectory', 'newline', 'temporaryDirectory',
+        'defaultDirectory',
+    )
+
+    object_attributes = (
+        'ncol', 'nrow', 'xmin', 'ymin', 'xmax', 'ymax', 'nx', 'ny', 'dx', 'dy',
+    )
+
+    tokens = {
+        'root': [
+            (r'(\s+)(#.*?$)',  bygroups(Whitespace, Comment.Single)),
+            (r'^#.*?$',        Comment.Single),
+            (r';[^\n]*',       Comment.Single),
+            (r'\s+',           Whitespace),
+
+            (r'\bprocedure\b', Keyword,       'procedure_definition'),
+            (r'\bcall\b',      Keyword,       'procedure_call'),
+            (r'@',             Name.Function, 'procedure_call'),
+
+            include('function_call'),
+
+            (words(keywords, suffix=r'\b'), Keyword),
+
+            (r'(\bform\b)(\s+)([^\n]+)',
+             bygroups(Keyword, Whitespace, String), 'old_form'),
+
+            (r'(print(?:line|tab)?|echo|exit|asserterror|pause|send(?:praat|socket)|'
+             r'include|execute|system(?:_nocheck)?)(\s+)',
+             bygroups(Keyword, Whitespace), 'string_unquoted'),
+
+            (r'(goto|label)(\s+)(\w+)', bygroups(Keyword, Whitespace, Name.Label)),
+
+            include('variable_name'),
+            include('number'),
+
+            (r'"', String, 'string'),
+
+            (words((objects), suffix=r'(?=\s+\S+\n)'), Name.Class, 'string_unquoted'),
+
+            (r'\b[A-Z]', Keyword, 'command'),
+            (r'(\.{3}|[)(,])', Punctuation),
+        ],
+        'command': [
+            (r'( ?[\w()-]+ ?)', Keyword),
+
+            include('string_interpolated'),
+
+            (r'\.{3}', Keyword, ('#pop', 'old_arguments')),
+            (r':', Keyword, ('#pop', 'comma_list')),
+            (r'\s', Whitespace, '#pop'),
+        ],
+        'procedure_call': [
+            (r'\s+', Whitespace),
+            (r'([\w.]+)(?:(:)|(?:(\s*)(\()))',
+             bygroups(Name.Function, Punctuation,
+                      Text.Whitespace, Punctuation), '#pop'),
+            (r'([\w.]+)', Name.Function, ('#pop', 'old_arguments')),
+        ],
+        'procedure_definition': [
+            (r'\s', Whitespace),
+            (r'([\w.]+)(\s*?[(:])',
+             bygroups(Name.Function, Whitespace), '#pop'),
+            (r'([\w.]+)([^\n]*)',
+             bygroups(Name.Function, Text), '#pop'),
+        ],
+        'function_call': [
+            (words(functions_string, suffix=r'\$(?=\s*[:(])'), Name.Function, 'function'),
+            (words(functions_array, suffix=r'#(?=\s*[:(])'),   Name.Function, 'function'),
+            (words(functions_numeric, suffix=r'(?=\s*[:(])'),  Name.Function, 'function'),
+        ],
+        'function': [
+            (r'\s+',   Whitespace),
+            (r':',     Punctuation, ('#pop', 'comma_list')),
+            (r'\s*\(', Punctuation, ('#pop', 'comma_list')),
+        ],
+        'comma_list': [
+            (r'(\s*\n\s*)(\.{3})', bygroups(Whitespace, Punctuation)),
+
+            (r'(\s*)(?:([)\]])|(\n))', bygroups(
+                Whitespace, Punctuation, Whitespace), '#pop'),
+
+            (r'\s+', Whitespace),
+            (r'"',   String, 'string'),
+            (r'\b(if|then|else|fi|endif)\b', Keyword),
+
+            include('function_call'),
+            include('variable_name'),
+            include('operator'),
+            include('number'),
+
+            (r'[()]', Text),
+            (r',', Punctuation),
+        ],
+        'old_arguments': [
+            (r'\n', Whitespace, '#pop'),
+
+            include('variable_name'),
+            include('operator'),
+            include('number'),
+
+            (r'"', String, 'string'),
+            (r'[^\n]', Text),
+        ],
+        'number': [
+            (r'\n', Whitespace, '#pop'),
+            (r'\b\d+(\.\d*)?([eE][-+]?\d+)?%?', Number),
+        ],
+        'object_reference': [
+            include('string_interpolated'),
+            (r'([a-z][a-zA-Z0-9_]*|\d+)', Name.Builtin),
+
+            (words(object_attributes, prefix=r'\.'), Name.Builtin, '#pop'),
+
+            (r'\$', Name.Builtin),
+            (r'\[', Text, '#pop'),
+        ],
+        'variable_name': [
+            include('operator'),
+            include('number'),
+
+            (words(variables_string,  suffix=r'\$'), Name.Variable.Global),
+            (words(variables_numeric,
+             suffix=r'(?=[^a-zA-Z0-9_."\'$#\[:(]|\s|^|$)'),
+             Name.Variable.Global),
+
+            (words(objects, prefix=r'\b', suffix=r"(_)"),
+             bygroups(Name.Builtin, Name.Builtin),
+             'object_reference'),
+
+            (r'\.?_?[a-z][\w.]*(\$|#)?', Text),
+            (r'[\[\]]', Punctuation, 'comma_list'),
+
+            include('string_interpolated'),
+        ],
+        'operator': [
+            (r'([+\/*<>=!-]=?|[&*|][&*|]?|\^|<>)',       Operator),
+            (r'(?', Punctuation),
+            (r'"(?:\\x[0-9a-fA-F]+\\|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|'
+             r'\\[0-7]+\\|\\["\\abcefnrstv]|[^\\"])*"', String.Double),
+            (r"'(?:''|[^'])*'", String.Atom),  # quoted atom
+            # Needs to not be followed by an atom.
+            # (r'=(?=\s|[a-zA-Z\[])', Operator),
+            (r'is\b', Operator),
+            (r'(<|>|=<|>=|==|=:=|=|/|//|\*|\+|-)(?=\s|[a-zA-Z0-9\[])',
+             Operator),
+            (r'(mod|div|not)\b', Operator),
+            (r'_', Keyword),  # The don't-care variable
+            (r'([a-z]+)(:)', bygroups(Name.Namespace, Punctuation)),
+            (r'([a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]'
+             r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*)'
+             r'(\s*)(:-|-->)',
+             bygroups(Name.Function, Text, Operator)),  # function defn
+            (r'([a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]'
+             r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*)'
+             r'(\s*)(\()',
+             bygroups(Name.Function, Text, Punctuation)),
+            (r'[a-z\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]'
+             r'[\w$\u00c0-\u1fff\u3040-\ud7ff\ue000-\uffef]*',
+             String.Atom),  # atom, characters
+            # This one includes !
+            (r'[#&*+\-./:<=>?@\\^~\u00a1-\u00bf\u2010-\u303f]+',
+             String.Atom),  # atom, graphics
+            (r'[A-Z_]\w*', Name.Variable),
+            (r'\s+|[\u2000-\u200f\ufff0-\ufffe\uffef]', Text),
+        ],
+        'nested-comment': [
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'[^*/]+', Comment.Multiline),
+            (r'[*/]', Comment.Multiline),
+        ],
+    }
+
+    def analyse_text(text):
+        """Competes with IDL and Visual Prolog on *.pro"""
+        if ':-' in text:
+            # Visual Prolog also uses :-
+            return 0.5
+        else:
+            return 0
+
+
+class LogtalkLexer(RegexLexer):
+    """
+    For Logtalk source code.
+    """
+
+    name = 'Logtalk'
+    url = 'http://logtalk.org/'
+    aliases = ['logtalk']
+    filenames = ['*.lgt', '*.logtalk']
+    mimetypes = ['text/x-logtalk']
+    version_added = '0.10'
+
+    tokens = {
+        'root': [
+            # Directives
+            (r'^\s*:-\s', Punctuation, 'directive'),
+            # Comments
+            (r'%.*?\n', Comment),
+            (r'/\*(.|\n)*?\*/', Comment),
+            # Whitespace
+            (r'\n', Text),
+            (r'\s+', Text),
+            # Numbers
+            (r"0'[\\]?.", Number),
+            (r'0b[01]+', Number.Bin),
+            (r'0o[0-7]+', Number.Oct),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'\d+\.?\d*((e|E)(\+|-)?\d+)?', Number),
+            # Variables
+            (r'([A-Z_][a-zA-Z0-9_]*)', Name.Variable),
+            # Event handlers
+            (r'(after|before)(?=[(])', Keyword),
+            # Message forwarding handler
+            (r'forward(?=[(])', Keyword),
+            # Execution-context methods
+            (r'(context|parameter|this|se(lf|nder))(?=[(])', Keyword),
+            # Reflection
+            (r'(current_predicate|predicate_property)(?=[(])', Keyword),
+            # DCGs and term expansion
+            (r'(expand_(goal|term)|(goal|term)_expansion|phrase)(?=[(])', Keyword),
+            # Entity
+            (r'(abolish|c(reate|urrent))_(object|protocol|category)(?=[(])', Keyword),
+            (r'(object|protocol|category)_property(?=[(])', Keyword),
+            # Entity relations
+            (r'co(mplements_object|nforms_to_protocol)(?=[(])', Keyword),
+            (r'extends_(object|protocol|category)(?=[(])', Keyword),
+            (r'imp(lements_protocol|orts_category)(?=[(])', Keyword),
+            (r'(instantiat|specializ)es_class(?=[(])', Keyword),
+            # Events
+            (r'(current_event|(abolish|define)_events)(?=[(])', Keyword),
+            # Flags
+            (r'(create|current|set)_logtalk_flag(?=[(])', Keyword),
+            # Compiling, loading, and library paths
+            (r'logtalk_(compile|l(ibrary_path|oad|oad_context)|make(_target_action)?)(?=[(])', Keyword),
+            (r'\blogtalk_make\b', Keyword),
+            # Database
+            (r'(clause|retract(all)?)(?=[(])', Keyword),
+            (r'a(bolish|ssert(a|z))(?=[(])', Keyword),
+            # Control constructs
+            (r'(ca(ll|tch)|throw)(?=[(])', Keyword),
+            (r'(fa(il|lse)|true|(instantiation|system)_error)\b', Keyword),
+            (r'(uninstantiation|type|domain|existence|permission|representation|evaluation|resource|syntax)_error(?=[(])', Keyword),
+            # All solutions
+            (r'((bag|set)of|f(ind|or)all)(?=[(])', Keyword),
+            # Multi-threading predicates
+            (r'threaded(_(ca(ll|ncel)|once|ignore|exit|peek|wait|notify))?(?=[(])', Keyword),
+            # Engine predicates
+            (r'threaded_engine(_(create|destroy|self|next|next_reified|yield|post|fetch))?(?=[(])', Keyword),
+            # Term unification
+            (r'(subsumes_term|unify_with_occurs_check)(?=[(])', Keyword),
+            # Term creation and decomposition
+            (r'(functor|arg|copy_term|numbervars|term_variables)(?=[(])', Keyword),
+            # Evaluable functors
+            (r'(div|rem|m(ax|in|od)|abs|sign)(?=[(])', Keyword),
+            (r'float(_(integer|fractional)_part)?(?=[(])', Keyword),
+            (r'(floor|t(an|runcate)|round|ceiling)(?=[(])', Keyword),
+            # Other arithmetic functors
+            (r'(cos|a(cos|sin|tan|tan2)|exp|log|s(in|qrt)|xor)(?=[(])', Keyword),
+            # Term testing
+            (r'(var|atom(ic)?|integer|float|c(allable|ompound)|n(onvar|umber)|ground|acyclic_term)(?=[(])', Keyword),
+            # Term comparison
+            (r'compare(?=[(])', Keyword),
+            # Stream selection and control
+            (r'(curren|se)t_(in|out)put(?=[(])', Keyword),
+            (r'(open|close)(?=[(])', Keyword),
+            (r'flush_output(?=[(])', Keyword),
+            (r'(at_end_of_stream|flush_output)\b', Keyword),
+            (r'(stream_property|at_end_of_stream|set_stream_position)(?=[(])', Keyword),
+            # Character and byte input/output
+            (r'(nl|(get|peek|put)_(byte|c(har|ode)))(?=[(])', Keyword),
+            (r'\bnl\b', Keyword),
+            # Term input/output
+            (r'read(_term)?(?=[(])', Keyword),
+            (r'write(q|_(canonical|term))?(?=[(])', Keyword),
+            (r'(current_)?op(?=[(])', Keyword),
+            (r'(current_)?char_conversion(?=[(])', Keyword),
+            # Atomic term processing
+            (r'atom_(length|c(hars|o(ncat|des)))(?=[(])', Keyword),
+            (r'(char_code|sub_atom)(?=[(])', Keyword),
+            (r'number_c(har|ode)s(?=[(])', Keyword),
+            # Implementation defined hooks functions
+            (r'(se|curren)t_prolog_flag(?=[(])', Keyword),
+            (r'\bhalt\b', Keyword),
+            (r'halt(?=[(])', Keyword),
+            # Message sending operators
+            (r'(::|:|\^\^)', Operator),
+            # External call
+            (r'[{}]', Keyword),
+            # Logic and control
+            (r'(ignore|once)(?=[(])', Keyword),
+            (r'\brepeat\b', Keyword),
+            # Sorting
+            (r'(key)?sort(?=[(])', Keyword),
+            # Bitwise functors
+            (r'(>>|<<|/\\|\\\\|\\)', Operator),
+            # Predicate aliases
+            (r'\bas\b', Operator),
+            # Arithmetic evaluation
+            (r'\bis\b', Keyword),
+            # Arithmetic comparison
+            (r'(=:=|=\\=|<|=<|>=|>)', Operator),
+            # Term creation and decomposition
+            (r'=\.\.', Operator),
+            # Term unification
+            (r'(=|\\=)', Operator),
+            # Term comparison
+            (r'(==|\\==|@=<|@<|@>=|@>)', Operator),
+            # Evaluable functors
+            (r'(//|[-+*/])', Operator),
+            (r'\b(e|pi|div|mod|rem)\b', Operator),
+            # Other arithmetic functors
+            (r'\b\*\*\b', Operator),
+            # DCG rules
+            (r'-->', Operator),
+            # Control constructs
+            (r'([!;]|->)', Operator),
+            # Logic and control
+            (r'\\+', Operator),
+            # Mode operators
+            (r'[?@]', Operator),
+            # Existential quantifier
+            (r'\^', Operator),
+            # Punctuation
+            (r'[()\[\],.|]', Text),
+            # Atoms
+            (r"[a-z][a-zA-Z0-9_]*", Text),
+            (r"'", String, 'quoted_atom'),
+            # Double-quoted terms
+            (r'"', String, 'double_quoted_term'),
+        ],
+
+        'quoted_atom': [
+            (r"''", String),
+            (r"'", String, '#pop'),
+            (r'\\([\\abfnrtv"\']|(x[a-fA-F0-9]+|[0-7]+)\\)', String.Escape),
+            (r"[^\\'\n]+", String),
+            (r'\\', String),
+        ],
+
+        'double_quoted_term': [
+            (r'""', String),
+            (r'"', String, '#pop'),
+            (r'\\([\\abfnrtv"\']|(x[a-fA-F0-9]+|[0-7]+)\\)', String.Escape),
+            (r'[^\\"\n]+', String),
+            (r'\\', String),
+        ],
+
+        'directive': [
+            # Conditional compilation directives
+            (r'(el)?if(?=[(])', Keyword, 'root'),
+            (r'(e(lse|ndif))(?=[.])', Keyword, 'root'),
+            # Entity directives
+            (r'(category|object|protocol)(?=[(])', Keyword, 'entityrelations'),
+            (r'(end_(category|object|protocol))(?=[.])', Keyword, 'root'),
+            # Predicate scope directives
+            (r'(public|protected|private)(?=[(])', Keyword, 'root'),
+            # Other directives
+            (r'e(n(coding|sure_loaded)|xport)(?=[(])', Keyword, 'root'),
+            (r'in(clude|itialization|fo)(?=[(])', Keyword, 'root'),
+            (r'(built_in|dynamic|synchronized|threaded)(?=[.])', Keyword, 'root'),
+            (r'(alias|d(ynamic|iscontiguous)|m(eta_(non_terminal|predicate)|ode|ultifile)|s(et_(logtalk|prolog)_flag|ynchronized))(?=[(])', Keyword, 'root'),
+            (r'op(?=[(])', Keyword, 'root'),
+            (r'(c(alls|oinductive)|module|reexport|use(s|_module))(?=[(])', Keyword, 'root'),
+            (r'[a-z][a-zA-Z0-9_]*(?=[(])', Text, 'root'),
+            (r'[a-z][a-zA-Z0-9_]*(?=[.])', Text, 'root'),
+        ],
+
+        'entityrelations': [
+            (r'(complements|extends|i(nstantiates|mp(lements|orts))|specializes)(?=[(])', Keyword),
+            # Numbers
+            (r"0'[\\]?.", Number),
+            (r'0b[01]+', Number.Bin),
+            (r'0o[0-7]+', Number.Oct),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'\d+\.?\d*((e|E)(\+|-)?\d+)?', Number),
+            # Variables
+            (r'([A-Z_][a-zA-Z0-9_]*)', Name.Variable),
+            # Atoms
+            (r"[a-z][a-zA-Z0-9_]*", Text),
+            (r"'", String, 'quoted_atom'),
+            # Double-quoted terms
+            (r'"', String, 'double_quoted_term'),
+            # End of entity-opening directive
+            (r'([)]\.)', Text, 'root'),
+            # Scope operator
+            (r'(::)', Operator),
+            # Punctuation
+            (r'[()\[\],.|]', Text),
+            # Comments
+            (r'%.*?\n', Comment),
+            (r'/\*(.|\n)*?\*/', Comment),
+            # Whitespace
+            (r'\n', Text),
+            (r'\s+', Text),
+        ]
+    }
+
+    def analyse_text(text):
+        if ':- object(' in text:
+            return 1.0
+        elif ':- protocol(' in text:
+            return 1.0
+        elif ':- category(' in text:
+            return 1.0
+        elif re.search(r'^:-\s[a-z]', text, re.M):
+            return 0.9
+        else:
+            return 0.0
diff --git a/.venv/Lib/site-packages/pygments/lexers/promql.py b/.venv/Lib/site-packages/pygments/lexers/promql.py
new file mode 100644
index 0000000..cad3c25
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/promql.py
@@ -0,0 +1,176 @@
+"""
+    pygments.lexers.promql
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Prometheus Query Language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, default, words
+from pygments.token import Comment, Keyword, Name, Number, Operator, \
+    Punctuation, String, Whitespace
+
+__all__ = ["PromQLLexer"]
+
+
+class PromQLLexer(RegexLexer):
+    """
+    For PromQL queries.
+
+    For details about the grammar see:
+    https://github.com/prometheus/prometheus/tree/master/promql/parser
+
+    .. versionadded: 2.7
+    """
+
+    name = "PromQL"
+    url = 'https://prometheus.io/docs/prometheus/latest/querying/basics/'
+    aliases = ["promql"]
+    filenames = ["*.promql"]
+    version_added = ''
+
+    base_keywords = (
+        words(
+            (
+                "bool",
+                "by",
+                "group_left",
+                "group_right",
+                "ignoring",
+                "offset",
+                "on",
+                "without",
+            ),
+            suffix=r"\b",
+        ),
+        Keyword,
+    )
+
+    aggregator_keywords = (
+        words(
+            (
+                "sum",
+                "min",
+                "max",
+                "avg",
+                "group",
+                "stddev",
+                "stdvar",
+                "count",
+                "count_values",
+                "bottomk",
+                "topk",
+                "quantile",
+            ),
+            suffix=r"\b",
+        ),
+        Keyword,
+    )
+
+    function_keywords = (
+        words(
+            (
+                "abs",
+                "absent",
+                "absent_over_time",
+                "avg_over_time",
+                "ceil",
+                "changes",
+                "clamp_max",
+                "clamp_min",
+                "count_over_time",
+                "day_of_month",
+                "day_of_week",
+                "days_in_month",
+                "delta",
+                "deriv",
+                "exp",
+                "floor",
+                "histogram_quantile",
+                "holt_winters",
+                "hour",
+                "idelta",
+                "increase",
+                "irate",
+                "label_join",
+                "label_replace",
+                "ln",
+                "log10",
+                "log2",
+                "max_over_time",
+                "min_over_time",
+                "minute",
+                "month",
+                "predict_linear",
+                "quantile_over_time",
+                "rate",
+                "resets",
+                "round",
+                "scalar",
+                "sort",
+                "sort_desc",
+                "sqrt",
+                "stddev_over_time",
+                "stdvar_over_time",
+                "sum_over_time",
+                "time",
+                "timestamp",
+                "vector",
+                "year",
+            ),
+            suffix=r"\b",
+        ),
+        Keyword.Reserved,
+    )
+
+    tokens = {
+        "root": [
+            (r"\n", Whitespace),
+            (r"\s+", Whitespace),
+            (r",", Punctuation),
+            # Keywords
+            base_keywords,
+            aggregator_keywords,
+            function_keywords,
+            # Offsets
+            (r"[1-9][0-9]*[smhdwy]", String),
+            # Numbers
+            (r"-?[0-9]+\.[0-9]+", Number.Float),
+            (r"-?[0-9]+", Number.Integer),
+            # Comments
+            (r"#.*?$", Comment.Single),
+            # Operators
+            (r"(\+|\-|\*|\/|\%|\^)", Operator),
+            (r"==|!=|>=|<=|<|>", Operator),
+            (r"and|or|unless", Operator.Word),
+            # Metrics
+            (r"[_a-zA-Z][a-zA-Z0-9_]+", Name.Variable),
+            # Params
+            (r'(["\'])(.*?)(["\'])', bygroups(Punctuation, String, Punctuation)),
+            # Other states
+            (r"\(", Operator, "function"),
+            (r"\)", Operator),
+            (r"\{", Punctuation, "labels"),
+            (r"\[", Punctuation, "range"),
+        ],
+        "labels": [
+            (r"\}", Punctuation, "#pop"),
+            (r"\n", Whitespace),
+            (r"\s+", Whitespace),
+            (r",", Punctuation),
+            (r'([_a-zA-Z][a-zA-Z0-9_]*?)(\s*?)(=~|!=|=|!~)(\s*?)("|\')(.*?)("|\')',
+             bygroups(Name.Label, Whitespace, Operator, Whitespace,
+                      Punctuation, String, Punctuation)),
+        ],
+        "range": [
+            (r"\]", Punctuation, "#pop"),
+            (r"[1-9][0-9]*[smhdwy]", String),
+        ],
+        "function": [
+            (r"\)", Operator, "#pop"),
+            (r"\(", Operator, "#push"),
+            default("#pop"),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/prql.py b/.venv/Lib/site-packages/pygments/lexers/prql.py
new file mode 100644
index 0000000..ee95d2d
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/prql.py
@@ -0,0 +1,251 @@
+"""
+    pygments.lexers.prql
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for the PRQL query language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, combined, words, include, bygroups
+from pygments.token import Comment, Literal, Keyword, Name, Number, Operator, \
+    Punctuation, String, Text, Whitespace
+
+__all__ = ['PrqlLexer']
+
+
+class PrqlLexer(RegexLexer):
+    """
+    For PRQL source code.
+
+    grammar: https://github.com/PRQL/prql/tree/main/grammars
+    """
+
+    name = 'PRQL'
+    url = 'https://prql-lang.org/'
+    aliases = ['prql']
+    filenames = ['*.prql']
+    mimetypes = ['application/prql', 'application/x-prql']
+    version_added = '2.17'
+
+    builtinTypes = words((
+        "bool",
+        "int",
+        "int8", "int16", "int32", "int64", "int128",
+        "float",
+        "text",
+        "set"), suffix=r'\b')
+
+    def innerstring_rules(ttype):
+        return [
+            # the new style '{}'.format(...) string formatting
+            (r'\{'
+             r'((\w+)((\.\w+)|(\[[^\]]+\]))*)?'  # field name
+             r'(\:(.?[<>=\^])?[-+ ]?#?0?(\d+)?,?(\.\d+)?[E-GXb-gnosx%]?)?'
+             r'\}', String.Interpol),
+
+            (r'[^\\\'"%{\n]+', ttype),
+            (r'[\'"\\]', ttype),
+            (r'%|(\{{1,2})', ttype)
+        ]
+
+    def fstring_rules(ttype):
+        return [
+            (r'\}', String.Interpol),
+            (r'\{', String.Interpol, 'expr-inside-fstring'),
+            (r'[^\\\'"{}\n]+', ttype),
+            (r'[\'"\\]', ttype),
+        ]
+
+    tokens = {
+        'root': [
+
+            # Comments
+            (r'#!.*', String.Doc),
+            (r'#.*', Comment.Single),
+
+            # Whitespace
+            (r'\s+', Whitespace),
+
+            # Modules
+            (r'^(\s*)(module)(\s*)',
+             bygroups(Whitespace, Keyword.Namespace, Whitespace),
+             'imports'),
+
+            (builtinTypes, Keyword.Type),
+
+            # Main
+            (r'^prql ', Keyword.Reserved),
+
+            ('let', Keyword.Declaration),
+
+            include('keywords'),
+            include('expr'),
+
+            # Transforms
+            (r'^[A-Za-z_][a-zA-Z0-9_]*', Keyword),
+        ],
+        'expr': [
+            # non-raw f-strings
+            ('(f)(""")', bygroups(String.Affix, String.Double),
+             combined('fstringescape', 'tdqf')),
+            ("(f)(''')", bygroups(String.Affix, String.Single),
+             combined('fstringescape', 'tsqf')),
+            ('(f)(")', bygroups(String.Affix, String.Double),
+             combined('fstringescape', 'dqf')),
+            ("(f)(')", bygroups(String.Affix, String.Single),
+             combined('fstringescape', 'sqf')),
+
+            # non-raw s-strings
+            ('(s)(""")', bygroups(String.Affix, String.Double),
+             combined('stringescape', 'tdqf')),
+            ("(s)(''')", bygroups(String.Affix, String.Single),
+             combined('stringescape', 'tsqf')),
+            ('(s)(")', bygroups(String.Affix, String.Double),
+             combined('stringescape', 'dqf')),
+            ("(s)(')", bygroups(String.Affix, String.Single),
+             combined('stringescape', 'sqf')),
+
+            # raw strings
+            ('(?i)(r)(""")',
+             bygroups(String.Affix, String.Double), 'tdqs'),
+            ("(?i)(r)(''')",
+             bygroups(String.Affix, String.Single), 'tsqs'),
+            ('(?i)(r)(")',
+             bygroups(String.Affix, String.Double), 'dqs'),
+            ("(?i)(r)(')",
+             bygroups(String.Affix, String.Single), 'sqs'),
+
+            # non-raw strings
+            ('"""', String.Double, combined('stringescape', 'tdqs')),
+            ("'''", String.Single, combined('stringescape', 'tsqs')),
+            ('"', String.Double, combined('stringescape', 'dqs')),
+            ("'", String.Single, combined('stringescape', 'sqs')),
+
+            # Time and dates
+            (r'@\d{4}-\d{2}-\d{2}T\d{2}(:\d{2})?(:\d{2})?(\.\d{1,6})?(Z|[+-]\d{1,2}(:\d{1,2})?)?', Literal.Date),
+            (r'@\d{4}-\d{2}-\d{2}', Literal.Date),
+            (r'@\d{2}(:\d{2})?(:\d{2})?(\.\d{1,6})?(Z|[+-]\d{1,2}(:\d{1,2})?)?', Literal.Date),
+
+            (r'[^\S\n]+', Text),
+            include('numbers'),
+            (r'->|=>|==|!=|>=|<=|~=|&&|\|\||\?\?|\/\/', Operator),
+            (r'[-~+/*%=<>&^|.@]', Operator),
+            (r'[]{}:(),;[]', Punctuation),
+            include('functions'),
+
+            # Variable Names
+            (r'[A-Za-z_][a-zA-Z0-9_]*', Name.Variable),
+        ],
+        'numbers': [
+            (r'(\d(?:_?\d)*\.(?:\d(?:_?\d)*)?|(?:\d(?:_?\d)*)?\.\d(?:_?\d)*)'
+             r'([eE][+-]?\d(?:_?\d)*)?', Number.Float),
+            (r'\d(?:_?\d)*[eE][+-]?\d(?:_?\d)*j?', Number.Float),
+            (r'0[oO](?:_?[0-7])+', Number.Oct),
+            (r'0[bB](?:_?[01])+', Number.Bin),
+            (r'0[xX](?:_?[a-fA-F0-9])+', Number.Hex),
+            (r'\d(?:_?\d)*', Number.Integer),
+        ],
+        'fstringescape': [
+            include('stringescape'),
+        ],
+        'bytesescape': [
+            (r'\\([\\bfnrt"\']|\n|x[a-fA-F0-9]{2}|[0-7]{1,3})', String.Escape)
+        ],
+        'stringescape': [
+            (r'\\(N\{.*?\}|u\{[a-fA-F0-9]{1,6}\})', String.Escape),
+            include('bytesescape')
+        ],
+        'fstrings-single': fstring_rules(String.Single),
+        'fstrings-double': fstring_rules(String.Double),
+        'strings-single': innerstring_rules(String.Single),
+        'strings-double': innerstring_rules(String.Double),
+        'dqf': [
+            (r'"', String.Double, '#pop'),
+            (r'\\\\|\\"|\\\n', String.Escape),  # included here for raw strings
+            include('fstrings-double')
+        ],
+        'sqf': [
+            (r"'", String.Single, '#pop'),
+            (r"\\\\|\\'|\\\n", String.Escape),  # included here for raw strings
+            include('fstrings-single')
+        ],
+        'dqs': [
+            (r'"', String.Double, '#pop'),
+            (r'\\\\|\\"|\\\n', String.Escape),  # included here for raw strings
+            include('strings-double')
+        ],
+        'sqs': [
+            (r"'", String.Single, '#pop'),
+            (r"\\\\|\\'|\\\n", String.Escape),  # included here for raw strings
+            include('strings-single')
+        ],
+        'tdqf': [
+            (r'"""', String.Double, '#pop'),
+            include('fstrings-double'),
+            (r'\n', String.Double)
+        ],
+        'tsqf': [
+            (r"'''", String.Single, '#pop'),
+            include('fstrings-single'),
+            (r'\n', String.Single)
+        ],
+        'tdqs': [
+            (r'"""', String.Double, '#pop'),
+            include('strings-double'),
+            (r'\n', String.Double)
+        ],
+        'tsqs': [
+            (r"'''", String.Single, '#pop'),
+            include('strings-single'),
+            (r'\n', String.Single)
+        ],
+
+        'expr-inside-fstring': [
+            (r'[{([]', Punctuation, 'expr-inside-fstring-inner'),
+            # without format specifier
+            (r'(=\s*)?'         # debug (https://bugs.python.org/issue36817)
+             r'\}', String.Interpol, '#pop'),
+            # with format specifier
+            # we'll catch the remaining '}' in the outer scope
+            (r'(=\s*)?'         # debug (https://bugs.python.org/issue36817)
+             r':', String.Interpol, '#pop'),
+            (r'\s+', Whitespace),  # allow new lines
+            include('expr'),
+        ],
+        'expr-inside-fstring-inner': [
+            (r'[{([]', Punctuation, 'expr-inside-fstring-inner'),
+            (r'[])}]', Punctuation, '#pop'),
+            (r'\s+', Whitespace),  # allow new lines
+            include('expr'),
+        ],
+        'keywords': [
+            (words((
+                'into', 'case', 'type', 'module', 'internal',
+            ), suffix=r'\b'),
+                Keyword),
+            (words(('true', 'false', 'null'), suffix=r'\b'), Keyword.Constant),
+        ],
+        'functions': [
+            (words((
+                "min", "max", "sum", "average", "stddev", "every", "any",
+                "concat_array", "count", "lag", "lead", "first", "last",
+                "rank", "rank_dense", "row_number", "round", "as", "in",
+                "tuple_every", "tuple_map", "tuple_zip", "_eq", "_is_null",
+                "from_text", "lower", "upper", "read_parquet", "read_csv"),
+                suffix=r'\b'),
+             Name.Function),
+        ],
+
+        'comment': [
+            (r'-(?!\})', Comment.Multiline),
+            (r'\{-', Comment.Multiline, 'comment'),
+            (r'[^-}]', Comment.Multiline),
+            (r'-\}', Comment.Multiline, '#pop'),
+        ],
+
+        'imports': [
+            (r'\w+(\.\w+)*', Name.Class, '#pop'),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/ptx.py b/.venv/Lib/site-packages/pygments/lexers/ptx.py
new file mode 100644
index 0000000..784ca13
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/ptx.py
@@ -0,0 +1,119 @@
+"""
+    pygments.lexers.ptx
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexer for other PTX language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, include, words
+from pygments.token import Comment, Keyword, Name, String, Number, \
+    Punctuation, Whitespace, Operator
+
+__all__ = ["PtxLexer"]
+
+
+class PtxLexer(RegexLexer):
+    """
+    For NVIDIA `PTX `_
+    source.
+    """
+    name = 'PTX'
+    url = "https://docs.nvidia.com/cuda/parallel-thread-execution/"
+    filenames = ['*.ptx']
+    aliases = ['ptx']
+    mimetypes = ['text/x-ptx']
+    version_added = '2.16'
+
+    #: optional Comment or Whitespace
+    string = r'"[^"]*?"'
+    followsym = r'[a-zA-Z0-9_$]'
+    identifier = r'([-a-zA-Z$._][\w\-$.]*|' + string + ')'
+    block_label = r'(' + identifier + r'|(\d+))'
+
+    tokens = {
+        'root': [
+            include('whitespace'),
+
+            (block_label + r'\s*:', Name.Label),
+
+            include('keyword'),
+
+            (r'%' + identifier, Name.Variable),
+            (r'%\d+', Name.Variable.Anonymous),
+            (r'c?' + string, String),
+            (identifier, Name.Variable),
+            (r';', Punctuation),
+            (r'[*+-/]', Operator),
+
+            (r'0[xX][a-fA-F0-9]+', Number),
+            (r'-?\d+(?:[.]\d+)?(?:[eE][-+]?\d+(?:[.]\d+)?)?', Number),
+
+            (r'[=<>{}\[\]()*.,!]|x\b', Punctuation)
+
+        ],
+        'whitespace': [
+            (r'(\n|\s+)+', Whitespace),
+            (r'//.*?\n', Comment)
+        ],
+
+        'keyword': [
+            # Instruction keywords
+            (words((
+                'abs', 'discard', 'min', 'shf', 'vadd',
+                'activemask', 'div', 'mma', 'shfl', 'vadd2',
+                'add', 'dp2a', 'mov', 'shl', 'vadd4',
+                'addc', 'dp4a', 'movmatrix', 'shr', 'vavrg2',
+                'alloca', 'elect', 'mul', 'sin', 'vavrg4',
+                'and', 'ex2', 'mul24', 'slct', 'vmad',
+                'applypriority', 'exit', 'multimem', 'sqrt', 'vmax',
+                'atom', 'fence', 'nanosleep', 'st', 'vmax2',
+                'bar', 'fma', 'neg', 'stackrestore', 'vmax4',
+                'barrier', 'fns', 'not', 'stacksave', 'vmin',
+                'bfe', 'getctarank', 'or', 'stmatrix', 'vmin2',
+                'bfi', 'griddepcontrol', 'pmevent', 'sub', 'vmin4',
+                'bfind', 'isspacep', 'popc', 'subc', 'vote',
+                'bmsk', 'istypep', 'prefetch', 'suld', 'vset',
+                'bra', 'ld', 'prefetchu', 'suq', 'vset2',
+                'brev', 'ldmatrix', 'prmt', 'sured', 'vset4',
+                'brkpt', 'ldu', 'rcp', 'sust', 'vshl',
+                'brx', 'lg2', 'red', 'szext', 'vshr',
+                'call', 'lop3', 'redux', 'tanh', 'vsub',
+                'clz', 'mad', 'rem', 'testp', 'vsub2',
+                'cnot', 'mad24', 'ret', 'tex', 'vsub4',
+                'copysign', 'madc', 'rsqrt', 'tld4', 'wgmma',
+                'cos', 'mapa', 'sad', 'trap', 'wmma',
+                'cp', 'match', 'selp', 'txq', 'xor',
+                'createpolicy', 'max', 'set', 'vabsdiff', 'cvt',
+                'mbarrier', 'setmaxnreg', 'vabsdiff2', 'cvta',
+                'membar', 'setp', 'vabsdiff4')), Keyword),
+            # State Spaces and Suffixes
+            (words((
+                'reg', '.sreg', '.const', '.global',
+                '.local', '.param', '.shared', '.tex',
+                '.wide', '.loc'
+            )), Keyword.Pseudo),
+            # PTX Directives
+            (words((
+                '.address_size', '.explicitcluster', '.maxnreg', '.section',
+                '.alias', '.extern', '.maxntid', '.shared',
+                '.align', '.file', '.minnctapersm', '.sreg',
+                '.branchtargets', '.func', '.noreturn', '.target',
+                '.callprototype', '.global', '.param', '.tex',
+                '.calltargets', '.loc', '.pragma', '.version',
+                '.common', '.local', '.reg', '.visible',
+                '.const', '.maxclusterrank', '.reqnctapercluster', '.weak',
+                '.entry', '.maxnctapersm', '.reqntid')), Keyword.Reserved),
+            # Fundamental Types
+            (words((
+                '.s8', '.s16', '.s32', '.s64',
+                '.u8', '.u16', '.u32', '.u64',
+                '.f16', '.f16x2', '.f32', '.f64',
+                '.b8', '.b16', '.b32', '.b64',
+                '.pred'
+            )), Keyword.Type)
+        ],
+
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/python.py b/.venv/Lib/site-packages/pygments/lexers/python.py
new file mode 100644
index 0000000..805f6ff
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/python.py
@@ -0,0 +1,1201 @@
+"""
+    pygments.lexers.python
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Python and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import keyword
+
+from pygments.lexer import DelegatingLexer, RegexLexer, include, \
+    bygroups, using, default, words, combined, this
+from pygments.util import get_bool_opt, shebang_matches
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Generic, Other, Error, Whitespace
+from pygments import unistring as uni
+
+__all__ = ['PythonLexer', 'PythonConsoleLexer', 'PythonTracebackLexer',
+           'Python2Lexer', 'Python2TracebackLexer',
+           'CythonLexer', 'DgLexer', 'NumPyLexer']
+
+
+class PythonLexer(RegexLexer):
+    """
+    For Python source code (version 3.x).
+
+    .. versionchanged:: 2.5
+       This is now the default ``PythonLexer``.  It is still available as the
+       alias ``Python3Lexer``.
+    """
+
+    name = 'Python'
+    url = 'https://www.python.org'
+    aliases = ['python', 'py', 'sage', 'python3', 'py3', 'bazel', 'starlark', 'pyi']
+    filenames = [
+        '*.py',
+        '*.pyw',
+        # Type stubs
+        '*.pyi',
+        # Jython
+        '*.jy',
+        # Sage
+        '*.sage',
+        # SCons
+        '*.sc',
+        'SConstruct',
+        'SConscript',
+        # Skylark/Starlark (used by Bazel, Buck, and Pants)
+        '*.bzl',
+        'BUCK',
+        'BUILD',
+        'BUILD.bazel',
+        'WORKSPACE',
+        # Twisted Application infrastructure
+        '*.tac',
+    ]
+    mimetypes = ['text/x-python', 'application/x-python',
+                 'text/x-python3', 'application/x-python3']
+    version_added = '0.10'
+
+    uni_name = f"[{uni.xid_start}][{uni.xid_continue}]*"
+
+    def innerstring_rules(ttype):
+        return [
+            # the old style '%s' % (...) string formatting (still valid in Py3)
+            (r'%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?'
+             '[hlL]?[E-GXc-giorsaux%]', String.Interpol),
+            # the new style '{}'.format(...) string formatting
+            (r'\{'
+             r'((\w+)((\.\w+)|(\[[^\]]+\]))*)?'  # field name
+             r'(\![sra])?'                       # conversion
+             r'(\:(.?[<>=\^])?[-+ ]?#?0?(\d+)?,?(\.\d+)?[E-GXb-gnosx%]?)?'
+             r'\}', String.Interpol),
+
+            # backslashes, quotes and formatting signs must be parsed one at a time
+            (r'[^\\\'"%{\n]+', ttype),
+            (r'[\'"\\]', ttype),
+            # unhandled string formatting sign
+            (r'%|(\{{1,2})', ttype)
+            # newlines are an error (use "nl" state)
+        ]
+
+    def fstring_rules(ttype):
+        return [
+            # Assuming that a '}' is the closing brace after format specifier.
+            # Sadly, this means that we won't detect syntax error. But it's
+            # more important to parse correct syntax correctly, than to
+            # highlight invalid syntax.
+            (r'\}', String.Interpol),
+            (r'\{', String.Interpol, 'expr-inside-fstring'),
+            # backslashes, quotes and formatting signs must be parsed one at a time
+            (r'[^\\\'"{}\n]+', ttype),
+            (r'[\'"\\]', ttype),
+            # newlines are an error (use "nl" state)
+        ]
+
+    tokens = {
+        'root': [
+            (r'\n', Whitespace),
+            (r'^(\s*)([rRuUbB]{,2})("""(?:.|\n)*?""")',
+             bygroups(Whitespace, String.Affix, String.Doc)),
+            (r"^(\s*)([rRuUbB]{,2})('''(?:.|\n)*?''')",
+             bygroups(Whitespace, String.Affix, String.Doc)),
+            (r'\A#!.+$', Comment.Hashbang),
+            (r'#.*$', Comment.Single),
+            (r'\\\n', Text),
+            (r'\\', Text),
+            include('keywords'),
+            include('soft-keywords'),
+            (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Whitespace), 'funcname'),
+            (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Whitespace), 'classname'),
+            (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Whitespace),
+             'fromimport'),
+            (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Whitespace),
+             'import'),
+            include('expr'),
+        ],
+        'expr': [
+            # raw f-strings
+            ('(?i)(rf|fr)(""")',
+             bygroups(String.Affix, String.Double),
+             combined('rfstringescape', 'tdqf')),
+            ("(?i)(rf|fr)(''')",
+             bygroups(String.Affix, String.Single),
+             combined('rfstringescape', 'tsqf')),
+            ('(?i)(rf|fr)(")',
+             bygroups(String.Affix, String.Double),
+             combined('rfstringescape', 'dqf')),
+            ("(?i)(rf|fr)(')",
+             bygroups(String.Affix, String.Single),
+             combined('rfstringescape', 'sqf')),
+            # non-raw f-strings
+            ('([fF])(""")', bygroups(String.Affix, String.Double),
+             combined('fstringescape', 'tdqf')),
+            ("([fF])(''')", bygroups(String.Affix, String.Single),
+             combined('fstringescape', 'tsqf')),
+            ('([fF])(")', bygroups(String.Affix, String.Double),
+             combined('fstringescape', 'dqf')),
+            ("([fF])(')", bygroups(String.Affix, String.Single),
+             combined('fstringescape', 'sqf')),
+            # raw bytes and strings
+            ('(?i)(rb|br|r)(""")',
+             bygroups(String.Affix, String.Double), 'tdqs'),
+            ("(?i)(rb|br|r)(''')",
+             bygroups(String.Affix, String.Single), 'tsqs'),
+            ('(?i)(rb|br|r)(")',
+             bygroups(String.Affix, String.Double), 'dqs'),
+            ("(?i)(rb|br|r)(')",
+             bygroups(String.Affix, String.Single), 'sqs'),
+            # non-raw strings
+            ('([uU]?)(""")', bygroups(String.Affix, String.Double),
+             combined('stringescape', 'tdqs')),
+            ("([uU]?)(''')", bygroups(String.Affix, String.Single),
+             combined('stringescape', 'tsqs')),
+            ('([uU]?)(")', bygroups(String.Affix, String.Double),
+             combined('stringescape', 'dqs')),
+            ("([uU]?)(')", bygroups(String.Affix, String.Single),
+             combined('stringescape', 'sqs')),
+            # non-raw bytes
+            ('([bB])(""")', bygroups(String.Affix, String.Double),
+             combined('bytesescape', 'tdqs')),
+            ("([bB])(''')", bygroups(String.Affix, String.Single),
+             combined('bytesescape', 'tsqs')),
+            ('([bB])(")', bygroups(String.Affix, String.Double),
+             combined('bytesescape', 'dqs')),
+            ("([bB])(')", bygroups(String.Affix, String.Single),
+             combined('bytesescape', 'sqs')),
+
+            (r'[^\S\n]+', Text),
+            include('numbers'),
+            (r'!=|==|<<|>>|:=|[-~+/*%=<>&^|.]', Operator),
+            (r'[]{}:(),;[]', Punctuation),
+            (r'(in|is|and|or|not)\b', Operator.Word),
+            include('expr-keywords'),
+            include('builtins'),
+            include('magicfuncs'),
+            include('magicvars'),
+            include('name'),
+        ],
+        'expr-inside-fstring': [
+            (r'[{([]', Punctuation, 'expr-inside-fstring-inner'),
+            # without format specifier
+            (r'(=\s*)?'         # debug (https://bugs.python.org/issue36817)
+             r'(\![sraf])?'     # conversion
+             r'\}', String.Interpol, '#pop'),
+            # with format specifier
+            # we'll catch the remaining '}' in the outer scope
+            (r'(=\s*)?'         # debug (https://bugs.python.org/issue36817)
+             r'(\![sraf])?'     # conversion
+             r':', String.Interpol, '#pop'),
+            (r'\s+', Whitespace),  # allow new lines
+            include('expr'),
+        ],
+        'expr-inside-fstring-inner': [
+            (r'[{([]', Punctuation, 'expr-inside-fstring-inner'),
+            (r'[])}]', Punctuation, '#pop'),
+            (r'\s+', Whitespace),  # allow new lines
+            include('expr'),
+        ],
+        'expr-keywords': [
+            # Based on https://docs.python.org/3/reference/expressions.html
+            (words((
+                'async for', 'await', 'else', 'for', 'if', 'lambda',
+                'yield', 'yield from'), suffix=r'\b'),
+             Keyword),
+            (words(('True', 'False', 'None'), suffix=r'\b'), Keyword.Constant),
+        ],
+        'keywords': [
+            (words((
+                'assert', 'async', 'await', 'break', 'continue', 'del', 'elif',
+                'else', 'except', 'finally', 'for', 'global', 'if', 'lambda',
+                'pass', 'raise', 'nonlocal', 'return', 'try', 'while', 'yield',
+                'yield from', 'as', 'with'), suffix=r'\b'),
+             Keyword),
+            (words(('True', 'False', 'None'), suffix=r'\b'), Keyword.Constant),
+        ],
+        'soft-keywords': [
+            # `match`, `case` and `_` soft keywords
+            (r'(^[ \t]*)'              # at beginning of line + possible indentation
+             r'(match|case)\b'         # a possible keyword
+             r'(?![ \t]*(?:'           # not followed by...
+             r'[:,;=^&|@~)\]}]|(?:' +  # characters and keywords that mean this isn't
+                                       # pattern matching (but None/True/False is ok)
+             r'|'.join(k for k in keyword.kwlist if k[0].islower()) + r')\b))',
+             bygroups(Text, Keyword), 'soft-keywords-inner'),
+        ],
+        'soft-keywords-inner': [
+            # optional `_` keyword
+            (r'(\s+)([^\n_]*)(_\b)', bygroups(Whitespace, using(this), Keyword)),
+            default('#pop')
+        ],
+        'builtins': [
+            (words((
+                '__import__', 'abs', 'aiter', 'all', 'any', 'bin', 'bool', 'bytearray',
+                'breakpoint', 'bytes', 'callable', 'chr', 'classmethod', 'compile',
+                'complex', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval',
+                'filter', 'float', 'format', 'frozenset', 'getattr', 'globals',
+                'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'isinstance',
+                'issubclass', 'iter', 'len', 'list', 'locals', 'map', 'max',
+                'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow',
+                'print', 'property', 'range', 'repr', 'reversed', 'round', 'set',
+                'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super',
+                'tuple', 'type', 'vars', 'zip'), prefix=r'(?>|[-~+/*%=<>&^|.]', Operator),
+            include('keywords'),
+            (r'(def)((?:\s|\\\s)+)', bygroups(Keyword, Whitespace), 'funcname'),
+            (r'(class)((?:\s|\\\s)+)', bygroups(Keyword, Whitespace), 'classname'),
+            (r'(from)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Whitespace),
+             'fromimport'),
+            (r'(import)((?:\s|\\\s)+)', bygroups(Keyword.Namespace, Whitespace),
+             'import'),
+            include('builtins'),
+            include('magicfuncs'),
+            include('magicvars'),
+            include('backtick'),
+            ('([rR]|[uUbB][rR]|[rR][uUbB])(""")',
+             bygroups(String.Affix, String.Double), 'tdqs'),
+            ("([rR]|[uUbB][rR]|[rR][uUbB])(''')",
+             bygroups(String.Affix, String.Single), 'tsqs'),
+            ('([rR]|[uUbB][rR]|[rR][uUbB])(")',
+             bygroups(String.Affix, String.Double), 'dqs'),
+            ("([rR]|[uUbB][rR]|[rR][uUbB])(')",
+             bygroups(String.Affix, String.Single), 'sqs'),
+            ('([uUbB]?)(""")', bygroups(String.Affix, String.Double),
+             combined('stringescape', 'tdqs')),
+            ("([uUbB]?)(''')", bygroups(String.Affix, String.Single),
+             combined('stringescape', 'tsqs')),
+            ('([uUbB]?)(")', bygroups(String.Affix, String.Double),
+             combined('stringescape', 'dqs')),
+            ("([uUbB]?)(')", bygroups(String.Affix, String.Single),
+             combined('stringescape', 'sqs')),
+            include('name'),
+            include('numbers'),
+        ],
+        'keywords': [
+            (words((
+                'assert', 'break', 'continue', 'del', 'elif', 'else', 'except',
+                'exec', 'finally', 'for', 'global', 'if', 'lambda', 'pass',
+                'print', 'raise', 'return', 'try', 'while', 'yield',
+                'yield from', 'as', 'with'), suffix=r'\b'),
+             Keyword),
+        ],
+        'builtins': [
+            (words((
+                '__import__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin',
+                'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod',
+                'cmp', 'coerce', 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod',
+                'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float',
+                'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'hex', 'id',
+                'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter', 'len',
+                'list', 'locals', 'long', 'map', 'max', 'min', 'next', 'object',
+                'oct', 'open', 'ord', 'pow', 'property', 'range', 'raw_input', 'reduce',
+                'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
+                'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type',
+                'unichr', 'unicode', 'vars', 'xrange', 'zip'),
+                prefix=r'(?>> )(.*\n)', bygroups(Generic.Prompt, Other.Code), 'continuations'),
+            # This happens, e.g., when tracebacks are embedded in documentation;
+            # trailing whitespaces are often stripped in such contexts.
+            (r'(>>>)(\n)', bygroups(Generic.Prompt, Whitespace)),
+            (r'(\^C)?Traceback \(most recent call last\):\n', Other.Traceback, 'traceback'),
+            # SyntaxError starts with this
+            (r'  File "[^"]+", line \d+', Other.Traceback, 'traceback'),
+            (r'.*\n', Generic.Output),
+        ],
+        'continuations': [
+            (r'(\.\.\. )(.*\n)', bygroups(Generic.Prompt, Other.Code)),
+            # See above.
+            (r'(\.\.\.)(\n)', bygroups(Generic.Prompt, Whitespace)),
+            default('#pop'),
+        ],
+        'traceback': [
+            # As soon as we see a traceback, consume everything until the next
+            # >>> prompt.
+            (r'(?=>>>( |$))', Text, '#pop'),
+            (r'(KeyboardInterrupt)(\n)', bygroups(Name.Class, Whitespace)),
+            (r'.*\n', Other.Traceback),
+        ],
+    }
+
+
+class PythonConsoleLexer(DelegatingLexer):
+    """
+    For Python console output or doctests, such as:
+
+    .. sourcecode:: pycon
+
+        >>> a = 'foo'
+        >>> print(a)
+        foo
+        >>> 1 / 0
+        Traceback (most recent call last):
+          File "", line 1, in 
+        ZeroDivisionError: integer division or modulo by zero
+
+    Additional options:
+
+    `python3`
+        Use Python 3 lexer for code.  Default is ``True``.
+
+        .. versionadded:: 1.0
+        .. versionchanged:: 2.5
+           Now defaults to ``True``.
+    """
+
+    name = 'Python console session'
+    aliases = ['pycon', 'python-console']
+    mimetypes = ['text/x-python-doctest']
+    url = 'https://python.org'
+    version_added = ''
+
+    def __init__(self, **options):
+        python3 = get_bool_opt(options, 'python3', True)
+        if python3:
+            pylexer = PythonLexer
+            tblexer = PythonTracebackLexer
+        else:
+            pylexer = Python2Lexer
+            tblexer = Python2TracebackLexer
+        # We have two auxiliary lexers. Use DelegatingLexer twice with
+        # different tokens.  TODO: DelegatingLexer should support this
+        # directly, by accepting a tuplet of auxiliary lexers and a tuple of
+        # distinguishing tokens. Then we wouldn't need this intermediary
+        # class.
+        class _ReplaceInnerCode(DelegatingLexer):
+            def __init__(self, **options):
+                super().__init__(pylexer, _PythonConsoleLexerBase, Other.Code, **options)
+        super().__init__(tblexer, _ReplaceInnerCode, Other.Traceback, **options)
+
+
+class PythonTracebackLexer(RegexLexer):
+    """
+    For Python 3.x tracebacks, with support for chained exceptions.
+
+    .. versionchanged:: 2.5
+       This is now the default ``PythonTracebackLexer``.  It is still available
+       as the alias ``Python3TracebackLexer``.
+    """
+
+    name = 'Python Traceback'
+    aliases = ['pytb', 'py3tb']
+    filenames = ['*.pytb', '*.py3tb']
+    mimetypes = ['text/x-python-traceback', 'text/x-python3-traceback']
+    url = 'https://python.org'
+    version_added = '1.0'
+
+    tokens = {
+        'root': [
+            (r'\n', Whitespace),
+            (r'^(\^C)?Traceback \(most recent call last\):\n', Generic.Traceback, 'intb'),
+            (r'^During handling of the above exception, another '
+             r'exception occurred:\n\n', Generic.Traceback),
+            (r'^The above exception was the direct cause of the '
+             r'following exception:\n\n', Generic.Traceback),
+            (r'^(?=  File "[^"]+", line \d+)', Generic.Traceback, 'intb'),
+            (r'^.*\n', Other),
+        ],
+        'intb': [
+            (r'^(  File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)',
+             bygroups(Text, Name.Builtin, Text, Number, Text, Name, Whitespace)),
+            (r'^(  File )("[^"]+")(, line )(\d+)(\n)',
+             bygroups(Text, Name.Builtin, Text, Number, Whitespace)),
+            (r'^(    )(.+)(\n)',
+             bygroups(Whitespace, using(PythonLexer), Whitespace), 'markers'),
+            (r'^([ \t]*)(\.\.\.)(\n)',
+             bygroups(Whitespace, Comment, Whitespace)),  # for doctests...
+            (r'^([^:]+)(: )(.+)(\n)',
+             bygroups(Generic.Error, Text, Name, Whitespace), '#pop'),
+            (r'^([a-zA-Z_][\w.]*)(:?\n)',
+             bygroups(Generic.Error, Whitespace), '#pop'),
+            default('#pop'),
+        ],
+        'markers': [
+            # Either `PEP 657 `
+            # error locations in Python 3.11+, or single-caret markers
+            # for syntax errors before that.
+            (r'^( {4,})([~^]+)(\n)',
+             bygroups(Whitespace, Punctuation.Marker, Whitespace),
+             '#pop'),
+            default('#pop'),
+        ],
+    }
+
+
+Python3TracebackLexer = PythonTracebackLexer
+
+
+class Python2TracebackLexer(RegexLexer):
+    """
+    For Python tracebacks.
+
+    .. versionchanged:: 2.5
+       This class has been renamed from ``PythonTracebackLexer``.
+       ``PythonTracebackLexer`` now refers to the Python 3 variant.
+    """
+
+    name = 'Python 2.x Traceback'
+    aliases = ['py2tb']
+    filenames = ['*.py2tb']
+    mimetypes = ['text/x-python2-traceback']
+    url = 'https://python.org'
+    version_added = '0.7'
+
+    tokens = {
+        'root': [
+            # Cover both (most recent call last) and (innermost last)
+            # The optional ^C allows us to catch keyboard interrupt signals.
+            (r'^(\^C)?(Traceback.*\n)',
+             bygroups(Text, Generic.Traceback), 'intb'),
+            # SyntaxError starts with this.
+            (r'^(?=  File "[^"]+", line \d+)', Generic.Traceback, 'intb'),
+            (r'^.*\n', Other),
+        ],
+        'intb': [
+            (r'^(  File )("[^"]+")(, line )(\d+)(, in )(.+)(\n)',
+             bygroups(Text, Name.Builtin, Text, Number, Text, Name, Whitespace)),
+            (r'^(  File )("[^"]+")(, line )(\d+)(\n)',
+             bygroups(Text, Name.Builtin, Text, Number, Whitespace)),
+            (r'^(    )(.+)(\n)',
+             bygroups(Text, using(Python2Lexer), Whitespace), 'marker'),
+            (r'^([ \t]*)(\.\.\.)(\n)',
+             bygroups(Text, Comment, Whitespace)),  # for doctests...
+            (r'^([^:]+)(: )(.+)(\n)',
+             bygroups(Generic.Error, Text, Name, Whitespace), '#pop'),
+            (r'^([a-zA-Z_]\w*)(:?\n)',
+             bygroups(Generic.Error, Whitespace), '#pop')
+        ],
+        'marker': [
+            # For syntax errors.
+            (r'( {4,})(\^)', bygroups(Text, Punctuation.Marker), '#pop'),
+            default('#pop'),
+        ],
+    }
+
+
+class CythonLexer(RegexLexer):
+    """
+    For Pyrex and Cython source code.
+    """
+
+    name = 'Cython'
+    url = 'https://cython.org'
+    aliases = ['cython', 'pyx', 'pyrex']
+    filenames = ['*.pyx', '*.pxd', '*.pxi']
+    mimetypes = ['text/x-cython', 'application/x-cython']
+    version_added = '1.1'
+
+    tokens = {
+        'root': [
+            (r'\n', Whitespace),
+            (r'^(\s*)("""(?:.|\n)*?""")', bygroups(Whitespace, String.Doc)),
+            (r"^(\s*)('''(?:.|\n)*?''')", bygroups(Whitespace, String.Doc)),
+            (r'[^\S\n]+', Text),
+            (r'#.*$', Comment),
+            (r'[]{}:(),;[]', Punctuation),
+            (r'\\\n', Whitespace),
+            (r'\\', Text),
+            (r'(in|is|and|or|not)\b', Operator.Word),
+            (r'(<)([a-zA-Z0-9.?]+)(>)',
+             bygroups(Punctuation, Keyword.Type, Punctuation)),
+            (r'!=|==|<<|>>|[-~+/*%=<>&^|.?]', Operator),
+            (r'(from)(\d+)(<=)(\s+)(<)(\d+)(:)',
+             bygroups(Keyword, Number.Integer, Operator, Whitespace, Operator,
+                      Name, Punctuation)),
+            include('keywords'),
+            (r'(def|property)(\s+)', bygroups(Keyword, Whitespace), 'funcname'),
+            (r'(cp?def)(\s+)', bygroups(Keyword, Whitespace), 'cdef'),
+            # (should actually start a block with only cdefs)
+            (r'(cdef)(:)', bygroups(Keyword, Punctuation)),
+            (r'(class|struct)(\s+)', bygroups(Keyword, Whitespace), 'classname'),
+            (r'(from)(\s+)', bygroups(Keyword, Whitespace), 'fromimport'),
+            (r'(c?import)(\s+)', bygroups(Keyword, Whitespace), 'import'),
+            include('builtins'),
+            include('backtick'),
+            ('(?:[rR]|[uU][rR]|[rR][uU])"""', String, 'tdqs'),
+            ("(?:[rR]|[uU][rR]|[rR][uU])'''", String, 'tsqs'),
+            ('(?:[rR]|[uU][rR]|[rR][uU])"', String, 'dqs'),
+            ("(?:[rR]|[uU][rR]|[rR][uU])'", String, 'sqs'),
+            ('[uU]?"""', String, combined('stringescape', 'tdqs')),
+            ("[uU]?'''", String, combined('stringescape', 'tsqs')),
+            ('[uU]?"', String, combined('stringescape', 'dqs')),
+            ("[uU]?'", String, combined('stringescape', 'sqs')),
+            include('name'),
+            include('numbers'),
+        ],
+        'keywords': [
+            (words((
+                'assert', 'async', 'await', 'break', 'by', 'continue', 'ctypedef', 'del', 'elif',
+                'else', 'except', 'except?', 'exec', 'finally', 'for', 'fused', 'gil',
+                'global', 'if', 'include', 'lambda', 'nogil', 'pass', 'print',
+                'raise', 'return', 'try', 'while', 'yield', 'as', 'with'), suffix=r'\b'),
+             Keyword),
+            (r'(DEF|IF|ELIF|ELSE)\b', Comment.Preproc),
+        ],
+        'builtins': [
+            (words((
+                '__import__', 'abs', 'all', 'any', 'apply', 'basestring', 'bin', 'bint',
+                'bool', 'buffer', 'bytearray', 'bytes', 'callable', 'chr',
+                'classmethod', 'cmp', 'coerce', 'compile', 'complex', 'delattr',
+                'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile', 'exit',
+                'file', 'filter', 'float', 'frozenset', 'getattr', 'globals',
+                'hasattr', 'hash', 'hex', 'id', 'input', 'int', 'intern', 'isinstance',
+                'issubclass', 'iter', 'len', 'list', 'locals', 'long', 'map', 'max',
+                'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'Py_ssize_t',
+                'range', 'raw_input', 'reduce', 'reload', 'repr', 'reversed',
+                'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod',
+                'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode', 'unsigned',
+                'vars', 'xrange', 'zip'), prefix=r'(??/\\:']?:)(\s*)(\{)",
+             bygroups(Name.Function, Whitespace, Operator, Whitespace, Punctuation),
+             "functions"),
+            # Variable Names
+            (r"([.]?[a-zA-Z][\w.]*)(\s*)([-.~=!@#$%^&*_+|,<>?/\\:']?:)",
+             bygroups(Name.Variable, Whitespace, Operator)),
+            # Functions
+            (r"\{", Punctuation, "functions"),
+            # Parentheses
+            (r"\(", Punctuation, "parentheses"),
+            # Brackets
+            (r"\[", Punctuation, "brackets"),
+            # Errors
+            (r"'`([a-zA-Z][\w.]*)?", Name.Exception),
+            # File Symbols
+            (r"`:([a-zA-Z/][\w./]*)?", String.Symbol),
+            # Symbols
+            (r"`([a-zA-Z][\w.]*)?", String.Symbol),
+            # Numbers
+            include("numbers"),
+            # Variable Names
+            (r"[a-zA-Z][\w.]*", Name),
+            # Operators
+            (r"[-=+*#$%@!~^&:.,<>'\\|/?_]", Operator),
+            # Punctuation
+            (r";", Punctuation),
+        ],
+        "functions": [
+            include("root"),
+            (r"\}", Punctuation, "#pop"),
+        ],
+        "parentheses": [
+            include("root"),
+            (r"\)", Punctuation, "#pop"),
+        ],
+        "brackets": [
+            include("root"),
+            (r"\]", Punctuation, "#pop"),
+        ],
+        "numbers": [
+            # Binary Values
+            (r"[01]+b", Number.Bin),
+            # Nulls/Infinities
+            (r"0[nNwW][cefghijmndzuvtp]?", Number),
+            # Timestamps
+            ((r"(?:[0-9]{4}[.][0-9]{2}[.][0-9]{2}|[0-9]+)"
+              "D(?:[0-9](?:[0-9](?::[0-9]{2}"
+              "(?::[0-9]{2}(?:[.][0-9]*)?)?)?)?)?"), Literal.Date),
+            # Datetimes
+            ((r"[0-9]{4}[.][0-9]{2}"
+              "(?:m|[.][0-9]{2}(?:T(?:[0-9]{2}:[0-9]{2}"
+              "(?::[0-9]{2}(?:[.][0-9]*)?)?)?)?)"), Literal.Date),
+            # Times
+            (r"[0-9]{2}:[0-9]{2}(?::[0-9]{2}(?:[.][0-9]{1,3})?)?",
+             Literal.Date),
+            # GUIDs
+            (r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",
+             Number.Hex),
+            # Byte Vectors
+            (r"0x[0-9a-fA-F]+", Number.Hex),
+            # Floats
+            (r"([0-9]*[.]?[0-9]+|[0-9]+[.]?[0-9]*)[eE][+-]?[0-9]+[ef]?",
+             Number.Float),
+            (r"([0-9]*[.][0-9]+|[0-9]+[.][0-9]*)[ef]?", Number.Float),
+            (r"[0-9]+[ef]", Number.Float),
+            # Characters
+            (r"[0-9]+c", Number),
+            # Integers
+            (r"[0-9]+[ihtuv]", Number.Integer),
+            # Long Integers
+            (r"[0-9]+[jnp]?", Number.Integer.Long),
+        ],
+        "comments": [
+            (r"[^\\]+", Comment.Multiline),
+            (r"^\\", Comment.Multiline, "#pop"),
+            (r"\\", Comment.Multiline),
+        ],
+        "strings": [
+            (r'[^"\\]+', String.Double),
+            (r"\\.", String.Escape),
+            (r'"', String.Double, "#pop"),
+        ],
+    }
+
+
+class QLexer(KLexer):
+    """
+    For `Q `_ source code.
+    """
+
+    name = "Q"
+    aliases = ["q"]
+    filenames = ["*.q"]
+    version_added = '2.12'
+
+    tokens = {
+        "root": [
+            (words(("aj", "aj0", "ajf", "ajf0", "all", "and", "any", "asc",
+                    "asof", "attr", "avgs", "ceiling", "cols", "count", "cross",
+                    "csv", "cut", "deltas", "desc", "differ", "distinct", "dsave",
+                    "each", "ej", "ema", "eval", "except", "fby", "fills", "first",
+                    "fkeys", "flip", "floor", "get", "group", "gtime", "hclose",
+                    "hcount", "hdel", "hsym", "iasc", "idesc", "ij", "ijf",
+                    "inter", "inv", "key", "keys", "lj", "ljf", "load", "lower",
+                    "lsq", "ltime", "ltrim", "mavg", "maxs", "mcount", "md5",
+                    "mdev", "med", "meta", "mins", "mmax", "mmin", "mmu", "mod",
+                    "msum", "neg", "next", "not", "null", "or", "over", "parse",
+                    "peach", "pj", "prds", "prior", "prev", "rand", "rank", "ratios",
+                    "raze", "read0", "read1", "reciprocal", "reval", "reverse",
+                    "rload", "rotate", "rsave", "rtrim", "save", "scan", "scov",
+                    "sdev", "set", "show", "signum", "ssr", "string", "sublist",
+                    "sums", "sv", "svar", "system", "tables", "til", "trim", "txf",
+                    "type", "uj", "ujf", "ungroup", "union", "upper", "upsert",
+                    "value", "view", "views", "vs", "where", "wj", "wj1", "ww",
+                    "xasc", "xbar", "xcol", "xcols", "xdesc", "xgroup", "xkey",
+                    "xlog", "xprev", "xrank"),
+                    suffix=r"\b"), Name.Builtin,
+            ),
+            inherit,
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/qlik.py b/.venv/Lib/site-packages/pygments/lexers/qlik.py
new file mode 100644
index 0000000..a29f89f
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/qlik.py
@@ -0,0 +1,117 @@
+"""
+    pygments.lexers.qlik
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for the qlik scripting language
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, bygroups, words
+from pygments.token import Comment, Keyword, Name, Number, Operator, \
+    Punctuation, String, Text
+from pygments.lexers._qlik_builtins import OPERATORS_LIST, STATEMENT_LIST, \
+    SCRIPT_FUNCTIONS, CONSTANT_LIST
+
+__all__ = ["QlikLexer"]
+
+
+class QlikLexer(RegexLexer):
+    """
+    Lexer for qlik code, including .qvs files
+    """
+
+    name = "Qlik"
+    aliases = ["qlik", "qlikview", "qliksense", "qlikscript"]
+    filenames = ["*.qvs", "*.qvw"]
+    url = "https://qlik.com"
+    version_added = '2.12'
+
+    flags = re.IGNORECASE
+
+    tokens = {
+        # Handle multi-line comments
+        "comment": [
+            (r"\*/", Comment.Multiline, "#pop"),
+            (r"[^*]+", Comment.Multiline),
+        ],
+        # Handle numbers
+        "numerics": [
+            (r"\b\d+\.\d+(e\d+)?[fd]?\b", Number.Float),
+            (r"\b\d+\b", Number.Integer),
+        ],
+        # Handle variable names in things
+        "interp": [
+            (
+                r"(\$\()(\w+)(\))",
+                bygroups(String.Interpol, Name.Variable, String.Interpol),
+            ),
+        ],
+        # Handle strings
+        "string": [
+            (r"'", String, "#pop"),
+            include("interp"),
+            (r"[^'$]+", String),
+            (r"\$", String),
+        ],
+        #
+        "assignment": [
+            (r";", Punctuation, "#pop"),
+            include("root"),
+        ],
+        "field_name_quote": [
+            (r'"', String.Symbol, "#pop"),
+            include("interp"),
+            (r"[^\"$]+", String.Symbol),
+            (r"\$", String.Symbol),
+        ],
+        "field_name_bracket": [
+            (r"\]", String.Symbol, "#pop"),
+            include("interp"),
+            (r"[^\]$]+", String.Symbol),
+            (r"\$", String.Symbol),
+        ],
+        "function": [(r"\)", Punctuation, "#pop"), include("root")],
+        "root": [
+            # Whitespace and comments
+            (r"\s+", Text.Whitespace),
+            (r"/\*", Comment.Multiline, "comment"),
+            (r"//.*\n", Comment.Single),
+            # variable assignment
+            (r"(let|set)(\s+)", bygroups(Keyword.Declaration, Text.Whitespace),
+             "assignment"),
+            # Word operators
+            (words(OPERATORS_LIST["words"], prefix=r"\b", suffix=r"\b"),
+             Operator.Word),
+            # Statements
+            (words(STATEMENT_LIST, suffix=r"\b"), Keyword),
+            # Table names
+            (r"[a-z]\w*:", Keyword.Declaration),
+            # Constants
+            (words(CONSTANT_LIST, suffix=r"\b"), Keyword.Constant),
+            # Functions
+            (words(SCRIPT_FUNCTIONS, suffix=r"(?=\s*\()"), Name.Builtin,
+             "function"),
+            # interpolation - e.g. $(variableName)
+            include("interp"),
+            # Quotes denote a field/file name
+            (r'"', String.Symbol, "field_name_quote"),
+            # Square brackets denote a field/file name
+            (r"\[", String.Symbol, "field_name_bracket"),
+            # Strings
+            (r"'", String, "string"),
+            # Numbers
+            include("numerics"),
+            # Operator symbols
+            (words(OPERATORS_LIST["symbols"]), Operator),
+            # Strings denoted by single quotes
+            (r"'.+?'", String),
+            # Words as text
+            (r"\b\w+\b", Text),
+            # Basic punctuation
+            (r"[,;.()\\/]", Punctuation),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/qvt.py b/.venv/Lib/site-packages/pygments/lexers/qvt.py
new file mode 100644
index 0000000..302d1b6
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/qvt.py
@@ -0,0 +1,153 @@
+"""
+    pygments.lexers.qvt
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexer for QVT Operational language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, include, combined, default, \
+    words
+from pygments.token import Text, Comment, Operator, Keyword, Punctuation, \
+    Name, String, Number
+
+__all__ = ['QVToLexer']
+
+
+class QVToLexer(RegexLexer):
+    """
+    For the QVT Operational Mapping language.
+
+    Reference for implementing this: «Meta Object Facility (MOF) 2.0
+    Query/View/Transformation Specification», Version 1.1 - January 2011
+    (https://www.omg.org/spec/QVT/1.1/), see §8.4, «Concrete Syntax» in
+    particular.
+
+    Notable tokens assignments:
+
+    - Name.Class is assigned to the identifier following any of the following
+      keywords: metamodel, class, exception, primitive, enum, transformation
+      or library
+
+    - Name.Function is assigned to the names of mappings and queries
+
+    - Name.Builtin.Pseudo is assigned to the pre-defined variables 'this',
+      'self' and 'result'.
+    """
+    # With obvious borrowings & inspiration from the Java, Python and C lexers
+
+    name = 'QVTO'
+    aliases = ['qvto', 'qvt']
+    filenames = ['*.qvto']
+    url = 'https://www.omg.org/spec/QVT/1.1'
+    version_added = ''
+
+    tokens = {
+        'root': [
+            (r'\n', Text),
+            (r'[^\S\n]+', Text),
+            (r'(--|//)(\s*)(directive:)?(.*)$',
+             bygroups(Comment, Comment, Comment.Preproc, Comment)),
+            # Uncomment the following if you want to distinguish between
+            # '/*' and '/**', à la javadoc
+            # (r'/[*]{2}(.|\n)*?[*]/', Comment.Multiline),
+            (r'/[*](.|\n)*?[*]/', Comment.Multiline),
+            (r'\\\n', Text),
+            (r'(and|not|or|xor|##?)\b', Operator.Word),
+            (r'(:{1,2}=|[-+]=)\b', Operator.Word),
+            (r'(@|<<|>>)\b', Keyword),  # stereotypes
+            (r'!=|<>|==|=|!->|->|>=|<=|[.]{3}|[+/*%=<>&|.~]', Operator),
+            (r'[]{}:(),;[]', Punctuation),
+            (r'(true|false|unlimited|null)\b', Keyword.Constant),
+            (r'(this|self|result)\b', Name.Builtin.Pseudo),
+            (r'(var)\b', Keyword.Declaration),
+            (r'(from|import)\b', Keyword.Namespace, 'fromimport'),
+            (r'(metamodel|class|exception|primitive|enum|transformation|'
+             r'library)(\s+)(\w+)',
+             bygroups(Keyword.Word, Text, Name.Class)),
+            (r'(exception)(\s+)(\w+)',
+             bygroups(Keyword.Word, Text, Name.Exception)),
+            (r'(main)\b', Name.Function),
+            (r'(mapping|helper|query)(\s+)',
+             bygroups(Keyword.Declaration, Text), 'operation'),
+            (r'(assert)(\s+)\b', bygroups(Keyword, Text), 'assert'),
+            (r'(Bag|Collection|Dict|OrderedSet|Sequence|Set|Tuple|List)\b',
+             Keyword.Type),
+            include('keywords'),
+            ('"', String, combined('stringescape', 'dqs')),
+            ("'", String, combined('stringescape', 'sqs')),
+            include('name'),
+            include('numbers'),
+            # (r'([a-zA-Z_]\w*)(::)([a-zA-Z_]\w*)',
+            # bygroups(Text, Text, Text)),
+        ],
+
+        'fromimport': [
+            (r'(?:[ \t]|\\\n)+', Text),
+            (r'[a-zA-Z_][\w.]*', Name.Namespace),
+            default('#pop'),
+        ],
+
+        'operation': [
+            (r'::', Text),
+            (r'(.*::)([a-zA-Z_]\w*)([ \t]*)(\()',
+             bygroups(Text, Name.Function, Text, Punctuation), '#pop')
+        ],
+
+        'assert': [
+            (r'(warning|error|fatal)\b', Keyword, '#pop'),
+            default('#pop'),  # all else: go back
+        ],
+
+        'keywords': [
+            (words((
+                'abstract', 'access', 'any', 'assert', 'blackbox', 'break',
+                'case', 'collect', 'collectNested', 'collectOne', 'collectselect',
+                'collectselectOne', 'composes', 'compute', 'configuration',
+                'constructor', 'continue', 'datatype', 'default', 'derived',
+                'disjuncts', 'do', 'elif', 'else', 'end', 'endif', 'except',
+                'exists', 'extends', 'forAll', 'forEach', 'forOne', 'from', 'if',
+                'implies', 'in', 'inherits', 'init', 'inout', 'intermediate',
+                'invresolve', 'invresolveIn', 'invresolveone', 'invresolveoneIn',
+                'isUnique', 'iterate', 'late', 'let', 'literal', 'log', 'map',
+                'merges', 'modeltype', 'new', 'object', 'one', 'ordered', 'out',
+                'package', 'population', 'property', 'raise', 'readonly',
+                'references', 'refines', 'reject', 'resolve', 'resolveIn',
+                'resolveone', 'resolveoneIn', 'return', 'select', 'selectOne',
+                'sortedBy', 'static', 'switch', 'tag', 'then', 'try', 'typedef',
+                'unlimited', 'uses', 'when', 'where', 'while', 'with', 'xcollect',
+                'xmap', 'xselect'), suffix=r'\b'), Keyword),
+        ],
+
+        # There is no need to distinguish between String.Single and
+        # String.Double: 'strings' is factorised for 'dqs' and 'sqs'
+        'strings': [
+            (r'[^\\\'"\n]+', String),
+            # quotes, percents and backslashes must be parsed one at a time
+            (r'[\'"\\]', String),
+        ],
+        'stringescape': [
+            (r'\\([\\btnfr"\']|u[0-3][0-7]{2}|u[0-7]{1,2})', String.Escape)
+        ],
+        'dqs': [  # double-quoted string
+            (r'"', String, '#pop'),
+            (r'\\\\|\\"', String.Escape),
+            include('strings')
+        ],
+        'sqs': [  # single-quoted string
+            (r"'", String, '#pop'),
+            (r"\\\\|\\'", String.Escape),
+            include('strings')
+        ],
+        'name': [
+            (r'[a-zA-Z_]\w*', Name),
+        ],
+        # numbers: excerpt taken from the python lexer
+        'numbers': [
+            (r'(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?', Number.Float),
+            (r'\d+[eE][+-]?[0-9]+', Number.Float),
+            (r'\d+', Number.Integer)
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/r.py b/.venv/Lib/site-packages/pygments/lexers/r.py
new file mode 100644
index 0000000..d3f65ba
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/r.py
@@ -0,0 +1,196 @@
+"""
+    pygments.lexers.r
+    ~~~~~~~~~~~~~~~~~
+
+    Lexers for the R/S languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import Lexer, RegexLexer, include, do_insertions
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Generic, Whitespace
+
+__all__ = ['RConsoleLexer', 'SLexer', 'RdLexer']
+
+
+line_re  = re.compile('.*?\n')
+
+
+class RConsoleLexer(Lexer):
+    """
+    For R console transcripts or R CMD BATCH output files.
+    """
+
+    name = 'RConsole'
+    aliases = ['rconsole', 'rout']
+    filenames = ['*.Rout']
+    url = 'https://www.r-project.org'
+    version_added = ''
+    _example = "rconsole/r-console-transcript.Rout"
+
+    def get_tokens_unprocessed(self, text):
+        slexer = SLexer(**self.options)
+
+        current_code_block = ''
+        insertions = []
+
+        for match in line_re.finditer(text):
+            line = match.group()
+            if line.startswith('>') or line.startswith('+'):
+                # Colorize the prompt as such,
+                # then put rest of line into current_code_block
+                insertions.append((len(current_code_block),
+                                   [(0, Generic.Prompt, line[:2])]))
+                current_code_block += line[2:]
+            else:
+                # We have reached a non-prompt line!
+                # If we have stored prompt lines, need to process them first.
+                if current_code_block:
+                    # Weave together the prompts and highlight code.
+                    yield from do_insertions(
+                        insertions, slexer.get_tokens_unprocessed(current_code_block))
+                    # Reset vars for next code block.
+                    current_code_block = ''
+                    insertions = []
+                # Now process the actual line itself, this is output from R.
+                yield match.start(), Generic.Output, line
+
+        # If we happen to end on a code block with nothing after it, need to
+        # process the last code block. This is neither elegant nor DRY so
+        # should be changed.
+        if current_code_block:
+            yield from do_insertions(
+                insertions, slexer.get_tokens_unprocessed(current_code_block))
+
+
+class SLexer(RegexLexer):
+    """
+    For S, S-plus, and R source code.
+    """
+
+    name = 'S'
+    aliases = ['splus', 's', 'r']
+    filenames = ['*.S', '*.R', '.Rhistory', '.Rprofile', '.Renviron']
+    mimetypes = ['text/S-plus', 'text/S', 'text/x-r-source', 'text/x-r',
+                 'text/x-R', 'text/x-r-history', 'text/x-r-profile']
+    url = 'https://www.r-project.org'
+    version_added = '0.10'
+
+    valid_name = r'`[^`\\]*(?:\\.[^`\\]*)*`|(?:[a-zA-Z]|\.[A-Za-z_.])[\w.]*|\.'
+    tokens = {
+        'comments': [
+            (r'#.*$', Comment.Single),
+        ],
+        'valid_name': [
+            (valid_name, Name),
+        ],
+        'function_name': [
+            (rf'({valid_name})\s*(?=\()', Name.Function),
+        ],
+        'punctuation': [
+            (r'\[{1,2}|\]{1,2}|\(|\)|;|,', Punctuation),
+        ],
+        'keywords': [
+            (r'(if|else|for|while|repeat|in|next|break|return|switch|function)'
+             r'(?![\w.])',
+             Keyword.Reserved),
+        ],
+        'operators': [
+            (r'<>?|-|==|<=|>=|\|>|<|>|&&?|!=|\|\|?|\?', Operator),
+            (r'\*|\+|\^|/|!|%[^%]*%|=|~|\$|@|:{1,3}', Operator),
+        ],
+        'builtin_symbols': [
+            (r'(NULL|NA(_(integer|real|complex|character)_)?|'
+             r'letters|LETTERS|Inf|TRUE|FALSE|NaN|pi|\.\.(\.|[0-9]+))'
+             r'(?![\w.])',
+             Keyword.Constant),
+            (r'(T|F)\b', Name.Builtin.Pseudo),
+        ],
+        'numbers': [
+            # hex number
+            (r'0[xX][a-fA-F0-9]+([pP][0-9]+)?[Li]?', Number.Hex),
+            # decimal number
+            (r'[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+|\.)([eE][+-]?[0-9]+)?[Li]?',
+             Number),
+        ],
+        'statements': [
+            include('comments'),
+            # whitespaces
+            (r'\s+', Whitespace),
+            (r'\'', String, 'string_squote'),
+            (r'\"', String, 'string_dquote'),
+            include('builtin_symbols'),
+            include('keywords'),
+            include('function_name'),
+            include('valid_name'),
+            include('numbers'),
+            include('punctuation'),
+            include('operators'),
+        ],
+        'root': [
+            # calls:
+            include('statements'),
+            # blocks:
+            (r'\{|\}', Punctuation),
+            # (r'\{', Punctuation, 'block'),
+            (r'.', Text),
+        ],
+        # 'block': [
+        #    include('statements'),
+        #    ('\{', Punctuation, '#push'),
+        #    ('\}', Punctuation, '#pop')
+        # ],
+        'string_squote': [
+            (r'([^\'\\]|\\.)*\'', String, '#pop'),
+        ],
+        'string_dquote': [
+            (r'([^"\\]|\\.)*"', String, '#pop'),
+        ],
+    }
+
+    def analyse_text(text):
+        if re.search(r'[a-z0-9_\])\s]<-(?!-)', text):
+            return 0.11
+
+
+class RdLexer(RegexLexer):
+    """
+    Pygments Lexer for R documentation (Rd) files
+
+    This is a very minimal implementation, highlighting little more
+    than the macros. A description of Rd syntax is found in `Writing R
+    Extensions `_
+    and `Parsing Rd files `_.
+    """
+    name = 'Rd'
+    aliases = ['rd']
+    filenames = ['*.Rd']
+    mimetypes = ['text/x-r-doc']
+    url = 'http://cran.r-project.org/doc/manuals/R-exts.html'
+    version_added = '1.6'
+
+    # To account for verbatim / LaTeX-like / and R-like areas
+    # would require parsing.
+    tokens = {
+        'root': [
+            # catch escaped brackets and percent sign
+            (r'\\[\\{}%]', String.Escape),
+            # comments
+            (r'%.*$', Comment),
+            # special macros with no arguments
+            (r'\\(?:cr|l?dots|R|tab)\b', Keyword.Constant),
+            # macros
+            (r'\\[a-zA-Z]+\b', Keyword),
+            # special preprocessor macros
+            (r'^\s*#(?:ifn?def|endif).*\b', Comment.Preproc),
+            # non-escaped brackets
+            (r'[{}]', Name.Builtin),
+            # everything else
+            (r'[^\\%\n{}]+', Text),
+            (r'.', Text),
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/rdf.py b/.venv/Lib/site-packages/pygments/lexers/rdf.py
new file mode 100644
index 0000000..4930c1b
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/rdf.py
@@ -0,0 +1,468 @@
+"""
+    pygments.lexers.rdf
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for semantic web and RDF query languages and markup.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, bygroups, default
+from pygments.token import Keyword, Punctuation, String, Number, Operator, \
+    Generic, Whitespace, Name, Literal, Comment, Text
+
+__all__ = ['SparqlLexer', 'TurtleLexer', 'ShExCLexer']
+
+
+class SparqlLexer(RegexLexer):
+    """
+    Lexer for SPARQL query language.
+    """
+    name = 'SPARQL'
+    aliases = ['sparql']
+    filenames = ['*.rq', '*.sparql']
+    mimetypes = ['application/sparql-query']
+    url = 'https://www.w3.org/TR/sparql11-query'
+    version_added = '2.0'
+
+    # character group definitions ::
+
+    PN_CHARS_BASE_GRP = ('a-zA-Z'
+                         '\u00c0-\u00d6'
+                         '\u00d8-\u00f6'
+                         '\u00f8-\u02ff'
+                         '\u0370-\u037d'
+                         '\u037f-\u1fff'
+                         '\u200c-\u200d'
+                         '\u2070-\u218f'
+                         '\u2c00-\u2fef'
+                         '\u3001-\ud7ff'
+                         '\uf900-\ufdcf'
+                         '\ufdf0-\ufffd')
+
+    PN_CHARS_U_GRP = (PN_CHARS_BASE_GRP + '_')
+
+    PN_CHARS_GRP = (PN_CHARS_U_GRP +
+                    r'\-' +
+                    r'0-9' +
+                    '\u00b7' +
+                    '\u0300-\u036f' +
+                    '\u203f-\u2040')
+
+    HEX_GRP = '0-9A-Fa-f'
+
+    PN_LOCAL_ESC_CHARS_GRP = r' _~.\-!$&"()*+,;=/?#@%'
+
+    # terminal productions ::
+
+    PN_CHARS_BASE = '[' + PN_CHARS_BASE_GRP + ']'
+
+    PN_CHARS_U = '[' + PN_CHARS_U_GRP + ']'
+
+    PN_CHARS = '[' + PN_CHARS_GRP + ']'
+
+    HEX = '[' + HEX_GRP + ']'
+
+    PN_LOCAL_ESC_CHARS = '[' + PN_LOCAL_ESC_CHARS_GRP + ']'
+
+    IRIREF = r'<(?:[^<>"{}|^`\\\x00-\x20])*>'
+
+    BLANK_NODE_LABEL = '_:[0-9' + PN_CHARS_U_GRP + '](?:[' + PN_CHARS_GRP + \
+                       '.]*' + PN_CHARS + ')?'
+
+    PN_PREFIX = PN_CHARS_BASE + '(?:[' + PN_CHARS_GRP + '.]*' + PN_CHARS + ')?'
+
+    VARNAME = '[0-9' + PN_CHARS_U_GRP + '][' + PN_CHARS_U_GRP + \
+              '0-9\u00b7\u0300-\u036f\u203f-\u2040]*'
+
+    PERCENT = '%' + HEX + HEX
+
+    PN_LOCAL_ESC = r'\\' + PN_LOCAL_ESC_CHARS
+
+    PLX = '(?:' + PERCENT + ')|(?:' + PN_LOCAL_ESC + ')'
+
+    PN_LOCAL = ('(?:[' + PN_CHARS_U_GRP + ':0-9' + ']|' + PLX + ')' +
+                '(?:(?:[' + PN_CHARS_GRP + '.:]|' + PLX + ')*(?:[' +
+                PN_CHARS_GRP + ':]|' + PLX + '))?')
+
+    EXPONENT = r'[eE][+-]?\d+'
+
+    # Lexer token definitions ::
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+            # keywords ::
+            (r'(?i)(select|construct|describe|ask|where|filter|group\s+by|minus|'
+             r'distinct|reduced|from\s+named|from|order\s+by|desc|asc|limit|'
+             r'offset|values|bindings|load|into|clear|drop|create|add|move|copy|'
+             r'insert\s+data|delete\s+data|delete\s+where|with|delete|insert|'
+             r'using\s+named|using|graph|default|named|all|optional|service|'
+             r'silent|bind|undef|union|not\s+in|in|as|having|to|prefix|base)\b', Keyword),
+            (r'(a)\b', Keyword),
+            # IRIs ::
+            ('(' + IRIREF + ')', Name.Label),
+            # blank nodes ::
+            ('(' + BLANK_NODE_LABEL + ')', Name.Label),
+            #  # variables ::
+            ('[?$]' + VARNAME, Name.Variable),
+            # prefixed names ::
+            (r'(' + PN_PREFIX + r')?(\:)(' + PN_LOCAL + r')?',
+             bygroups(Name.Namespace, Punctuation, Name.Tag)),
+            # function names ::
+            (r'(?i)(str|lang|langmatches|datatype|bound|iri|uri|bnode|rand|abs|'
+             r'ceil|floor|round|concat|strlen|ucase|lcase|encode_for_uri|'
+             r'contains|strstarts|strends|strbefore|strafter|year|month|day|'
+             r'hours|minutes|seconds|timezone|tz|now|uuid|struuid|md5|sha1|sha256|sha384|'
+             r'sha512|coalesce|if|strlang|strdt|sameterm|isiri|isuri|isblank|'
+             r'isliteral|isnumeric|regex|substr|replace|exists|not\s+exists|'
+             r'count|sum|min|max|avg|sample|group_concat|separator)\b',
+             Name.Function),
+            # boolean literals ::
+            (r'(true|false)', Keyword.Constant),
+            # double literals ::
+            (r'[+\-]?(\d+\.\d*' + EXPONENT + r'|\.?\d+' + EXPONENT + ')', Number.Float),
+            # decimal literals ::
+            (r'[+\-]?(\d+\.\d*|\.\d+)', Number.Float),
+            # integer literals ::
+            (r'[+\-]?\d+', Number.Integer),
+            # operators ::
+            (r'(\|\||&&|=|\*|\-|\+|/|!=|<=|>=|!|<|>)', Operator),
+            # punctuation characters ::
+            (r'[(){}.;,:^\[\]]', Punctuation),
+            # line comments ::
+            (r'#[^\n]*', Comment),
+            # strings ::
+            (r'"""', String, 'triple-double-quoted-string'),
+            (r'"', String, 'single-double-quoted-string'),
+            (r"'''", String, 'triple-single-quoted-string'),
+            (r"'", String, 'single-single-quoted-string'),
+        ],
+        'triple-double-quoted-string': [
+            (r'"""', String, 'end-of-string'),
+            (r'[^\\]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'single-double-quoted-string': [
+            (r'"', String, 'end-of-string'),
+            (r'[^"\\\n]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'triple-single-quoted-string': [
+            (r"'''", String, 'end-of-string'),
+            (r'[^\\]+', String),
+            (r'\\', String.Escape, 'string-escape'),
+        ],
+        'single-single-quoted-string': [
+            (r"'", String, 'end-of-string'),
+            (r"[^'\\\n]+", String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'string-escape': [
+            (r'u' + HEX + '{4}', String.Escape, '#pop'),
+            (r'U' + HEX + '{8}', String.Escape, '#pop'),
+            (r'.', String.Escape, '#pop'),
+        ],
+        'end-of-string': [
+            (r'(@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)',
+             bygroups(Operator, Name.Function), '#pop:2'),
+            (r'\^\^', Operator, '#pop:2'),
+            default('#pop:2'),
+        ],
+    }
+
+
+class TurtleLexer(RegexLexer):
+    """
+    Lexer for Turtle data language.
+    """
+    name = 'Turtle'
+    aliases = ['turtle']
+    filenames = ['*.ttl']
+    mimetypes = ['text/turtle', 'application/x-turtle']
+    url = 'https://www.w3.org/TR/turtle'
+    version_added = '2.1'
+
+    # character group definitions ::
+    PN_CHARS_BASE_GRP = ('a-zA-Z'
+                         '\u00c0-\u00d6'
+                         '\u00d8-\u00f6'
+                         '\u00f8-\u02ff'
+                         '\u0370-\u037d'
+                         '\u037f-\u1fff'
+                         '\u200c-\u200d'
+                         '\u2070-\u218f'
+                         '\u2c00-\u2fef'
+                         '\u3001-\ud7ff'
+                         '\uf900-\ufdcf'
+                         '\ufdf0-\ufffd')
+
+    PN_CHARS_U_GRP = (PN_CHARS_BASE_GRP + '_')
+
+    PN_CHARS_GRP = (PN_CHARS_U_GRP +
+                    r'\-' +
+                    r'0-9' +
+                    '\u00b7' +
+                    '\u0300-\u036f' +
+                    '\u203f-\u2040')
+
+    PN_CHARS = '[' + PN_CHARS_GRP + ']'
+
+    PN_CHARS_BASE = '[' + PN_CHARS_BASE_GRP + ']'
+
+    PN_PREFIX = PN_CHARS_BASE + '(?:[' + PN_CHARS_GRP + '.]*' + PN_CHARS + ')?'
+
+    HEX_GRP = '0-9A-Fa-f'
+
+    HEX = '[' + HEX_GRP + ']'
+
+    PERCENT = '%' + HEX + HEX
+
+    PN_LOCAL_ESC_CHARS_GRP = r' _~.\-!$&"()*+,;=/?#@%'
+
+    PN_LOCAL_ESC_CHARS = '[' + PN_LOCAL_ESC_CHARS_GRP + ']'
+
+    PN_LOCAL_ESC = r'\\' + PN_LOCAL_ESC_CHARS
+
+    PLX = '(?:' + PERCENT + ')|(?:' + PN_LOCAL_ESC + ')'
+
+    PN_LOCAL = ('(?:[' + PN_CHARS_U_GRP + ':0-9' + ']|' + PLX + ')' +
+                '(?:(?:[' + PN_CHARS_GRP + '.:]|' + PLX + ')*(?:[' +
+                PN_CHARS_GRP + ':]|' + PLX + '))?')
+
+    patterns = {
+        'PNAME_NS': r'((?:[a-zA-Z][\w-]*)?\:)',  # Simplified character range
+        'IRIREF': r'(<[^<>"{}|^`\\\x00-\x20]*>)'
+    }
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+
+            # Base / prefix
+            (r'(@base|BASE)(\s+){IRIREF}(\s*)(\.?)'.format(**patterns),
+             bygroups(Keyword, Whitespace, Name.Variable, Whitespace,
+                      Punctuation)),
+            (r'(@prefix|PREFIX)(\s+){PNAME_NS}(\s+){IRIREF}(\s*)(\.?)'.format(**patterns),
+             bygroups(Keyword, Whitespace, Name.Namespace, Whitespace,
+                      Name.Variable, Whitespace, Punctuation)),
+
+            # The shorthand predicate 'a'
+            (r'(?<=\s)a(?=\s)', Keyword.Type),
+
+            # IRIREF
+            (r'{IRIREF}'.format(**patterns), Name.Variable),
+
+            # PrefixedName
+            (r'(' + PN_PREFIX + r')?(\:)(' + PN_LOCAL + r')?',
+             bygroups(Name.Namespace, Punctuation, Name.Tag)),
+
+            # BlankNodeLabel
+            (r'(_)(:)([' + PN_CHARS_U_GRP + r'0-9]([' + PN_CHARS_GRP + r'.]*' + PN_CHARS + ')?)',
+             bygroups(Name.Namespace, Punctuation, Name.Tag)),
+
+            # Comment
+            (r'#[^\n]+', Comment),
+
+            (r'\b(true|false)\b', Literal),
+            (r'[+\-]?\d*\.\d+', Number.Float),
+            (r'[+\-]?\d*(:?\.\d+)?E[+\-]?\d+', Number.Float),
+            (r'[+\-]?\d+', Number.Integer),
+            (r'[\[\](){}.;,:^]', Punctuation),
+
+            (r'"""', String, 'triple-double-quoted-string'),
+            (r'"', String, 'single-double-quoted-string'),
+            (r"'''", String, 'triple-single-quoted-string'),
+            (r"'", String, 'single-single-quoted-string'),
+        ],
+        'triple-double-quoted-string': [
+            (r'"""', String, 'end-of-string'),
+            (r'[^\\]+(?=""")', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'single-double-quoted-string': [
+            (r'"', String, 'end-of-string'),
+            (r'[^"\\\n]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'triple-single-quoted-string': [
+            (r"'''", String, 'end-of-string'),
+            (r"[^\\]+(?=''')", String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'single-single-quoted-string': [
+            (r"'", String, 'end-of-string'),
+            (r"[^'\\\n]+", String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'string-escape': [
+            (r'.', String, '#pop'),
+        ],
+        'end-of-string': [
+            (r'(@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)',
+             bygroups(Operator, Generic.Emph), '#pop:2'),
+
+            (r'(\^\^){IRIREF}'.format(**patterns), bygroups(Operator, Generic.Emph), '#pop:2'),
+
+            default('#pop:2'),
+
+        ],
+    }
+
+    # Turtle and Tera Term macro files share the same file extension
+    # but each has a recognizable and distinct syntax.
+    def analyse_text(text):
+        for t in ('@base ', 'BASE ', '@prefix ', 'PREFIX '):
+            if re.search(rf'^\s*{t}', text):
+                return 0.80
+
+
+class ShExCLexer(RegexLexer):
+    """
+    Lexer for ShExC shape expressions language syntax.
+    """
+    name = 'ShExC'
+    aliases = ['shexc', 'shex']
+    filenames = ['*.shex']
+    mimetypes = ['text/shex']
+    url = 'https://shex.io/shex-semantics/#shexc'
+    version_added = ''
+
+    # character group definitions ::
+
+    PN_CHARS_BASE_GRP = ('a-zA-Z'
+                         '\u00c0-\u00d6'
+                         '\u00d8-\u00f6'
+                         '\u00f8-\u02ff'
+                         '\u0370-\u037d'
+                         '\u037f-\u1fff'
+                         '\u200c-\u200d'
+                         '\u2070-\u218f'
+                         '\u2c00-\u2fef'
+                         '\u3001-\ud7ff'
+                         '\uf900-\ufdcf'
+                         '\ufdf0-\ufffd')
+
+    PN_CHARS_U_GRP = (PN_CHARS_BASE_GRP + '_')
+
+    PN_CHARS_GRP = (PN_CHARS_U_GRP +
+                    r'\-' +
+                    r'0-9' +
+                    '\u00b7' +
+                    '\u0300-\u036f' +
+                    '\u203f-\u2040')
+
+    HEX_GRP = '0-9A-Fa-f'
+
+    PN_LOCAL_ESC_CHARS_GRP = r"_~.\-!$&'()*+,;=/?#@%"
+
+    # terminal productions ::
+
+    PN_CHARS_BASE = '[' + PN_CHARS_BASE_GRP + ']'
+
+    PN_CHARS_U = '[' + PN_CHARS_U_GRP + ']'
+
+    PN_CHARS = '[' + PN_CHARS_GRP + ']'
+
+    HEX = '[' + HEX_GRP + ']'
+
+    PN_LOCAL_ESC_CHARS = '[' + PN_LOCAL_ESC_CHARS_GRP + ']'
+
+    UCHAR_NO_BACKSLASH = '(?:u' + HEX + '{4}|U' + HEX + '{8})'
+
+    UCHAR = r'\\' + UCHAR_NO_BACKSLASH
+
+    IRIREF = r'<(?:[^\x00-\x20<>"{}|^`\\]|' + UCHAR + ')*>'
+
+    BLANK_NODE_LABEL = '_:[0-9' + PN_CHARS_U_GRP + '](?:[' + PN_CHARS_GRP + \
+                       '.]*' + PN_CHARS + ')?'
+
+    PN_PREFIX = PN_CHARS_BASE + '(?:[' + PN_CHARS_GRP + '.]*' + PN_CHARS + ')?'
+
+    PERCENT = '%' + HEX + HEX
+
+    PN_LOCAL_ESC = r'\\' + PN_LOCAL_ESC_CHARS
+
+    PLX = '(?:' + PERCENT + ')|(?:' + PN_LOCAL_ESC + ')'
+
+    PN_LOCAL = ('(?:[' + PN_CHARS_U_GRP + ':0-9' + ']|' + PLX + ')' +
+                '(?:(?:[' + PN_CHARS_GRP + '.:]|' + PLX + ')*(?:[' +
+                PN_CHARS_GRP + ':]|' + PLX + '))?')
+
+    EXPONENT = r'[eE][+-]?\d+'
+
+    # Lexer token definitions ::
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+            # keywords ::
+            (r'(?i)(base|prefix|start|external|'
+             r'literal|iri|bnode|nonliteral|length|minlength|maxlength|'
+             r'mininclusive|minexclusive|maxinclusive|maxexclusive|'
+             r'totaldigits|fractiondigits|'
+             r'closed|extra)\b', Keyword),
+            (r'(a)\b', Keyword),
+            # IRIs ::
+            ('(' + IRIREF + ')', Name.Label),
+            # blank nodes ::
+            ('(' + BLANK_NODE_LABEL + ')', Name.Label),
+            # prefixed names ::
+            (r'(' + PN_PREFIX + r')?(\:)(' + PN_LOCAL + ')?',
+             bygroups(Name.Namespace, Punctuation, Name.Tag)),
+            # boolean literals ::
+            (r'(true|false)', Keyword.Constant),
+            # double literals ::
+            (r'[+\-]?(\d+\.\d*' + EXPONENT + r'|\.?\d+' + EXPONENT + ')', Number.Float),
+            # decimal literals ::
+            (r'[+\-]?(\d+\.\d*|\.\d+)', Number.Float),
+            # integer literals ::
+            (r'[+\-]?\d+', Number.Integer),
+            # operators ::
+            (r'[@|$&=*+?^\-~]', Operator),
+            # operator keywords ::
+            (r'(?i)(and|or|not)\b', Operator.Word),
+            # punctuation characters ::
+            (r'[(){}.;,:^\[\]]', Punctuation),
+            # line comments ::
+            (r'#[^\n]*', Comment),
+            # strings ::
+            (r'"""', String, 'triple-double-quoted-string'),
+            (r'"', String, 'single-double-quoted-string'),
+            (r"'''", String, 'triple-single-quoted-string'),
+            (r"'", String, 'single-single-quoted-string'),
+        ],
+        'triple-double-quoted-string': [
+            (r'"""', String, 'end-of-string'),
+            (r'[^\\]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'single-double-quoted-string': [
+            (r'"', String, 'end-of-string'),
+            (r'[^"\\\n]+', String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'triple-single-quoted-string': [
+            (r"'''", String, 'end-of-string'),
+            (r'[^\\]+', String),
+            (r'\\', String.Escape, 'string-escape'),
+        ],
+        'single-single-quoted-string': [
+            (r"'", String, 'end-of-string'),
+            (r"[^'\\\n]+", String),
+            (r'\\', String, 'string-escape'),
+        ],
+        'string-escape': [
+            (UCHAR_NO_BACKSLASH, String.Escape, '#pop'),
+            (r'.', String.Escape, '#pop'),
+        ],
+        'end-of-string': [
+            (r'(@)([a-zA-Z]+(?:-[a-zA-Z0-9]+)*)',
+             bygroups(Operator, Name.Function), '#pop:2'),
+            (r'\^\^', Operator, '#pop:2'),
+            default('#pop:2'),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/rebol.py b/.venv/Lib/site-packages/pygments/lexers/rebol.py
new file mode 100644
index 0000000..4b37a74
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/rebol.py
@@ -0,0 +1,419 @@
+"""
+    pygments.lexers.rebol
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the REBOL and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Generic, Whitespace
+
+__all__ = ['RebolLexer', 'RedLexer']
+
+
+class RebolLexer(RegexLexer):
+    """
+    A REBOL lexer.
+    """
+    name = 'REBOL'
+    aliases = ['rebol']
+    filenames = ['*.r', '*.r3', '*.reb']
+    mimetypes = ['text/x-rebol']
+    url = 'http://www.rebol.com'
+    version_added = '1.1'
+
+    flags = re.IGNORECASE | re.MULTILINE
+
+    escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)'
+
+    def word_callback(lexer, match):
+        word = match.group()
+
+        if re.match(".*:$", word):
+            yield match.start(), Generic.Subheading, word
+        elif re.match(
+            r'(native|alias|all|any|as-string|as-binary|bind|bound\?|case|'
+            r'catch|checksum|comment|debase|dehex|exclude|difference|disarm|'
+            r'either|else|enbase|foreach|remove-each|form|free|get|get-env|if|'
+            r'in|intersect|loop|minimum-of|maximum-of|mold|new-line|'
+            r'new-line\?|not|now|prin|print|reduce|compose|construct|repeat|'
+            r'reverse|save|script\?|set|shift|switch|throw|to-hex|trace|try|'
+            r'type\?|union|unique|unless|unprotect|unset|until|use|value\?|'
+            r'while|compress|decompress|secure|open|close|read|read-io|'
+            r'write-io|write|update|query|wait|input\?|exp|log-10|log-2|'
+            r'log-e|square-root|cosine|sine|tangent|arccosine|arcsine|'
+            r'arctangent|protect|lowercase|uppercase|entab|detab|connected\?|'
+            r'browse|launch|stats|get-modes|set-modes|to-local-file|'
+            r'to-rebol-file|encloak|decloak|create-link|do-browser|bind\?|'
+            r'hide|draw|show|size-text|textinfo|offset-to-caret|'
+            r'caret-to-offset|local-request-file|rgb-to-hsv|hsv-to-rgb|'
+            r'crypt-strength\?|dh-make-key|dh-generate-key|dh-compute-key|'
+            r'dsa-make-key|dsa-generate-key|dsa-make-signature|'
+            r'dsa-verify-signature|rsa-make-key|rsa-generate-key|'
+            r'rsa-encrypt)$', word):
+            yield match.start(), Name.Builtin, word
+        elif re.match(
+            r'(add|subtract|multiply|divide|remainder|power|and~|or~|xor~|'
+            r'minimum|maximum|negate|complement|absolute|random|head|tail|'
+            r'next|back|skip|at|pick|first|second|third|fourth|fifth|sixth|'
+            r'seventh|eighth|ninth|tenth|last|path|find|select|make|to|copy\*|'
+            r'insert|remove|change|poke|clear|trim|sort|min|max|abs|cp|'
+            r'copy)$', word):
+            yield match.start(), Name.Function, word
+        elif re.match(
+            r'(error|source|input|license|help|install|echo|Usage|with|func|'
+            r'throw-on-error|function|does|has|context|probe|\?\?|as-pair|'
+            r'mod|modulo|round|repend|about|set-net|append|join|rejoin|reform|'
+            r'remold|charset|array|replace|move|extract|forskip|forall|alter|'
+            r'first+|also|take|for|forever|dispatch|attempt|what-dir|'
+            r'change-dir|clean-path|list-dir|dirize|rename|split-path|delete|'
+            r'make-dir|delete-dir|in-dir|confirm|dump-obj|upgrade|what|'
+            r'build-tag|process-source|build-markup|decode-cgi|read-cgi|'
+            r'write-user|save-user|set-user-name|protect-system|parse-xml|'
+            r'cvs-date|cvs-version|do-boot|get-net-info|desktop|layout|'
+            r'scroll-para|get-face|alert|set-face|uninstall|unfocus|'
+            r'request-dir|center-face|do-events|net-error|decode-url|'
+            r'parse-header|parse-header-date|parse-email-addrs|import-email|'
+            r'send|build-attach-body|resend|show-popup|hide-popup|open-events|'
+            r'find-key-face|do-face|viewtop|confine|find-window|'
+            r'insert-event-func|remove-event-func|inform|dump-pane|dump-face|'
+            r'flag-face|deflag-face|clear-fields|read-net|vbug|path-thru|'
+            r'read-thru|load-thru|do-thru|launch-thru|load-image|'
+            r'request-download|do-face-alt|set-font|set-para|get-style|'
+            r'set-style|make-face|stylize|choose|hilight-text|hilight-all|'
+            r'unlight-text|focus|scroll-drag|clear-face|reset-face|scroll-face|'
+            r'resize-face|load-stock|load-stock-block|notify|request|flash|'
+            r'request-color|request-pass|request-text|request-list|'
+            r'request-date|request-file|dbug|editor|link-relative-path|'
+            r'emailer|parse-error)$', word):
+            yield match.start(), Keyword.Namespace, word
+        elif re.match(
+            r'(halt|quit|do|load|q|recycle|call|run|ask|parse|view|unview|'
+            r'return|exit|break)$', word):
+            yield match.start(), Name.Exception, word
+        elif re.match('REBOL$', word):
+            yield match.start(), Generic.Heading, word
+        elif re.match("to-.*", word):
+            yield match.start(), Keyword, word
+        elif re.match(r'(\+|-|\*|/|//|\*\*|and|or|xor|=\?|=|==|<>|<|>|<=|>=)$',
+                      word):
+            yield match.start(), Operator, word
+        elif re.match(r".*\?$", word):
+            yield match.start(), Keyword, word
+        elif re.match(r".*\!$", word):
+            yield match.start(), Keyword.Type, word
+        elif re.match("'.*", word):
+            yield match.start(), Name.Variable.Instance, word  # lit-word
+        elif re.match("#.*", word):
+            yield match.start(), Name.Label, word  # issue
+        elif re.match("%.*", word):
+            yield match.start(), Name.Decorator, word  # file
+        else:
+            yield match.start(), Name.Variable, word
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+            (r'#"', String.Char, 'char'),
+            (r'#\{[0-9a-f]*\}', Number.Hex),
+            (r'2#\{', Number.Hex, 'bin2'),
+            (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex),
+            (r'"', String, 'string'),
+            (r'\{', String, 'string2'),
+            (r';#+.*\n', Comment.Special),
+            (r';\*+.*\n', Comment.Preproc),
+            (r';.*\n', Comment),
+            (r'%"', Name.Decorator, 'stringFile'),
+            (r'%[^(^{")\s\[\]]+', Name.Decorator),
+            (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float),  # money
+            (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other),    # time
+            (r'\d+[\-/][0-9a-z]+[\-/]\d+(\/\d+\:\d+((\:\d+)?'
+             r'([.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other),   # date
+            (r'\d+(\.\d+)+\.\d+', Keyword.Constant),             # tuple
+            (r'\d+X\d+', Keyword.Constant),                   # pair
+            (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float),
+            (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float),
+            (r'[+-]?\d+(\'\d+)?', Number),
+            (r'[\[\]()]', Generic.Strong),
+            (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator),  # url
+            (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator),  # url
+            (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator),         # email
+            (r'comment\s"', Comment, 'commentString1'),
+            (r'comment\s\{', Comment, 'commentString2'),
+            (r'comment\s\[', Comment, 'commentBlock'),
+            (r'comment\s[^(\s{"\[]+', Comment),
+            (r'/[^(^{")\s/[\]]*', Name.Attribute),
+            (r'([^(^{")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback),
+            (r'<[\w:.-]*>', Name.Tag),
+            (r'<[^(<>\s")]+', Name.Tag, 'tag'),
+            (r'([^(^{")\s]+)', Text),
+        ],
+        'string': [
+            (r'[^(^")]+', String),
+            (escape_re, String.Escape),
+            (r'[(|)]+', String),
+            (r'\^.', String.Escape),
+            (r'"', String, '#pop'),
+        ],
+        'string2': [
+            (r'[^(^{})]+', String),
+            (escape_re, String.Escape),
+            (r'[(|)]+', String),
+            (r'\^.', String.Escape),
+            (r'\{', String, '#push'),
+            (r'\}', String, '#pop'),
+        ],
+        'stringFile': [
+            (r'[^(^")]+', Name.Decorator),
+            (escape_re, Name.Decorator),
+            (r'\^.', Name.Decorator),
+            (r'"', Name.Decorator, '#pop'),
+        ],
+        'char': [
+            (escape_re + '"', String.Char, '#pop'),
+            (r'\^."', String.Char, '#pop'),
+            (r'."', String.Char, '#pop'),
+        ],
+        'tag': [
+            (escape_re, Name.Tag),
+            (r'"', Name.Tag, 'tagString'),
+            (r'[^(<>\r\n")]+', Name.Tag),
+            (r'>', Name.Tag, '#pop'),
+        ],
+        'tagString': [
+            (r'[^(^")]+', Name.Tag),
+            (escape_re, Name.Tag),
+            (r'[(|)]+', Name.Tag),
+            (r'\^.', Name.Tag),
+            (r'"', Name.Tag, '#pop'),
+        ],
+        'tuple': [
+            (r'(\d+\.)+', Keyword.Constant),
+            (r'\d+', Keyword.Constant, '#pop'),
+        ],
+        'bin2': [
+            (r'\s+', Number.Hex),
+            (r'([01]\s*){8}', Number.Hex),
+            (r'\}', Number.Hex, '#pop'),
+        ],
+        'commentString1': [
+            (r'[^(^")]+', Comment),
+            (escape_re, Comment),
+            (r'[(|)]+', Comment),
+            (r'\^.', Comment),
+            (r'"', Comment, '#pop'),
+        ],
+        'commentString2': [
+            (r'[^(^{})]+', Comment),
+            (escape_re, Comment),
+            (r'[(|)]+', Comment),
+            (r'\^.', Comment),
+            (r'\{', Comment, '#push'),
+            (r'\}', Comment, '#pop'),
+        ],
+        'commentBlock': [
+            (r'\[', Comment, '#push'),
+            (r'\]', Comment, '#pop'),
+            (r'"', Comment, "commentString1"),
+            (r'\{', Comment, "commentString2"),
+            (r'[^(\[\]"{)]+', Comment),
+        ],
+    }
+
+    def analyse_text(text):
+        """
+        Check if code contains REBOL header and so it probably not R code
+        """
+        if re.match(r'^\s*REBOL\s*\[', text, re.IGNORECASE):
+            # The code starts with REBOL header
+            return 1.0
+        elif re.search(r'\s*REBOL\s*\[', text, re.IGNORECASE):
+            # The code contains REBOL header but also some text before it
+            return 0.5
+
+
+class RedLexer(RegexLexer):
+    """
+    A Red-language lexer.
+    """
+    name = 'Red'
+    aliases = ['red', 'red/system']
+    filenames = ['*.red', '*.reds']
+    mimetypes = ['text/x-red', 'text/x-red-system']
+    url = 'https://www.red-lang.org'
+    version_added = '2.0'
+
+    flags = re.IGNORECASE | re.MULTILINE
+
+    escape_re = r'(?:\^\([0-9a-f]{1,4}\)*)'
+
+    def word_callback(lexer, match):
+        word = match.group()
+
+        if re.match(".*:$", word):
+            yield match.start(), Generic.Subheading, word
+        elif re.match(r'(if|unless|either|any|all|while|until|loop|repeat|'
+                      r'foreach|forall|func|function|does|has|switch|'
+                      r'case|reduce|compose|get|set|print|prin|equal\?|'
+                      r'not-equal\?|strict-equal\?|lesser\?|greater\?|lesser-or-equal\?|'
+                      r'greater-or-equal\?|same\?|not|type\?|stats|'
+                      r'bind|union|replace|charset|routine)$', word):
+            yield match.start(), Name.Builtin, word
+        elif re.match(r'(make|random|reflect|to|form|mold|absolute|add|divide|multiply|negate|'
+                      r'power|remainder|round|subtract|even\?|odd\?|and~|complement|or~|xor~|'
+                      r'append|at|back|change|clear|copy|find|head|head\?|index\?|insert|'
+                      r'length\?|next|pick|poke|remove|reverse|select|sort|skip|swap|tail|tail\?|'
+                      r'take|trim|create|close|delete|modify|open|open\?|query|read|rename|'
+                      r'update|write)$', word):
+            yield match.start(), Name.Function, word
+        elif re.match(r'(yes|on|no|off|true|false|tab|cr|lf|newline|escape|slash|sp|space|null|'
+                      r'none|crlf|dot|null-byte)$', word):
+            yield match.start(), Name.Builtin.Pseudo, word
+        elif re.match(r'(#system-global|#include|#enum|#define|#either|#if|#import|#export|'
+                      r'#switch|#default|#get-definition)$', word):
+            yield match.start(), Keyword.Namespace, word
+        elif re.match(r'(system|halt|quit|quit-return|do|load|q|recycle|call|run|ask|parse|'
+                      r'raise-error|return|exit|break|alias|push|pop|probe|\?\?|spec-of|body-of|'
+                      r'quote|forever)$', word):
+            yield match.start(), Name.Exception, word
+        elif re.match(r'(action\?|block\?|char\?|datatype\?|file\?|function\?|get-path\?|zero\?|'
+                      r'get-word\?|integer\?|issue\?|lit-path\?|lit-word\?|logic\?|native\?|'
+                      r'op\?|paren\?|path\?|refinement\?|set-path\?|set-word\?|string\?|unset\?|'
+                      r'any-struct\?|none\?|word\?|any-series\?)$', word):
+            yield match.start(), Keyword, word
+        elif re.match(r'(JNICALL|stdcall|cdecl|infix)$', word):
+            yield match.start(), Keyword.Namespace, word
+        elif re.match("to-.*", word):
+            yield match.start(), Keyword, word
+        elif re.match(r'(\+|-\*\*|-|\*\*|//|/|\*|and|or|xor|=\?|===|==|=|<>|<=|>=|'
+                      r'<<<|>>>|<<|>>|<|>%)$', word):
+            yield match.start(), Operator, word
+        elif re.match(r".*\!$", word):
+            yield match.start(), Keyword.Type, word
+        elif re.match("'.*", word):
+            yield match.start(), Name.Variable.Instance, word  # lit-word
+        elif re.match("#.*", word):
+            yield match.start(), Name.Label, word  # issue
+        elif re.match("%.*", word):
+            yield match.start(), Name.Decorator, word  # file
+        elif re.match(":.*", word):
+            yield match.start(), Generic.Subheading, word  # get-word
+        else:
+            yield match.start(), Name.Variable, word
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+            (r'#"', String.Char, 'char'),
+            (r'#\{[0-9a-f\s]*\}', Number.Hex),
+            (r'2#\{', Number.Hex, 'bin2'),
+            (r'64#\{[0-9a-z+/=\s]*\}', Number.Hex),
+            (r'([0-9a-f]+)(h)((\s)|(?=[\[\]{}"()]))',
+             bygroups(Number.Hex, Name.Variable, Whitespace)),
+            (r'"', String, 'string'),
+            (r'\{', String, 'string2'),
+            (r';#+.*\n', Comment.Special),
+            (r';\*+.*\n', Comment.Preproc),
+            (r';.*\n', Comment),
+            (r'%"', Name.Decorator, 'stringFile'),
+            (r'%[^(^{")\s\[\]]+', Name.Decorator),
+            (r'[+-]?([a-z]{1,3})?\$\d+(\.\d+)?', Number.Float),  # money
+            (r'[+-]?\d+\:\d+(\:\d+)?(\.\d+)?', String.Other),    # time
+            (r'\d+[\-/][0-9a-z]+[\-/]\d+(/\d+:\d+((:\d+)?'
+             r'([\.\d+]?([+-]?\d+:\d+)?)?)?)?', String.Other),   # date
+            (r'\d+(\.\d+)+\.\d+', Keyword.Constant),             # tuple
+            (r'\d+X\d+', Keyword.Constant),                   # pair
+            (r'[+-]?\d+(\'\d+)?([.,]\d*)?E[+-]?\d+', Number.Float),
+            (r'[+-]?\d+(\'\d+)?[.,]\d*', Number.Float),
+            (r'[+-]?\d+(\'\d+)?', Number),
+            (r'[\[\]()]', Generic.Strong),
+            (r'[a-z]+[^(^{"\s:)]*://[^(^{"\s)]*', Name.Decorator),  # url
+            (r'mailto:[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator),  # url
+            (r'[^(^{"@\s)]+@[^(^{"@\s)]+', Name.Decorator),         # email
+            (r'comment\s"', Comment, 'commentString1'),
+            (r'comment\s\{', Comment, 'commentString2'),
+            (r'comment\s\[', Comment, 'commentBlock'),
+            (r'comment\s[^(\s{"\[]+', Comment),
+            (r'/[^(^{^")\s/[\]]*', Name.Attribute),
+            (r'([^(^{^")\s/[\]]+)(?=[:({"\s/\[\]])', word_callback),
+            (r'<[\w:.-]*>', Name.Tag),
+            (r'<[^(<>\s")]+', Name.Tag, 'tag'),
+            (r'([^(^{")\s]+)', Text),
+        ],
+        'string': [
+            (r'[^(^")]+', String),
+            (escape_re, String.Escape),
+            (r'[(|)]+', String),
+            (r'\^.', String.Escape),
+            (r'"', String, '#pop'),
+        ],
+        'string2': [
+            (r'[^(^{})]+', String),
+            (escape_re, String.Escape),
+            (r'[(|)]+', String),
+            (r'\^.', String.Escape),
+            (r'\{', String, '#push'),
+            (r'\}', String, '#pop'),
+        ],
+        'stringFile': [
+            (r'[^(^")]+', Name.Decorator),
+            (escape_re, Name.Decorator),
+            (r'\^.', Name.Decorator),
+            (r'"', Name.Decorator, '#pop'),
+        ],
+        'char': [
+            (escape_re + '"', String.Char, '#pop'),
+            (r'\^."', String.Char, '#pop'),
+            (r'."', String.Char, '#pop'),
+        ],
+        'tag': [
+            (escape_re, Name.Tag),
+            (r'"', Name.Tag, 'tagString'),
+            (r'[^(<>\r\n")]+', Name.Tag),
+            (r'>', Name.Tag, '#pop'),
+        ],
+        'tagString': [
+            (r'[^(^")]+', Name.Tag),
+            (escape_re, Name.Tag),
+            (r'[(|)]+', Name.Tag),
+            (r'\^.', Name.Tag),
+            (r'"', Name.Tag, '#pop'),
+        ],
+        'tuple': [
+            (r'(\d+\.)+', Keyword.Constant),
+            (r'\d+', Keyword.Constant, '#pop'),
+        ],
+        'bin2': [
+            (r'\s+', Number.Hex),
+            (r'([01]\s*){8}', Number.Hex),
+            (r'\}', Number.Hex, '#pop'),
+        ],
+        'commentString1': [
+            (r'[^(^")]+', Comment),
+            (escape_re, Comment),
+            (r'[(|)]+', Comment),
+            (r'\^.', Comment),
+            (r'"', Comment, '#pop'),
+        ],
+        'commentString2': [
+            (r'[^(^{})]+', Comment),
+            (escape_re, Comment),
+            (r'[(|)]+', Comment),
+            (r'\^.', Comment),
+            (r'\{', Comment, '#push'),
+            (r'\}', Comment, '#pop'),
+        ],
+        'commentBlock': [
+            (r'\[', Comment, '#push'),
+            (r'\]', Comment, '#pop'),
+            (r'"', Comment, "commentString1"),
+            (r'\{', Comment, "commentString2"),
+            (r'[^(\[\]"{)]+', Comment),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/rego.py b/.venv/Lib/site-packages/pygments/lexers/rego.py
new file mode 100644
index 0000000..6f2e3e9
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/rego.py
@@ -0,0 +1,57 @@
+"""
+    pygments.lexers.rego
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the Rego policy languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words
+from pygments.token import Comment, Operator, Keyword, Name, String, Number, Punctuation, Whitespace
+
+class RegoLexer(RegexLexer):
+    """
+    For Rego source.
+    """
+    name = 'Rego'
+    url = 'https://www.openpolicyagent.org/docs/latest/policy-language/'
+    filenames = ['*.rego']
+    aliases = ['rego']
+    mimetypes = ['text/x-rego']
+    version_added = '2.19'
+
+    reserved_words = (
+        'as', 'contains', 'data', 'default', 'else', 'every', 'false',
+        'if', 'in', 'import', 'package', 'not', 'null',
+        'some', 'true', 'with'
+    )
+
+    builtins = (
+        # https://www.openpolicyagent.org/docs/latest/philosophy/#the-opa-document-model
+        'data',  # Global variable for accessing base and virtual documents
+        'input', # Represents synchronously pushed base documents
+    )
+
+    tokens = {
+        'root': [
+            (r'\n', Whitespace),
+            (r'\s+', Whitespace),
+            (r'#.*?$', Comment.Single),
+            (words(reserved_words, suffix=r'\b'), Keyword),
+            (words(builtins, suffix=r'\b'), Name.Builtin),
+            (r'[a-zA-Z_][a-zA-Z0-9_]*', Name),
+            (r'"(\\\\|\\"|[^"])*"', String.Double),
+            (r'`[^`]*`', String.Backtick),
+            (r'-?\d+(\.\d+)?', Number),
+            (r'(==|!=|<=|>=|:=)', Operator),  # Compound operators
+            (r'[=<>+\-*/%&|]', Operator),     # Single-character operators
+            (r'[\[\]{}(),.:;]', Punctuation),
+        ]
+    }
+
+__all__ = ['RegoLexer']
+
+
+
diff --git a/.venv/Lib/site-packages/pygments/lexers/resource.py b/.venv/Lib/site-packages/pygments/lexers/resource.py
new file mode 100644
index 0000000..9593c21
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/resource.py
@@ -0,0 +1,83 @@
+"""
+    pygments.lexers.resource
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for resource definition files.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, bygroups, words
+from pygments.token import Comment, String, Number, Operator, Text, \
+    Keyword, Name
+
+__all__ = ['ResourceLexer']
+
+
+class ResourceLexer(RegexLexer):
+    """Lexer for ICU Resource bundles.
+    """
+    name = 'ResourceBundle'
+    aliases = ['resourcebundle', 'resource']
+    filenames = []
+    url = 'https://unicode-org.github.io/icu/userguide/locale/resources.html'
+    version_added = '2.0'
+
+    _types = (':table', ':array', ':string', ':bin', ':import', ':intvector',
+              ':int', ':alias')
+
+    flags = re.MULTILINE | re.IGNORECASE
+    tokens = {
+        'root': [
+            (r'//.*?$', Comment),
+            (r'"', String, 'string'),
+            (r'-?\d+', Number.Integer),
+            (r'[,{}]', Operator),
+            (r'([^\s{{:]+)(\s*)({}?)'.format('|'.join(_types)),
+             bygroups(Name, Text, Keyword)),
+            (r'\s+', Text),
+            (words(_types), Keyword),
+        ],
+        'string': [
+            (r'(\\x[0-9a-f]{2}|\\u[0-9a-f]{4}|\\U00[0-9a-f]{6}|'
+             r'\\[0-7]{1,3}|\\c.|\\[abtnvfre\'"?\\]|\\\{|[^"{\\])+', String),
+            (r'\{', String.Escape, 'msgname'),
+            (r'"', String, '#pop')
+        ],
+        'msgname': [
+            (r'([^{},]+)(\s*)', bygroups(Name, String.Escape), ('#pop', 'message'))
+        ],
+        'message': [
+            (r'\{', String.Escape, 'msgname'),
+            (r'\}', String.Escape, '#pop'),
+            (r'(,)(\s*)([a-z]+)(\s*\})',
+             bygroups(Operator, String.Escape, Keyword, String.Escape), '#pop'),
+            (r'(,)(\s*)([a-z]+)(\s*)(,)(\s*)(offset)(\s*)(:)(\s*)(-?\d+)(\s*)',
+             bygroups(Operator, String.Escape, Keyword, String.Escape, Operator,
+                      String.Escape, Operator.Word, String.Escape, Operator,
+                      String.Escape, Number.Integer, String.Escape), 'choice'),
+            (r'(,)(\s*)([a-z]+)(\s*)(,)(\s*)',
+             bygroups(Operator, String.Escape, Keyword, String.Escape, Operator,
+                      String.Escape), 'choice'),
+            (r'\s+', String.Escape)
+        ],
+        'choice': [
+            (r'(=|<|>|<=|>=|!=)(-?\d+)(\s*\{)',
+             bygroups(Operator, Number.Integer, String.Escape), 'message'),
+            (r'([a-z]+)(\s*\{)', bygroups(Keyword.Type, String.Escape), 'str'),
+            (r'\}', String.Escape, ('#pop', '#pop')),
+            (r'\s+', String.Escape)
+        ],
+        'str': [
+            (r'\}', String.Escape, '#pop'),
+            (r'\{', String.Escape, 'msgname'),
+            (r'[^{}]+', String)
+        ]
+    }
+
+    def analyse_text(text):
+        if text.startswith('root:table'):
+            return 1.0
diff --git a/.venv/Lib/site-packages/pygments/lexers/ride.py b/.venv/Lib/site-packages/pygments/lexers/ride.py
new file mode 100644
index 0000000..4d60c29
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/ride.py
@@ -0,0 +1,138 @@
+"""
+    pygments.lexers.ride
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for the Ride programming language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words, include
+from pygments.token import Comment, Keyword, Name, Number, Punctuation, \
+    String, Text
+
+__all__ = ['RideLexer']
+
+
+class RideLexer(RegexLexer):
+    """
+    For Ride source code.
+    """
+
+    name = 'Ride'
+    aliases = ['ride']
+    filenames = ['*.ride']
+    mimetypes = ['text/x-ride']
+    url = 'https://docs.waves.tech/en/ride'
+    version_added = '2.6'
+
+    validName = r'[a-zA-Z_][a-zA-Z0-9_\']*'
+
+    builtinOps = (
+        '||', '|', '>=', '>', '==', '!',
+        '=', '<=', '<', '::', ':+', ':', '!=', '/',
+        '.', '=>', '-', '+', '*', '&&', '%', '++',
+    )
+
+    globalVariablesName = (
+        'NOALG', 'MD5', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512',
+        'SHA3224', 'SHA3256', 'SHA3384', 'SHA3512', 'nil', 'this', 'unit',
+        'height', 'lastBlock', 'Buy', 'Sell', 'CEILING', 'FLOOR', 'DOWN',
+        'HALFDOWN', 'HALFEVEN', 'HALFUP', 'UP',
+    )
+
+    typesName = (
+        'Unit', 'Int', 'Boolean', 'ByteVector', 'String', 'Address', 'Alias',
+        'Transfer', 'AssetPair', 'DataEntry', 'Order', 'Transaction',
+        'GenesisTransaction', 'PaymentTransaction', 'ReissueTransaction',
+        'BurnTransaction', 'MassTransferTransaction', 'ExchangeTransaction',
+        'TransferTransaction', 'SetAssetScriptTransaction',
+        'InvokeScriptTransaction', 'IssueTransaction', 'LeaseTransaction',
+        'LeaseCancelTransaction', 'CreateAliasTransaction',
+        'SetScriptTransaction', 'SponsorFeeTransaction', 'DataTransaction',
+        'WriteSet', 'AttachedPayment', 'ScriptTransfer', 'TransferSet',
+        'ScriptResult', 'Invocation', 'Asset', 'BlockInfo', 'Issue', 'Reissue',
+        'Burn', 'NoAlg', 'Md5', 'Sha1', 'Sha224', 'Sha256', 'Sha384', 'Sha512',
+        'Sha3224', 'Sha3256', 'Sha3384', 'Sha3512', 'BinaryEntry',
+        'BooleanEntry', 'IntegerEntry', 'StringEntry', 'List', 'Ceiling',
+        'Down', 'Floor', 'HalfDown', 'HalfEven', 'HalfUp', 'Up',
+    )
+
+    functionsName = (
+        'fraction', 'size', 'toBytes', 'take', 'drop', 'takeRight', 'dropRight',
+        'toString', 'isDefined', 'extract', 'throw', 'getElement', 'value',
+        'cons', 'toUtf8String', 'toInt', 'indexOf', 'lastIndexOf', 'split',
+        'parseInt', 'parseIntValue', 'keccak256', 'blake2b256', 'sha256',
+        'sigVerify', 'toBase58String', 'fromBase58String', 'toBase64String',
+        'fromBase64String', 'transactionById', 'transactionHeightById',
+        'getInteger', 'getBoolean', 'getBinary', 'getString',
+        'addressFromPublicKey', 'addressFromString', 'addressFromRecipient',
+        'assetBalance', 'wavesBalance', 'getIntegerValue', 'getBooleanValue',
+        'getBinaryValue', 'getStringValue', 'addressFromStringValue',
+        'assetInfo', 'rsaVerify', 'checkMerkleProof', 'median',
+        'valueOrElse', 'valueOrErrorMessage', 'contains', 'log', 'pow',
+        'toBase16String', 'fromBase16String', 'blockInfoByHeight',
+        'transferTransactionById',
+    )
+
+    reservedWords = words((
+        'match', 'case', 'else', 'func', 'if',
+        'let', 'then', '@Callable', '@Verifier',
+    ), suffix=r'\b')
+
+    tokens = {
+        'root': [
+            # Comments
+            (r'#.*', Comment.Single),
+            # Whitespace
+            (r'\s+', Text),
+            # Strings
+            (r'"', String, 'doublequote'),
+            (r'utf8\'', String, 'utf8quote'),
+            (r'base(58|64|16)\'', String, 'singlequote'),
+            # Keywords
+            (reservedWords, Keyword.Reserved),
+            (r'\{-#.*?#-\}', Keyword.Reserved),
+            (r'FOLD<\d+>', Keyword.Reserved),
+            # Types
+            (words(typesName), Keyword.Type),
+            # Main
+            # (specialName, Keyword.Reserved),
+            # Prefix Operators
+            (words(builtinOps, prefix=r'\(', suffix=r'\)'), Name.Function),
+            # Infix Operators
+            (words(builtinOps), Name.Function),
+            (words(globalVariablesName), Name.Function),
+            (words(functionsName), Name.Function),
+            # Numbers
+            include('numbers'),
+            # Variable Names
+            (validName, Name.Variable),
+            # Parens
+            (r'[,()\[\]{}]', Punctuation),
+        ],
+
+        'doublequote': [
+            (r'\\u[0-9a-fA-F]{4}', String.Escape),
+            (r'\\[nrfvb\\"]', String.Escape),
+            (r'[^"]', String),
+            (r'"', String, '#pop'),
+        ],
+
+        'utf8quote': [
+            (r'\\u[0-9a-fA-F]{4}', String.Escape),
+            (r'\\[nrfvb\\\']', String.Escape),
+            (r'[^\']', String),
+            (r'\'', String, '#pop'),
+        ],
+
+        'singlequote': [
+            (r'[^\']', String),
+            (r'\'', String, '#pop'),
+        ],
+
+        'numbers': [
+            (r'_?\d+', Number.Integer),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/rita.py b/.venv/Lib/site-packages/pygments/lexers/rita.py
new file mode 100644
index 0000000..536aaff
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/rita.py
@@ -0,0 +1,42 @@
+"""
+    pygments.lexers.rita
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for RITA language
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer
+from pygments.token import Comment, Operator, Keyword, Name, Literal, \
+    Punctuation, Whitespace
+
+__all__ = ['RitaLexer']
+
+
+class RitaLexer(RegexLexer):
+    """
+    Lexer for RITA.
+    """
+    name = 'Rita'
+    url = 'https://github.com/zaibacu/rita-dsl'
+    filenames = ['*.rita']
+    aliases = ['rita']
+    mimetypes = ['text/rita']
+    version_added = '2.11'
+
+    tokens = {
+        'root': [
+            (r'\n', Whitespace),
+            (r'\s+', Whitespace),
+            (r'#(.*?)\n', Comment.Single),
+            (r'@(.*?)\n', Operator),  # Yes, whole line as an operator
+            (r'"(\w|\d|\s|(\\")|[\'_\-./,\?\!])+?"', Literal),
+            (r'\'(\w|\d|\s|(\\\')|["_\-./,\?\!])+?\'', Literal),
+            (r'([A-Z_]+)', Keyword),
+            (r'([a-z0-9_]+)', Name),
+            (r'((->)|[!?+*|=])', Operator),
+            (r'[\(\),\{\}]', Punctuation)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/rnc.py b/.venv/Lib/site-packages/pygments/lexers/rnc.py
new file mode 100644
index 0000000..b7a06bb
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/rnc.py
@@ -0,0 +1,66 @@
+"""
+    pygments.lexers.rnc
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Relax-NG Compact syntax
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Punctuation
+
+__all__ = ['RNCCompactLexer']
+
+
+class RNCCompactLexer(RegexLexer):
+    """
+    For RelaxNG-compact syntax.
+    """
+
+    name = 'Relax-NG Compact'
+    url = 'http://relaxng.org'
+    aliases = ['rng-compact', 'rnc']
+    filenames = ['*.rnc']
+    version_added = '2.2'
+
+    tokens = {
+        'root': [
+            (r'namespace\b', Keyword.Namespace),
+            (r'(?:default|datatypes)\b', Keyword.Declaration),
+            (r'##.*$', Comment.Preproc),
+            (r'#.*$', Comment.Single),
+            (r'"[^"]*"', String.Double),
+            # TODO single quoted strings and escape sequences outside of
+            # double-quoted strings
+            (r'(?:element|attribute|mixed)\b', Keyword.Declaration, 'variable'),
+            (r'(text\b|xsd:[^ ]+)', Keyword.Type, 'maybe_xsdattributes'),
+            (r'[,?&*=|~]|>>', Operator),
+            (r'[(){}]', Punctuation),
+            (r'.', Text),
+        ],
+
+        # a variable has been declared using `element` or `attribute`
+        'variable': [
+            (r'[^{]+', Name.Variable),
+            (r'\{', Punctuation, '#pop'),
+        ],
+
+        # after an xsd: declaration there may be attributes
+        'maybe_xsdattributes': [
+            (r'\{', Punctuation, 'xsdattributes'),
+            (r'\}', Punctuation, '#pop'),
+            (r'.', Text),
+        ],
+
+        # attributes take the form { key1 = value1 key2 = value2 ... }
+        'xsdattributes': [
+            (r'[^ =}]', Name.Attribute),
+            (r'=', Operator),
+            (r'"[^"]*"', String.Double),
+            (r'\}', Punctuation, '#pop'),
+            (r'.', Text),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/roboconf.py b/.venv/Lib/site-packages/pygments/lexers/roboconf.py
new file mode 100644
index 0000000..31adba9
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/roboconf.py
@@ -0,0 +1,81 @@
+"""
+    pygments.lexers.roboconf
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Roboconf DSL.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words, re
+from pygments.token import Text, Operator, Keyword, Name, Comment
+
+__all__ = ['RoboconfGraphLexer', 'RoboconfInstancesLexer']
+
+
+class RoboconfGraphLexer(RegexLexer):
+    """
+    Lexer for Roboconf graph files.
+    """
+    name = 'Roboconf Graph'
+    aliases = ['roboconf-graph']
+    filenames = ['*.graph']
+    url = 'https://roboconf.github.io/en/user-guide/graph-definition.html'
+    version_added = '2.1'
+
+    flags = re.IGNORECASE | re.MULTILINE
+    tokens = {
+        'root': [
+            # Skip white spaces
+            (r'\s+', Text),
+
+            # There is one operator
+            (r'=', Operator),
+
+            # Keywords
+            (words(('facet', 'import'), suffix=r'\s*\b', prefix=r'\b'), Keyword),
+            (words((
+                'installer', 'extends', 'exports', 'imports', 'facets',
+                'children'), suffix=r'\s*:?', prefix=r'\b'), Name),
+
+            # Comments
+            (r'#.*\n', Comment),
+
+            # Default
+            (r'[^#]', Text),
+            (r'.*\n', Text)
+        ]
+    }
+
+
+class RoboconfInstancesLexer(RegexLexer):
+    """
+    Lexer for Roboconf instances files.
+    """
+    name = 'Roboconf Instances'
+    aliases = ['roboconf-instances']
+    filenames = ['*.instances']
+    url = 'https://roboconf.github.io'
+    version_added = '2.1'
+
+    flags = re.IGNORECASE | re.MULTILINE
+    tokens = {
+        'root': [
+
+            # Skip white spaces
+            (r'\s+', Text),
+
+            # Keywords
+            (words(('instance of', 'import'), suffix=r'\s*\b', prefix=r'\b'), Keyword),
+            (words(('name', 'count'), suffix=r's*:?', prefix=r'\b'), Name),
+            (r'\s*[\w.-]+\s*:', Name),
+
+            # Comments
+            (r'#.*\n', Comment),
+
+            # Default
+            (r'[^#]', Text),
+            (r'.*\n', Text)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/robotframework.py b/.venv/Lib/site-packages/pygments/lexers/robotframework.py
new file mode 100644
index 0000000..f92d567
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/robotframework.py
@@ -0,0 +1,551 @@
+"""
+    pygments.lexers.robotframework
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Robot Framework.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+#  Copyright 2012 Nokia Siemens Networks Oyj
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+import re
+
+from pygments.lexer import Lexer
+from pygments.token import Token
+
+__all__ = ['RobotFrameworkLexer']
+
+
+HEADING = Token.Generic.Heading
+SETTING = Token.Keyword.Namespace
+IMPORT = Token.Name.Namespace
+TC_KW_NAME = Token.Generic.Subheading
+KEYWORD = Token.Name.Function
+ARGUMENT = Token.String
+VARIABLE = Token.Name.Variable
+COMMENT = Token.Comment
+SEPARATOR = Token.Punctuation
+SYNTAX = Token.Punctuation
+GHERKIN = Token.Generic.Emph
+ERROR = Token.Error
+
+
+def normalize(string, remove=''):
+    string = string.lower()
+    for char in remove + ' ':
+        if char in string:
+            string = string.replace(char, '')
+    return string
+
+
+class RobotFrameworkLexer(Lexer):
+    """
+    For Robot Framework test data.
+
+    Supports both space and pipe separated plain text formats.
+    """
+    name = 'RobotFramework'
+    url = 'http://robotframework.org'
+    aliases = ['robotframework']
+    filenames = ['*.robot', '*.resource']
+    mimetypes = ['text/x-robotframework']
+    version_added = '1.6'
+
+    def __init__(self, **options):
+        options['tabsize'] = 2
+        options['encoding'] = 'UTF-8'
+        Lexer.__init__(self, **options)
+
+    def get_tokens_unprocessed(self, text):
+        row_tokenizer = RowTokenizer()
+        var_tokenizer = VariableTokenizer()
+        index = 0
+        for row in text.splitlines():
+            for value, token in row_tokenizer.tokenize(row):
+                for value, token in var_tokenizer.tokenize(value, token):
+                    if value:
+                        yield index, token, str(value)
+                        index += len(value)
+
+
+class VariableTokenizer:
+
+    def tokenize(self, string, token):
+        var = VariableSplitter(string, identifiers='$@%&')
+        if var.start < 0 or token in (COMMENT, ERROR):
+            yield string, token
+            return
+        for value, token in self._tokenize(var, string, token):
+            if value:
+                yield value, token
+
+    def _tokenize(self, var, string, orig_token):
+        before = string[:var.start]
+        yield before, orig_token
+        yield var.identifier + '{', SYNTAX
+        yield from self.tokenize(var.base, VARIABLE)
+        yield '}', SYNTAX
+        if var.index is not None:
+            yield '[', SYNTAX
+            yield from self.tokenize(var.index, VARIABLE)
+            yield ']', SYNTAX
+        yield from self.tokenize(string[var.end:], orig_token)
+
+
+class RowTokenizer:
+
+    def __init__(self):
+        self._table = UnknownTable()
+        self._splitter = RowSplitter()
+        testcases = TestCaseTable()
+        settings = SettingTable(testcases.set_default_template)
+        variables = VariableTable()
+        keywords = KeywordTable()
+        self._tables = {'settings': settings, 'setting': settings,
+                        'metadata': settings,
+                        'variables': variables, 'variable': variables,
+                        'testcases': testcases, 'testcase': testcases,
+                        'tasks': testcases, 'task': testcases,
+                        'keywords': keywords, 'keyword': keywords,
+                        'userkeywords': keywords, 'userkeyword': keywords}
+
+    def tokenize(self, row):
+        commented = False
+        heading = False
+        for index, value in enumerate(self._splitter.split(row)):
+            # First value, and every second after that, is a separator.
+            index, separator = divmod(index-1, 2)
+            if value.startswith('#'):
+                commented = True
+            elif index == 0 and value.startswith('*'):
+                self._table = self._start_table(value)
+                heading = True
+            yield from self._tokenize(value, index, commented,
+                                      separator, heading)
+        self._table.end_row()
+
+    def _start_table(self, header):
+        name = normalize(header, remove='*')
+        return self._tables.get(name, UnknownTable())
+
+    def _tokenize(self, value, index, commented, separator, heading):
+        if commented:
+            yield value, COMMENT
+        elif separator:
+            yield value, SEPARATOR
+        elif heading:
+            yield value, HEADING
+        else:
+            yield from self._table.tokenize(value, index)
+
+
+class RowSplitter:
+    _space_splitter = re.compile('( {2,})')
+    _pipe_splitter = re.compile(r'((?:^| +)\|(?: +|$))')
+
+    def split(self, row):
+        splitter = (row.startswith('| ') and self._split_from_pipes
+                    or self._split_from_spaces)
+        yield from splitter(row)
+        yield '\n'
+
+    def _split_from_spaces(self, row):
+        yield ''  # Start with (pseudo)separator similarly as with pipes
+        yield from self._space_splitter.split(row)
+
+    def _split_from_pipes(self, row):
+        _, separator, rest = self._pipe_splitter.split(row, 1)
+        yield separator
+        while self._pipe_splitter.search(rest):
+            cell, separator, rest = self._pipe_splitter.split(rest, 1)
+            yield cell
+            yield separator
+        yield rest
+
+
+class Tokenizer:
+    _tokens = None
+
+    def __init__(self):
+        self._index = 0
+
+    def tokenize(self, value):
+        values_and_tokens = self._tokenize(value, self._index)
+        self._index += 1
+        if isinstance(values_and_tokens, type(Token)):
+            values_and_tokens = [(value, values_and_tokens)]
+        return values_and_tokens
+
+    def _tokenize(self, value, index):
+        index = min(index, len(self._tokens) - 1)
+        return self._tokens[index]
+
+    def _is_assign(self, value):
+        if value.endswith('='):
+            value = value[:-1].strip()
+        var = VariableSplitter(value, identifiers='$@&')
+        return var.start == 0 and var.end == len(value)
+
+
+class Comment(Tokenizer):
+    _tokens = (COMMENT,)
+
+
+class Setting(Tokenizer):
+    _tokens = (SETTING, ARGUMENT)
+    _keyword_settings = ('suitesetup', 'suiteprecondition', 'suiteteardown',
+                         'suitepostcondition', 'testsetup', 'tasksetup', 'testprecondition',
+                         'testteardown','taskteardown', 'testpostcondition', 'testtemplate', 'tasktemplate')
+    _import_settings = ('library', 'resource', 'variables')
+    _other_settings = ('documentation', 'metadata', 'forcetags', 'defaulttags',
+                       'testtimeout','tasktimeout')
+    _custom_tokenizer = None
+
+    def __init__(self, template_setter=None):
+        Tokenizer.__init__(self)
+        self._template_setter = template_setter
+
+    def _tokenize(self, value, index):
+        if index == 1 and self._template_setter:
+            self._template_setter(value)
+        if index == 0:
+            normalized = normalize(value)
+            if normalized in self._keyword_settings:
+                self._custom_tokenizer = KeywordCall(support_assign=False)
+            elif normalized in self._import_settings:
+                self._custom_tokenizer = ImportSetting()
+            elif normalized not in self._other_settings:
+                return ERROR
+        elif self._custom_tokenizer:
+            return self._custom_tokenizer.tokenize(value)
+        return Tokenizer._tokenize(self, value, index)
+
+
+class ImportSetting(Tokenizer):
+    _tokens = (IMPORT, ARGUMENT)
+
+
+class TestCaseSetting(Setting):
+    _keyword_settings = ('setup', 'precondition', 'teardown', 'postcondition',
+                         'template')
+    _import_settings = ()
+    _other_settings = ('documentation', 'tags', 'timeout')
+
+    def _tokenize(self, value, index):
+        if index == 0:
+            type = Setting._tokenize(self, value[1:-1], index)
+            return [('[', SYNTAX), (value[1:-1], type), (']', SYNTAX)]
+        return Setting._tokenize(self, value, index)
+
+
+class KeywordSetting(TestCaseSetting):
+    _keyword_settings = ('teardown',)
+    _other_settings = ('documentation', 'arguments', 'return', 'timeout', 'tags')
+
+
+class Variable(Tokenizer):
+    _tokens = (SYNTAX, ARGUMENT)
+
+    def _tokenize(self, value, index):
+        if index == 0 and not self._is_assign(value):
+            return ERROR
+        return Tokenizer._tokenize(self, value, index)
+
+
+class KeywordCall(Tokenizer):
+    _tokens = (KEYWORD, ARGUMENT)
+
+    def __init__(self, support_assign=True):
+        Tokenizer.__init__(self)
+        self._keyword_found = not support_assign
+        self._assigns = 0
+
+    def _tokenize(self, value, index):
+        if not self._keyword_found and self._is_assign(value):
+            self._assigns += 1
+            return SYNTAX  # VariableTokenizer tokenizes this later.
+        if self._keyword_found:
+            return Tokenizer._tokenize(self, value, index - self._assigns)
+        self._keyword_found = True
+        return GherkinTokenizer().tokenize(value, KEYWORD)
+
+
+class GherkinTokenizer:
+    _gherkin_prefix = re.compile('^(Given|When|Then|And|But) ', re.IGNORECASE)
+
+    def tokenize(self, value, token):
+        match = self._gherkin_prefix.match(value)
+        if not match:
+            return [(value, token)]
+        end = match.end()
+        return [(value[:end], GHERKIN), (value[end:], token)]
+
+
+class TemplatedKeywordCall(Tokenizer):
+    _tokens = (ARGUMENT,)
+
+
+class ForLoop(Tokenizer):
+
+    def __init__(self):
+        Tokenizer.__init__(self)
+        self._in_arguments = False
+
+    def _tokenize(self, value, index):
+        token = self._in_arguments and ARGUMENT or SYNTAX
+        if value.upper() in ('IN', 'IN RANGE'):
+            self._in_arguments = True
+        return token
+
+
+class _Table:
+    _tokenizer_class = None
+
+    def __init__(self, prev_tokenizer=None):
+        self._tokenizer = self._tokenizer_class()
+        self._prev_tokenizer = prev_tokenizer
+        self._prev_values_on_row = []
+
+    def tokenize(self, value, index):
+        if self._continues(value, index):
+            self._tokenizer = self._prev_tokenizer
+            yield value, SYNTAX
+        else:
+            yield from self._tokenize(value, index)
+        self._prev_values_on_row.append(value)
+
+    def _continues(self, value, index):
+        return value == '...' and all(self._is_empty(t)
+                                      for t in self._prev_values_on_row)
+
+    def _is_empty(self, value):
+        return value in ('', '\\')
+
+    def _tokenize(self, value, index):
+        return self._tokenizer.tokenize(value)
+
+    def end_row(self):
+        self.__init__(prev_tokenizer=self._tokenizer)
+
+
+class UnknownTable(_Table):
+    _tokenizer_class = Comment
+
+    def _continues(self, value, index):
+        return False
+
+
+class VariableTable(_Table):
+    _tokenizer_class = Variable
+
+
+class SettingTable(_Table):
+    _tokenizer_class = Setting
+
+    def __init__(self, template_setter, prev_tokenizer=None):
+        _Table.__init__(self, prev_tokenizer)
+        self._template_setter = template_setter
+
+    def _tokenize(self, value, index):
+        if index == 0 and normalize(value) == 'testtemplate':
+            self._tokenizer = Setting(self._template_setter)
+        return _Table._tokenize(self, value, index)
+
+    def end_row(self):
+        self.__init__(self._template_setter, prev_tokenizer=self._tokenizer)
+
+
+class TestCaseTable(_Table):
+    _setting_class = TestCaseSetting
+    _test_template = None
+    _default_template = None
+
+    @property
+    def _tokenizer_class(self):
+        if self._test_template or (self._default_template and
+                                   self._test_template is not False):
+            return TemplatedKeywordCall
+        return KeywordCall
+
+    def _continues(self, value, index):
+        return index > 0 and _Table._continues(self, value, index)
+
+    def _tokenize(self, value, index):
+        if index == 0:
+            if value:
+                self._test_template = None
+            return GherkinTokenizer().tokenize(value, TC_KW_NAME)
+        if index == 1 and self._is_setting(value):
+            if self._is_template(value):
+                self._test_template = False
+                self._tokenizer = self._setting_class(self.set_test_template)
+            else:
+                self._tokenizer = self._setting_class()
+        if index == 1 and self._is_for_loop(value):
+            self._tokenizer = ForLoop()
+        if index == 1 and self._is_empty(value):
+            return [(value, SYNTAX)]
+        return _Table._tokenize(self, value, index)
+
+    def _is_setting(self, value):
+        return value.startswith('[') and value.endswith(']')
+
+    def _is_template(self, value):
+        return normalize(value) == '[template]'
+
+    def _is_for_loop(self, value):
+        return value.startswith(':') and normalize(value, remove=':') == 'for'
+
+    def set_test_template(self, template):
+        self._test_template = self._is_template_set(template)
+
+    def set_default_template(self, template):
+        self._default_template = self._is_template_set(template)
+
+    def _is_template_set(self, template):
+        return normalize(template) not in ('', '\\', 'none', '${empty}')
+
+
+class KeywordTable(TestCaseTable):
+    _tokenizer_class = KeywordCall
+    _setting_class = KeywordSetting
+
+    def _is_template(self, value):
+        return False
+
+
+# Following code copied directly from Robot Framework 2.7.5.
+
+class VariableSplitter:
+
+    def __init__(self, string, identifiers):
+        self.identifier = None
+        self.base = None
+        self.index = None
+        self.start = -1
+        self.end = -1
+        self._identifiers = identifiers
+        self._may_have_internal_variables = False
+        try:
+            self._split(string)
+        except ValueError:
+            pass
+        else:
+            self._finalize()
+
+    def get_replaced_base(self, variables):
+        if self._may_have_internal_variables:
+            return variables.replace_string(self.base)
+        return self.base
+
+    def _finalize(self):
+        self.identifier = self._variable_chars[0]
+        self.base = ''.join(self._variable_chars[2:-1])
+        self.end = self.start + len(self._variable_chars)
+        if self._has_list_or_dict_variable_index():
+            self.index = ''.join(self._list_and_dict_variable_index_chars[1:-1])
+            self.end += len(self._list_and_dict_variable_index_chars)
+
+    def _has_list_or_dict_variable_index(self):
+        return self._list_and_dict_variable_index_chars\
+        and self._list_and_dict_variable_index_chars[-1] == ']'
+
+    def _split(self, string):
+        start_index, max_index = self._find_variable(string)
+        self.start = start_index
+        self._open_curly = 1
+        self._state = self._variable_state
+        self._variable_chars = [string[start_index], '{']
+        self._list_and_dict_variable_index_chars = []
+        self._string = string
+        start_index += 2
+        for index, char in enumerate(string[start_index:]):
+            index += start_index  # Giving start to enumerate only in Py 2.6+
+            try:
+                self._state(char, index)
+            except StopIteration:
+                return
+            if index  == max_index and not self._scanning_list_variable_index():
+                return
+
+    def _scanning_list_variable_index(self):
+        return self._state in [self._waiting_list_variable_index_state,
+                               self._list_variable_index_state]
+
+    def _find_variable(self, string):
+        max_end_index = string.rfind('}')
+        if max_end_index == -1:
+            raise ValueError('No variable end found')
+        if self._is_escaped(string, max_end_index):
+            return self._find_variable(string[:max_end_index])
+        start_index = self._find_start_index(string, 1, max_end_index)
+        if start_index == -1:
+            raise ValueError('No variable start found')
+        return start_index, max_end_index
+
+    def _find_start_index(self, string, start, end):
+        index = string.find('{', start, end) - 1
+        if index < 0:
+            return -1
+        if self._start_index_is_ok(string, index):
+            return index
+        return self._find_start_index(string, index+2, end)
+
+    def _start_index_is_ok(self, string, index):
+        return string[index] in self._identifiers\
+        and not self._is_escaped(string, index)
+
+    def _is_escaped(self, string, index):
+        escaped = False
+        while index > 0 and string[index-1] == '\\':
+            index -= 1
+            escaped = not escaped
+        return escaped
+
+    def _variable_state(self, char, index):
+        self._variable_chars.append(char)
+        if char == '}' and not self._is_escaped(self._string, index):
+            self._open_curly -= 1
+            if self._open_curly == 0:
+                if not self._is_list_or_dict_variable():
+                    raise StopIteration
+                self._state = self._waiting_list_variable_index_state
+        elif char in self._identifiers:
+            self._state = self._internal_variable_start_state
+
+    def _is_list_or_dict_variable(self):
+        return self._variable_chars[0] in ('@','&')
+
+    def _internal_variable_start_state(self, char, index):
+        self._state = self._variable_state
+        if char == '{':
+            self._variable_chars.append(char)
+            self._open_curly += 1
+            self._may_have_internal_variables = True
+        else:
+            self._variable_state(char, index)
+
+    def _waiting_list_variable_index_state(self, char, index):
+        if char != '[':
+            raise StopIteration
+        self._list_and_dict_variable_index_chars.append(char)
+        self._state = self._list_variable_index_state
+
+    def _list_variable_index_state(self, char, index):
+        self._list_and_dict_variable_index_chars.append(char)
+        if char == ']':
+            raise StopIteration
diff --git a/.venv/Lib/site-packages/pygments/lexers/ruby.py b/.venv/Lib/site-packages/pygments/lexers/ruby.py
new file mode 100644
index 0000000..72aaeb5
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/ruby.py
@@ -0,0 +1,518 @@
+"""
+    pygments.lexers.ruby
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Ruby and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import Lexer, RegexLexer, ExtendedRegexLexer, include, \
+    bygroups, default, LexerContext, do_insertions, words, line_re
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Error, Generic, Whitespace
+from pygments.util import shebang_matches
+
+__all__ = ['RubyLexer', 'RubyConsoleLexer', 'FancyLexer']
+
+
+RUBY_OPERATORS = (
+    '*', '**', '-', '+', '-@', '+@', '/', '%', '&', '|', '^', '`', '~',
+    '[]', '[]=', '<<', '>>', '<', '<>', '<=>', '>', '>=', '==', '==='
+)
+
+
+class RubyLexer(ExtendedRegexLexer):
+    """
+    For Ruby source code.
+    """
+
+    name = 'Ruby'
+    url = 'http://www.ruby-lang.org'
+    aliases = ['ruby', 'rb', 'duby']
+    filenames = ['*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec',
+                 '*.rbx', '*.duby', 'Gemfile', 'Vagrantfile']
+    mimetypes = ['text/x-ruby', 'application/x-ruby']
+    version_added = ''
+
+    flags = re.DOTALL | re.MULTILINE
+
+    def heredoc_callback(self, match, ctx):
+        # okay, this is the hardest part of parsing Ruby...
+        # match: 1 = <<[-~]?, 2 = quote? 3 = name 4 = quote? 5 = rest of line
+
+        start = match.start(1)
+        yield start, Operator, match.group(1)        # <<[-~]?
+        yield match.start(2), String.Heredoc, match.group(2)   # quote ", ', `
+        yield match.start(3), String.Delimiter, match.group(3) # heredoc name
+        yield match.start(4), String.Heredoc, match.group(4)   # quote again
+
+        heredocstack = ctx.__dict__.setdefault('heredocstack', [])
+        outermost = not bool(heredocstack)
+        heredocstack.append((match.group(1) in ('<<-', '<<~'), match.group(3)))
+
+        ctx.pos = match.start(5)
+        ctx.end = match.end(5)
+        # this may find other heredocs, so limit the recursion depth
+        if len(heredocstack) < 100:
+            yield from self.get_tokens_unprocessed(context=ctx)
+        else:
+            yield ctx.pos, String.Heredoc, match.group(5)
+        ctx.pos = match.end()
+
+        if outermost:
+            # this is the outer heredoc again, now we can process them all
+            for tolerant, hdname in heredocstack:
+                lines = []
+                for match in line_re.finditer(ctx.text, ctx.pos):
+                    if tolerant:
+                        check = match.group().strip()
+                    else:
+                        check = match.group().rstrip()
+                    if check == hdname:
+                        for amatch in lines:
+                            yield amatch.start(), String.Heredoc, amatch.group()
+                        yield match.start(), String.Delimiter, match.group()
+                        ctx.pos = match.end()
+                        break
+                    else:
+                        lines.append(match)
+                else:
+                    # end of heredoc not found -- error!
+                    for amatch in lines:
+                        yield amatch.start(), Error, amatch.group()
+            ctx.end = len(ctx.text)
+            del heredocstack[:]
+
+    def gen_rubystrings_rules():
+        def intp_regex_callback(self, match, ctx):
+            yield match.start(1), String.Regex, match.group(1)  # begin
+            nctx = LexerContext(match.group(3), 0, ['interpolated-regex'])
+            for i, t, v in self.get_tokens_unprocessed(context=nctx):
+                yield match.start(3)+i, t, v
+            yield match.start(4), String.Regex, match.group(4)  # end[mixounse]*
+            ctx.pos = match.end()
+
+        def intp_string_callback(self, match, ctx):
+            yield match.start(1), String.Other, match.group(1)
+            nctx = LexerContext(match.group(3), 0, ['interpolated-string'])
+            for i, t, v in self.get_tokens_unprocessed(context=nctx):
+                yield match.start(3)+i, t, v
+            yield match.start(4), String.Other, match.group(4)  # end
+            ctx.pos = match.end()
+
+        states = {}
+        states['strings'] = [
+            # easy ones
+            (r'\:@{0,2}[a-zA-Z_]\w*[!?]?', String.Symbol),
+            (words(RUBY_OPERATORS, prefix=r'\:@{0,2}'), String.Symbol),
+            (r":'(\\\\|\\[^\\]|[^'\\])*'", String.Symbol),
+            (r':"', String.Symbol, 'simple-sym'),
+            (r'([a-zA-Z_]\w*)(:)(?!:)',
+             bygroups(String.Symbol, Punctuation)),  # Since Ruby 1.9
+            (r'"', String.Double, 'simple-string-double'),
+            (r"'", String.Single, 'simple-string-single'),
+            (r'(?', '<>', 'ab'):
+            states[name+'-intp-string'] = [
+                (r'\\[\\' + bracecc + ']', String.Other),
+                (lbrace, String.Other, '#push'),
+                (rbrace, String.Other, '#pop'),
+                include('string-intp-escaped'),
+                (r'[\\#' + bracecc + ']', String.Other),
+                (r'[^\\#' + bracecc + ']+', String.Other),
+            ]
+            states['strings'].append((r'%[QWx]?' + lbrace, String.Other,
+                                      name+'-intp-string'))
+            states[name+'-string'] = [
+                (r'\\[\\' + bracecc + ']', String.Other),
+                (lbrace, String.Other, '#push'),
+                (rbrace, String.Other, '#pop'),
+                (r'[\\#' + bracecc + ']', String.Other),
+                (r'[^\\#' + bracecc + ']+', String.Other),
+            ]
+            states['strings'].append((r'%[qsw]' + lbrace, String.Other,
+                                      name+'-string'))
+            states[name+'-regex'] = [
+                (r'\\[\\' + bracecc + ']', String.Regex),
+                (lbrace, String.Regex, '#push'),
+                (rbrace + '[mixounse]*', String.Regex, '#pop'),
+                include('string-intp'),
+                (r'[\\#' + bracecc + ']', String.Regex),
+                (r'[^\\#' + bracecc + ']+', String.Regex),
+            ]
+            states['strings'].append((r'%r' + lbrace, String.Regex,
+                                      name+'-regex'))
+
+        # these must come after %!
+        states['strings'] += [
+            # %r regex
+            (r'(%r([\W_]))((?:\\\2|(?!\2).)*)(\2[mixounse]*)',
+             intp_regex_callback),
+            # regular fancy strings with qsw
+            (r'%[qsw]([\W_])((?:\\\1|(?!\1).)*)\1', String.Other),
+            (r'(%[QWx]([\W_]))((?:\\\2|(?!\2).)*)(\2)',
+             intp_string_callback),
+            # special forms of fancy strings after operators or
+            # in method calls with braces
+            (r'(?<=[-+/*%=<>&!^|~,(])(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
+             bygroups(Whitespace, String.Other, None)),
+            # and because of fixed width lookbehinds the whole thing a
+            # second time for line startings...
+            (r'^(\s*)(%([\t ])(?:(?:\\\3|(?!\3).)*)\3)',
+             bygroups(Whitespace, String.Other, None)),
+            # all regular fancy strings without qsw
+            (r'(%([^a-zA-Z0-9\s]))((?:\\\2|(?!\2).)*)(\2)',
+             intp_string_callback),
+        ]
+
+        return states
+
+    tokens = {
+        'root': [
+            (r'\A#!.+?$', Comment.Hashbang),
+            (r'#.*?$', Comment.Single),
+            (r'=begin\s.*?\n=end.*?$', Comment.Multiline),
+            # keywords
+            (words((
+                'BEGIN', 'END', 'alias', 'begin', 'break', 'case', 'defined?',
+                'do', 'else', 'elsif', 'end', 'ensure', 'for', 'if', 'in', 'next', 'redo',
+                'rescue', 'raise', 'retry', 'return', 'super', 'then', 'undef',
+                'unless', 'until', 'when', 'while', 'yield'), suffix=r'\b'),
+             Keyword),
+            # start of function, class and module names
+            (r'(module)(\s+)([a-zA-Z_]\w*'
+             r'(?:::[a-zA-Z_]\w*)*)',
+             bygroups(Keyword, Whitespace, Name.Namespace)),
+            (r'(def)(\s+)', bygroups(Keyword, Whitespace), 'funcname'),
+            (r'def(?=[*%&^`~+-/\[<>=])', Keyword, 'funcname'),
+            (r'(class)(\s+)', bygroups(Keyword, Whitespace), 'classname'),
+            # special methods
+            (words((
+                'initialize', 'new', 'loop', 'include', 'extend', 'raise', 'attr_reader',
+                'attr_writer', 'attr_accessor', 'attr', 'catch', 'throw', 'private',
+                'module_function', 'public', 'protected', 'true', 'false', 'nil'),
+                suffix=r'\b'),
+             Keyword.Pseudo),
+            (r'(not|and|or)\b', Operator.Word),
+            (words((
+                'autoload', 'block_given', 'const_defined', 'eql', 'equal', 'frozen', 'include',
+                'instance_of', 'is_a', 'iterator', 'kind_of', 'method_defined', 'nil',
+                'private_method_defined', 'protected_method_defined',
+                'public_method_defined', 'respond_to', 'tainted'), suffix=r'\?'),
+             Name.Builtin),
+            (r'(chomp|chop|exit|gsub|sub)!', Name.Builtin),
+            (words((
+                'Array', 'Float', 'Integer', 'String', '__id__', '__send__', 'abort',
+                'ancestors', 'at_exit', 'autoload', 'binding', 'callcc', 'caller',
+                'catch', 'chomp', 'chop', 'class_eval', 'class_variables',
+                'clone', 'const_defined?', 'const_get', 'const_missing', 'const_set',
+                'constants', 'display', 'dup', 'eval', 'exec', 'exit', 'extend', 'fail', 'fork',
+                'format', 'freeze', 'getc', 'gets', 'global_variables', 'gsub',
+                'hash', 'id', 'included_modules', 'inspect', 'instance_eval',
+                'instance_method', 'instance_methods',
+                'instance_variable_get', 'instance_variable_set', 'instance_variables',
+                'lambda', 'load', 'local_variables', 'loop',
+                'method', 'method_missing', 'methods', 'module_eval', 'name',
+                'object_id', 'open', 'p', 'print', 'printf', 'private_class_method',
+                'private_instance_methods',
+                'private_methods', 'proc', 'protected_instance_methods',
+                'protected_methods', 'public_class_method',
+                'public_instance_methods', 'public_methods',
+                'putc', 'puts', 'raise', 'rand', 'readline', 'readlines', 'require',
+                'scan', 'select', 'self', 'send', 'set_trace_func', 'singleton_methods', 'sleep',
+                'split', 'sprintf', 'srand', 'sub', 'syscall', 'system', 'taint',
+                'test', 'throw', 'to_a', 'to_s', 'trace_var', 'trap', 'untaint',
+                'untrace_var', 'warn'), prefix=r'(?~!:])|'
+             r'(?<=(?:\s|;)when\s)|'
+             r'(?<=(?:\s|;)or\s)|'
+             r'(?<=(?:\s|;)and\s)|'
+             r'(?<=\.index\s)|'
+             r'(?<=\.scan\s)|'
+             r'(?<=\.sub\s)|'
+             r'(?<=\.sub!\s)|'
+             r'(?<=\.gsub\s)|'
+             r'(?<=\.gsub!\s)|'
+             r'(?<=\.match\s)|'
+             r'(?<=(?:\s|;)if\s)|'
+             r'(?<=(?:\s|;)elsif\s)|'
+             r'(?<=^when\s)|'
+             r'(?<=^index\s)|'
+             r'(?<=^scan\s)|'
+             r'(?<=^sub\s)|'
+             r'(?<=^gsub\s)|'
+             r'(?<=^sub!\s)|'
+             r'(?<=^gsub!\s)|'
+             r'(?<=^match\s)|'
+             r'(?<=^if\s)|'
+             r'(?<=^elsif\s)'
+             r')(\s*)(/)', bygroups(Text, String.Regex), 'multiline-regex'),
+            # multiline regex (in method calls or subscripts)
+            (r'(?<=\(|,|\[)/', String.Regex, 'multiline-regex'),
+            # multiline regex (this time the funny no whitespace rule)
+            (r'(\s+)(/)(?![\s=])', bygroups(Whitespace, String.Regex),
+             'multiline-regex'),
+            # lex numbers and ignore following regular expressions which
+            # are division operators in fact (grrrr. i hate that. any
+            # better ideas?)
+            # since pygments 0.7 we also eat a "?" operator after numbers
+            # so that the char operator does not work. Chars are not allowed
+            # there so that you can use the ternary operator.
+            # stupid example:
+            #   x>=0?n[x]:""
+            (r'(0_?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
+             bygroups(Number.Oct, Whitespace, Operator)),
+            (r'(0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
+             bygroups(Number.Hex, Whitespace, Operator)),
+            (r'(0b[01]+(?:_[01]+)*)(\s*)([/?])?',
+             bygroups(Number.Bin, Whitespace, Operator)),
+            (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
+             bygroups(Number.Integer, Whitespace, Operator)),
+            # Names
+            (r'@@[a-zA-Z_]\w*', Name.Variable.Class),
+            (r'@[a-zA-Z_]\w*', Name.Variable.Instance),
+            (r'\$\w+', Name.Variable.Global),
+            (r'\$[!@&`\'+~=/\\,;.<>_*$?:"^-]', Name.Variable.Global),
+            (r'\$-[0adFiIlpvw]', Name.Variable.Global),
+            (r'::', Operator),
+            include('strings'),
+            # chars
+            (r'\?(\\[MC]-)*'  # modifiers
+             r'(\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})|\S)'
+             r'(?!\w)',
+             String.Char),
+            (r'[A-Z]\w+', Name.Constant),
+            # this is needed because ruby attributes can look
+            # like keywords (class) or like this: ` ?!?
+            (words(RUBY_OPERATORS, prefix=r'(\.|::)'),
+             bygroups(Operator, Name.Operator)),
+            (r'(\.|::)([a-zA-Z_]\w*[!?]?|[*%&^`~+\-/\[<>=])',
+             bygroups(Operator, Name)),
+            (r'[a-zA-Z_]\w*[!?]?', Name),
+            (r'(\[|\]|\*\*|<>?|>=|<=|<=>|=~|={3}|'
+             r'!~|&&?|\|\||\.{1,3})', Operator),
+            (r'[-+/*%=<>&!^|~]=?', Operator),
+            (r'[(){};,/?:\\]', Punctuation),
+            (r'\s+', Whitespace)
+        ],
+        'funcname': [
+            (r'\(', Punctuation, 'defexpr'),
+            (r'(?:([a-zA-Z_]\w*)(\.))?'  # optional scope name, like "self."
+             r'('
+                r'[a-zA-Z\u0080-\uffff][a-zA-Z0-9_\u0080-\uffff]*[!?=]?'  # method name
+                r'|!=|!~|=~|\*\*?|[-+!~]@?|[/%&|^]|<=>|<[<=]?|>[>=]?|===?'  # or operator override
+                r'|\[\]=?'  # or element reference/assignment override
+                r'|`'  # or the undocumented backtick override
+             r')',
+             bygroups(Name.Class, Operator, Name.Function), '#pop'),
+            default('#pop')
+        ],
+        'classname': [
+            (r'\(', Punctuation, 'defexpr'),
+            (r'<<', Operator, '#pop'),
+            (r'[A-Z_]\w*', Name.Class, '#pop'),
+            default('#pop')
+        ],
+        'defexpr': [
+            (r'(\))(\.|::)?', bygroups(Punctuation, Operator), '#pop'),
+            (r'\(', Operator, '#push'),
+            include('root')
+        ],
+        'in-intp': [
+            (r'\{', String.Interpol, '#push'),
+            (r'\}', String.Interpol, '#pop'),
+            include('root'),
+        ],
+        'string-intp': [
+            (r'#\{', String.Interpol, 'in-intp'),
+            (r'#@@?[a-zA-Z_]\w*', String.Interpol),
+            (r'#\$[a-zA-Z_]\w*', String.Interpol)
+        ],
+        'string-intp-escaped': [
+            include('string-intp'),
+            (r'\\([\\abefnrstv#"\']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})',
+             String.Escape)
+        ],
+        'interpolated-regex': [
+            include('string-intp'),
+            (r'[\\#]', String.Regex),
+            (r'[^\\#]+', String.Regex),
+        ],
+        'interpolated-string': [
+            include('string-intp'),
+            (r'[\\#]', String.Other),
+            (r'[^\\#]+', String.Other),
+        ],
+        'multiline-regex': [
+            include('string-intp'),
+            (r'\\\\', String.Regex),
+            (r'\\/', String.Regex),
+            (r'[\\#]', String.Regex),
+            (r'[^\\/#]+', String.Regex),
+            (r'/[mixounse]*', String.Regex, '#pop'),
+        ],
+        'end-part': [
+            (r'.+', Comment.Preproc, '#pop')
+        ]
+    }
+    tokens.update(gen_rubystrings_rules())
+
+    def analyse_text(text):
+        return shebang_matches(text, r'ruby(1\.\d)?')
+
+
+class RubyConsoleLexer(Lexer):
+    """
+    For Ruby interactive console (**irb**) output.
+    """
+    name = 'Ruby irb session'
+    aliases = ['rbcon', 'irb']
+    mimetypes = ['text/x-ruby-shellsession']
+    url = 'https://www.ruby-lang.org'
+    version_added = ''
+    _example = 'rbcon/console'
+
+    _prompt_re = re.compile(r'irb\([a-zA-Z_]\w*\):\d{3}:\d+[>*"\'] '
+                            r'|>> |\?> ')
+
+    def get_tokens_unprocessed(self, text):
+        rblexer = RubyLexer(**self.options)
+
+        curcode = ''
+        insertions = []
+        for match in line_re.finditer(text):
+            line = match.group()
+            m = self._prompt_re.match(line)
+            if m is not None:
+                end = m.end()
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt, line[:end])]))
+                curcode += line[end:]
+            else:
+                if curcode:
+                    yield from do_insertions(
+                        insertions, rblexer.get_tokens_unprocessed(curcode))
+                    curcode = ''
+                    insertions = []
+                yield match.start(), Generic.Output, line
+        if curcode:
+            yield from do_insertions(
+                insertions, rblexer.get_tokens_unprocessed(curcode))
+
+
+class FancyLexer(RegexLexer):
+    """
+    Pygments Lexer For Fancy.
+
+    Fancy is a self-hosted, pure object-oriented, dynamic,
+    class-based, concurrent general-purpose programming language
+    running on Rubinius, the Ruby VM.
+    """
+    name = 'Fancy'
+    url = 'https://github.com/bakkdoor/fancy'
+    filenames = ['*.fy', '*.fancypack']
+    aliases = ['fancy', 'fy']
+    mimetypes = ['text/x-fancysrc']
+    version_added = '1.5'
+
+    tokens = {
+        # copied from PerlLexer:
+        'balanced-regex': [
+            (r'/(\\\\|\\[^\\]|[^/\\])*/[egimosx]*', String.Regex, '#pop'),
+            (r'!(\\\\|\\[^\\]|[^!\\])*![egimosx]*', String.Regex, '#pop'),
+            (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
+            (r'\{(\\\\|\\[^\\]|[^}\\])*\}[egimosx]*', String.Regex, '#pop'),
+            (r'<(\\\\|\\[^\\]|[^>\\])*>[egimosx]*', String.Regex, '#pop'),
+            (r'\[(\\\\|\\[^\\]|[^\]\\])*\][egimosx]*', String.Regex, '#pop'),
+            (r'\((\\\\|\\[^\\]|[^)\\])*\)[egimosx]*', String.Regex, '#pop'),
+            (r'@(\\\\|\\[^\\]|[^@\\])*@[egimosx]*', String.Regex, '#pop'),
+            (r'%(\\\\|\\[^\\]|[^%\\])*%[egimosx]*', String.Regex, '#pop'),
+            (r'\$(\\\\|\\[^\\]|[^$\\])*\$[egimosx]*', String.Regex, '#pop'),
+        ],
+        'root': [
+            (r'\s+', Whitespace),
+
+            # balanced delimiters (copied from PerlLexer):
+            (r's\{(\\\\|\\[^\\]|[^}\\])*\}\s*', String.Regex, 'balanced-regex'),
+            (r's<(\\\\|\\[^\\]|[^>\\])*>\s*', String.Regex, 'balanced-regex'),
+            (r's\[(\\\\|\\[^\\]|[^\]\\])*\]\s*', String.Regex, 'balanced-regex'),
+            (r's\((\\\\|\\[^\\]|[^)\\])*\)\s*', String.Regex, 'balanced-regex'),
+            (r'm?/(\\\\|\\[^\\]|[^///\n])*/[gcimosx]*', String.Regex),
+            (r'm(?=[/!\\{<\[(@%$])', String.Regex, 'balanced-regex'),
+
+            # Comments
+            (r'#(.*?)\n', Comment.Single),
+            # Symbols
+            (r'\'([^\'\s\[\](){}]+|\[\])', String.Symbol),
+            # Multi-line DoubleQuotedString
+            (r'"""(\\\\|\\[^\\]|[^\\])*?"""', String),
+            # DoubleQuotedString
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
+            # keywords
+            (r'(def|class|try|catch|finally|retry|return|return_local|match|'
+             r'case|->|=>)\b', Keyword),
+            # constants
+            (r'(self|super|nil|false|true)\b', Name.Constant),
+            (r'[(){};,/?|:\\]', Punctuation),
+            # names
+            (words((
+                'Object', 'Array', 'Hash', 'Directory', 'File', 'Class', 'String',
+                'Number', 'Enumerable', 'FancyEnumerable', 'Block', 'TrueClass',
+                'NilClass', 'FalseClass', 'Tuple', 'Symbol', 'Stack', 'Set',
+                'FancySpec', 'Method', 'Package', 'Range'), suffix=r'\b'),
+             Name.Builtin),
+            # functions
+            (r'[a-zA-Z](\w|[-+?!=*/^><%])*:', Name.Function),
+            # operators, must be below functions
+            (r'[-+*/~,<>=&!?%^\[\].$]+', Operator),
+            (r'[A-Z]\w*', Name.Constant),
+            (r'@[a-zA-Z_]\w*', Name.Variable.Instance),
+            (r'@@[a-zA-Z_]\w*', Name.Variable.Class),
+            ('@@?', Operator),
+            (r'[a-zA-Z_]\w*', Name),
+            # numbers - / checks are necessary to avoid mismarking regexes,
+            # see comment in RubyLexer
+            (r'(0[oO]?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
+             bygroups(Number.Oct, Whitespace, Operator)),
+            (r'(0[xX][0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
+             bygroups(Number.Hex, Whitespace, Operator)),
+            (r'(0[bB][01]+(?:_[01]+)*)(\s*)([/?])?',
+             bygroups(Number.Bin, Whitespace, Operator)),
+            (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
+             bygroups(Number.Integer, Whitespace, Operator)),
+            (r'\d+([eE][+-]?[0-9]+)|\d+\.\d+([eE][+-]?[0-9]+)?', Number.Float),
+            (r'\d+', Number.Integer)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/rust.py b/.venv/Lib/site-packages/pygments/lexers/rust.py
new file mode 100644
index 0000000..6341047
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/rust.py
@@ -0,0 +1,222 @@
+"""
+    pygments.lexers.rust
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the Rust language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, include, bygroups, words, default
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Whitespace
+
+__all__ = ['RustLexer']
+
+
+class RustLexer(RegexLexer):
+    """
+    Lexer for the Rust programming language (version 1.47).
+    """
+    name = 'Rust'
+    url = 'https://www.rust-lang.org/'
+    filenames = ['*.rs', '*.rs.in']
+    aliases = ['rust', 'rs']
+    mimetypes = ['text/rust', 'text/x-rust']
+    version_added = '1.6'
+
+    keyword_types = (words((
+        'u8', 'u16', 'u32', 'u64', 'u128', 'i8', 'i16', 'i32', 'i64', 'i128',
+        'usize', 'isize', 'f32', 'f64', 'char', 'str', 'bool',
+    ), suffix=r'\b'), Keyword.Type)
+
+    builtin_funcs_types = (words((
+        'Copy', 'Send', 'Sized', 'Sync', 'Unpin',
+        'Drop', 'Fn', 'FnMut', 'FnOnce', 'drop',
+        'Box', 'ToOwned', 'Clone',
+        'PartialEq', 'PartialOrd', 'Eq', 'Ord',
+        'AsRef', 'AsMut', 'Into', 'From', 'Default',
+        'Iterator', 'Extend', 'IntoIterator', 'DoubleEndedIterator',
+        'ExactSizeIterator',
+        'Option', 'Some', 'None',
+        'Result', 'Ok', 'Err',
+        'String', 'ToString', 'Vec',
+    ), suffix=r'\b'), Name.Builtin)
+
+    builtin_macros = (words((
+        'asm', 'assert', 'assert_eq', 'assert_ne', 'cfg', 'column',
+        'compile_error', 'concat', 'concat_idents', 'dbg', 'debug_assert',
+        'debug_assert_eq', 'debug_assert_ne', 'env', 'eprint', 'eprintln',
+        'file', 'format', 'format_args', 'format_args_nl', 'global_asm',
+        'include', 'include_bytes', 'include_str',
+        'is_aarch64_feature_detected',
+        'is_arm_feature_detected',
+        'is_mips64_feature_detected',
+        'is_mips_feature_detected',
+        'is_powerpc64_feature_detected',
+        'is_powerpc_feature_detected',
+        'is_x86_feature_detected',
+        'line', 'llvm_asm', 'log_syntax', 'macro_rules', 'matches',
+        'module_path', 'option_env', 'panic', 'print', 'println', 'stringify',
+        'thread_local', 'todo', 'trace_macros', 'unimplemented', 'unreachable',
+        'vec', 'write', 'writeln',
+    ), suffix=r'!'), Name.Function.Magic)
+
+    tokens = {
+        'root': [
+            # rust allows a file to start with a shebang, but if the first line
+            # starts with #![ then it's not a shebang but a crate attribute.
+            (r'#![^[\r\n].*$', Comment.Preproc),
+            default('base'),
+        ],
+        'base': [
+            # Whitespace and Comments
+            (r'\n', Whitespace),
+            (r'\s+', Whitespace),
+            (r'//!.*?\n', String.Doc),
+            (r'///(\n|[^/].*?\n)', String.Doc),
+            (r'//(.*?)\n', Comment.Single),
+            (r'/\*\*(\n|[^/*])', String.Doc, 'doccomment'),
+            (r'/\*!', String.Doc, 'doccomment'),
+            (r'/\*', Comment.Multiline, 'comment'),
+
+            # Macro parameters
+            (r"""\$([a-zA-Z_]\w*|\(,?|\),?|,?)""", Comment.Preproc),
+            # Keywords
+            (words(('as', 'async', 'await', 'box', 'const', 'crate', 'dyn',
+                    'else', 'extern', 'for', 'if', 'impl', 'in', 'loop',
+                    'match', 'move', 'mut', 'pub', 'ref', 'return', 'static',
+                    'super', 'trait', 'unsafe', 'use', 'where', 'while'),
+                   suffix=r'\b'), Keyword),
+            (words(('abstract', 'become', 'do', 'final', 'macro', 'override',
+                    'priv', 'typeof', 'try', 'unsized', 'virtual', 'yield'),
+                   suffix=r'\b'), Keyword.Reserved),
+            (r'(true|false)\b', Keyword.Constant),
+            (r'self\b', Name.Builtin.Pseudo),
+            (r'mod\b', Keyword, 'modname'),
+            (r'let\b', Keyword.Declaration),
+            (r'fn\b', Keyword, 'funcname'),
+            (r'(struct|enum|type|union)\b', Keyword, 'typename'),
+            (r'(default)(\s+)(type|fn)\b', bygroups(Keyword, Whitespace, Keyword)),
+            keyword_types,
+            (r'[sS]elf\b', Name.Builtin.Pseudo),
+            # Prelude (taken from Rust's src/libstd/prelude.rs)
+            builtin_funcs_types,
+            builtin_macros,
+            # Path separators, so types don't catch them.
+            (r'::\b', Punctuation),
+            # Types in positions.
+            (r'(?::|->)', Punctuation, 'typename'),
+            # Labels
+            (r'(break|continue)(\b\s*)(\'[A-Za-z_]\w*)?',
+             bygroups(Keyword, Text.Whitespace, Name.Label)),
+
+            # Character literals
+            (r"""'(\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0"""
+             r"""|\\u\{[0-9a-fA-F]{1,6}\}|.)'""",
+             String.Char),
+            (r"""b'(\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\0"""
+             r"""|\\u\{[0-9a-fA-F]{1,6}\}|.)'""",
+             String.Char),
+
+            # Binary literals
+            (r'0b[01_]+', Number.Bin, 'number_lit'),
+            # Octal literals
+            (r'0o[0-7_]+', Number.Oct, 'number_lit'),
+            # Hexadecimal literals
+            (r'0[xX][0-9a-fA-F_]+', Number.Hex, 'number_lit'),
+            # Decimal literals
+            (r'[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|'
+             r'\.[0-9_]*(?!\.)|[eE][+\-]?[0-9_]+)', Number.Float,
+             'number_lit'),
+            (r'[0-9][0-9_]*', Number.Integer, 'number_lit'),
+
+            # String literals
+            (r'b"', String, 'bytestring'),
+            (r'"', String, 'string'),
+            (r'(?s)b?r(#*)".*?"\1', String),
+
+            # Lifetime names
+            (r"'", Operator, 'lifetime'),
+
+            # Operators and Punctuation
+            (r'\.\.=?', Operator),
+            (r'[{}()\[\],.;]', Punctuation),
+            (r'[+\-*/%&|<>^!~@=:?]', Operator),
+
+            # Identifiers
+            (r'[a-zA-Z_]\w*', Name),
+            # Raw identifiers
+            (r'r#[a-zA-Z_]\w*', Name),
+
+            # Attributes
+            (r'#!?\[', Comment.Preproc, 'attribute['),
+
+            # Misc
+            # Lone hashes: not used in Rust syntax, but allowed in macro
+            # arguments, most famously for quote::quote!()
+            (r'#', Punctuation),
+        ],
+        'comment': [
+            (r'[^*/]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[*/]', Comment.Multiline),
+        ],
+        'doccomment': [
+            (r'[^*/]+', String.Doc),
+            (r'/\*', String.Doc, '#push'),
+            (r'\*/', String.Doc, '#pop'),
+            (r'[*/]', String.Doc),
+        ],
+        'modname': [
+            (r'\s+', Whitespace),
+            (r'[a-zA-Z_]\w*', Name.Namespace, '#pop'),
+            default('#pop'),
+        ],
+        'funcname': [
+            (r'\s+', Whitespace),
+            (r'[a-zA-Z_]\w*', Name.Function, '#pop'),
+            default('#pop'),
+        ],
+        'typename': [
+            (r'\s+', Whitespace),
+            (r'&', Keyword.Pseudo),
+            (r"'", Operator, 'lifetime'),
+            builtin_funcs_types,
+            keyword_types,
+            (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
+            default('#pop'),
+        ],
+        'lifetime': [
+            (r"(static|_)", Name.Builtin),
+            (r"[a-zA-Z_]+\w*", Name.Attribute),
+            default('#pop'),
+        ],
+        'number_lit': [
+            (r'[ui](8|16|32|64|size)', Keyword, '#pop'),
+            (r'f(32|64)', Keyword, '#pop'),
+            default('#pop'),
+        ],
+        'string': [
+            (r'"', String, '#pop'),
+            (r"""\\['"\\nrt]|\\x[0-7][0-9a-fA-F]|\\0"""
+             r"""|\\u\{[0-9a-fA-F]{1,6}\}""", String.Escape),
+            (r'[^\\"]+', String),
+            (r'\\', String),
+        ],
+        'bytestring': [
+            (r"""\\x[89a-fA-F][0-9a-fA-F]""", String.Escape),
+            include('string'),
+        ],
+        'attribute_common': [
+            (r'"', String, 'string'),
+            (r'\[', Comment.Preproc, 'attribute['),
+        ],
+        'attribute[': [
+            include('attribute_common'),
+            (r'\]', Comment.Preproc, '#pop'),
+            (r'[^"\]\[]+', Comment.Preproc),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/sas.py b/.venv/Lib/site-packages/pygments/lexers/sas.py
new file mode 100644
index 0000000..1b2ad43
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/sas.py
@@ -0,0 +1,227 @@
+"""
+    pygments.lexers.sas
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexer for SAS.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+from pygments.lexer import RegexLexer, include, words
+from pygments.token import Comment, Keyword, Name, Number, String, Text, \
+    Other, Generic
+
+__all__ = ['SASLexer']
+
+
+class SASLexer(RegexLexer):
+    """
+    For SAS files.
+    """
+    # Syntax from syntax/sas.vim by James Kidd 
+
+    name      = 'SAS'
+    aliases   = ['sas']
+    filenames = ['*.SAS', '*.sas']
+    mimetypes = ['text/x-sas', 'text/sas', 'application/x-sas']
+    url = 'https://en.wikipedia.org/wiki/SAS_(software)'
+    version_added = '2.2'
+    flags     = re.IGNORECASE | re.MULTILINE
+
+    builtins_macros = (
+        "bquote", "nrbquote", "cmpres", "qcmpres", "compstor", "datatyp",
+        "display", "do", "else", "end", "eval", "global", "goto", "if",
+        "index", "input", "keydef", "label", "left", "length", "let",
+        "local", "lowcase", "macro", "mend", "nrquote",
+        "nrstr", "put", "qleft", "qlowcase", "qscan",
+        "qsubstr", "qsysfunc", "qtrim", "quote", "qupcase", "scan",
+        "str", "substr", "superq", "syscall", "sysevalf", "sysexec",
+        "sysfunc", "sysget", "syslput", "sysprod", "sysrc", "sysrput",
+        "then", "to", "trim", "unquote", "until", "upcase", "verify",
+        "while", "window"
+    )
+
+    builtins_conditionals = (
+        "do", "if", "then", "else", "end", "until", "while"
+    )
+
+    builtins_statements = (
+        "abort", "array", "attrib", "by", "call", "cards", "cards4",
+        "catname", "continue", "datalines", "datalines4", "delete", "delim",
+        "delimiter", "display", "dm", "drop", "endsas", "error", "file",
+        "filename", "footnote", "format", "goto", "in", "infile", "informat",
+        "input", "keep", "label", "leave", "length", "libname", "link",
+        "list", "lostcard", "merge", "missing", "modify", "options", "output",
+        "out", "page", "put", "redirect", "remove", "rename", "replace",
+        "retain", "return", "select", "set", "skip", "startsas", "stop",
+        "title", "update", "waitsas", "where", "window", "x", "systask"
+    )
+
+    builtins_sql = (
+        "add", "and", "alter", "as", "cascade", "check", "create",
+        "delete", "describe", "distinct", "drop", "foreign", "from",
+        "group", "having", "index", "insert", "into", "in", "key", "like",
+        "message", "modify", "msgtype", "not", "null", "on", "or",
+        "order", "primary", "references", "reset", "restrict", "select",
+        "set", "table", "unique", "update", "validate", "view", "where"
+    )
+
+    builtins_functions = (
+        "abs", "addr", "airy", "arcos", "arsin", "atan", "attrc",
+        "attrn", "band", "betainv", "blshift", "bnot", "bor",
+        "brshift", "bxor", "byte", "cdf", "ceil", "cexist", "cinv",
+        "close", "cnonct", "collate", "compbl", "compound",
+        "compress", "cos", "cosh", "css", "curobs", "cv", "daccdb",
+        "daccdbsl", "daccsl", "daccsyd", "dacctab", "dairy", "date",
+        "datejul", "datepart", "datetime", "day", "dclose", "depdb",
+        "depdbsl", "depsl", "depsyd",
+        "deptab", "dequote", "dhms", "dif", "digamma",
+        "dim", "dinfo", "dnum", "dopen", "doptname", "doptnum",
+        "dread", "dropnote", "dsname", "erf", "erfc", "exist", "exp",
+        "fappend", "fclose", "fcol", "fdelete", "fetch", "fetchobs",
+        "fexist", "fget", "fileexist", "filename", "fileref",
+        "finfo", "finv", "fipname", "fipnamel", "fipstate", "floor",
+        "fnonct", "fnote", "fopen", "foptname", "foptnum", "fpoint",
+        "fpos", "fput", "fread", "frewind", "frlen", "fsep", "fuzz",
+        "fwrite", "gaminv", "gamma", "getoption", "getvarc", "getvarn",
+        "hbound", "hms", "hosthelp", "hour", "ibessel", "index",
+        "indexc", "indexw", "input", "inputc", "inputn", "int",
+        "intck", "intnx", "intrr", "irr", "jbessel", "juldate",
+        "kurtosis", "lag", "lbound", "left", "length", "lgamma",
+        "libname", "libref", "log", "log10", "log2", "logpdf", "logpmf",
+        "logsdf", "lowcase", "max", "mdy", "mean", "min", "minute",
+        "mod", "month", "mopen", "mort", "n", "netpv", "nmiss",
+        "normal", "note", "npv", "open", "ordinal", "pathname",
+        "pdf", "peek", "peekc", "pmf", "point", "poisson", "poke",
+        "probbeta", "probbnml", "probchi", "probf", "probgam",
+        "probhypr", "probit", "probnegb", "probnorm", "probt",
+        "put", "putc", "putn", "qtr", "quote", "ranbin", "rancau",
+        "ranexp", "rangam", "range", "rank", "rannor", "ranpoi",
+        "rantbl", "rantri", "ranuni", "repeat", "resolve", "reverse",
+        "rewind", "right", "round", "saving", "scan", "sdf", "second",
+        "sign", "sin", "sinh", "skewness", "soundex", "spedis",
+        "sqrt", "std", "stderr", "stfips", "stname", "stnamel",
+        "substr", "sum", "symget", "sysget", "sysmsg", "sysprod",
+        "sysrc", "system", "tan", "tanh", "time", "timepart", "tinv",
+        "tnonct", "today", "translate", "tranwrd", "trigamma",
+        "trim", "trimn", "trunc", "uniform", "upcase", "uss", "var",
+        "varfmt", "varinfmt", "varlabel", "varlen", "varname",
+        "varnum", "varray", "varrayx", "vartype", "verify", "vformat",
+        "vformatd", "vformatdx", "vformatn", "vformatnx", "vformatw",
+        "vformatwx", "vformatx", "vinarray", "vinarrayx", "vinformat",
+        "vinformatd", "vinformatdx", "vinformatn", "vinformatnx",
+        "vinformatw", "vinformatwx", "vinformatx", "vlabel",
+        "vlabelx", "vlength", "vlengthx", "vname", "vnamex", "vtype",
+        "vtypex", "weekday", "year", "yyq", "zipfips", "zipname",
+        "zipnamel", "zipstate"
+    )
+
+    tokens = {
+        'root': [
+            include('comments'),
+            include('proc-data'),
+            include('cards-datalines'),
+            include('logs'),
+            include('general'),
+            (r'.', Text),
+        ],
+        # SAS is multi-line regardless, but * is ended by ;
+        'comments': [
+            (r'^\s*\*.*?;', Comment),
+            (r'/\*.*?\*/', Comment),
+            (r'^\s*\*(.|\n)*?;', Comment.Multiline),
+            (r'/[*](.|\n)*?[*]/', Comment.Multiline),
+        ],
+        # Special highlight for proc, data, quit, run
+        'proc-data': [
+            (r'(^|;)\s*(proc \w+|data|run|quit)[\s;]',
+             Keyword.Reserved),
+        ],
+        # Special highlight cards and datalines
+        'cards-datalines': [
+            (r'^\s*(datalines|cards)\s*;\s*$', Keyword, 'data'),
+        ],
+        'data': [
+            (r'(.|\n)*^\s*;\s*$', Other, '#pop'),
+        ],
+        # Special highlight for put NOTE|ERROR|WARNING (order matters)
+        'logs': [
+            (r'\n?^\s*%?put ', Keyword, 'log-messages'),
+        ],
+        'log-messages': [
+            (r'NOTE(:|-).*', Generic, '#pop'),
+            (r'WARNING(:|-).*', Generic.Emph, '#pop'),
+            (r'ERROR(:|-).*', Generic.Error, '#pop'),
+            include('general'),
+        ],
+        'general': [
+            include('keywords'),
+            include('vars-strings'),
+            include('special'),
+            include('numbers'),
+        ],
+        # Keywords, statements, functions, macros
+        'keywords': [
+            (words(builtins_statements,
+                   prefix = r'\b',
+                   suffix = r'\b'),
+             Keyword),
+            (words(builtins_sql,
+                   prefix = r'\b',
+                   suffix = r'\b'),
+             Keyword),
+            (words(builtins_conditionals,
+                   prefix = r'\b',
+                   suffix = r'\b'),
+             Keyword),
+            (words(builtins_macros,
+                   prefix = r'%',
+                   suffix = r'\b'),
+             Name.Builtin),
+            (words(builtins_functions,
+                   prefix = r'\b',
+                   suffix = r'\('),
+             Name.Builtin),
+        ],
+        # Strings and user-defined variables and macros (order matters)
+        'vars-strings': [
+            (r'&[a-z_]\w{0,31}\.?', Name.Variable),
+            (r'%[a-z_]\w{0,31}', Name.Function),
+            (r'\'', String, 'string_squote'),
+            (r'"', String, 'string_dquote'),
+        ],
+        'string_squote': [
+            ('\'', String, '#pop'),
+            (r'\\\\|\\"|\\\n', String.Escape),
+            # AFAIK, macro variables are not evaluated in single quotes
+            # (r'&', Name.Variable, 'validvar'),
+            (r'[^$\'\\]+', String),
+            (r'[$\'\\]', String),
+        ],
+        'string_dquote': [
+            (r'"', String, '#pop'),
+            (r'\\\\|\\"|\\\n', String.Escape),
+            (r'&', Name.Variable, 'validvar'),
+            (r'[^$&"\\]+', String),
+            (r'[$"\\]', String),
+        ],
+        'validvar': [
+            (r'[a-z_]\w{0,31}\.?', Name.Variable, '#pop'),
+        ],
+        # SAS numbers and special variables
+        'numbers': [
+            (r'\b[+-]?([0-9]+(\.[0-9]+)?|\.[0-9]+|\.)(E[+-]?[0-9]+)?i?\b',
+             Number),
+        ],
+        'special': [
+            (r'(null|missing|_all_|_automatic_|_character_|_n_|'
+             r'_infile_|_name_|_null_|_numeric_|_user_|_webout_)',
+             Keyword.Constant),
+        ],
+        # 'operators': [
+        #     (r'(-|=|<=|>=|<|>|<>|&|!=|'
+        #      r'\||\*|\+|\^|/|!|~|~=)', Operator)
+        # ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/savi.py b/.venv/Lib/site-packages/pygments/lexers/savi.py
new file mode 100644
index 0000000..1e443ae
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/savi.py
@@ -0,0 +1,171 @@
+"""
+    pygments.lexers.savi
+    ~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Savi.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, include
+from pygments.token import Whitespace, Keyword, Name, String, Number, \
+  Operator, Punctuation, Comment, Generic, Error
+
+__all__ = ['SaviLexer']
+
+
+# The canonical version of this file can be found in the following repository,
+# where it is kept in sync with any language changes, as well as the other
+# pygments-like lexers that are maintained for use with other tools:
+# - https://github.com/savi-lang/savi/blob/main/tooling/pygments/lexers/savi.py
+#
+# If you're changing this file in the pygments repository, please ensure that
+# any changes you make are also propagated to the official Savi repository,
+# in order to avoid accidental clobbering of your changes later when an update
+# from the Savi repository flows forward into the pygments repository.
+#
+# If you're changing this file in the Savi repository, please ensure that
+# any changes you make are also reflected in the other pygments-like lexers
+# (rouge, vscode, etc) so that all of the lexers can be kept cleanly in sync.
+
+class SaviLexer(RegexLexer):
+    """
+    For Savi source code.
+
+    .. versionadded: 2.10
+    """
+
+    name = 'Savi'
+    url = 'https://github.com/savi-lang/savi'
+    aliases = ['savi']
+    filenames = ['*.savi']
+    version_added = ''
+
+    tokens = {
+      "root": [
+        # Line Comment
+        (r'//.*?$', Comment.Single),
+
+        # Doc Comment
+        (r'::.*?$', Comment.Single),
+
+        # Capability Operator
+        (r'(\')(\w+)(?=[^\'])', bygroups(Operator, Name)),
+
+        # Double-Quote String
+        (r'\w?"', String.Double, "string.double"),
+
+        # Single-Char String
+        (r"'", String.Char, "string.char"),
+
+        # Type Name
+        (r'(_?[A-Z]\w*)', Name.Class),
+
+        # Nested Type Name
+        (r'(\.)(\s*)(_?[A-Z]\w*)', bygroups(Punctuation, Whitespace, Name.Class)),
+
+        # Declare
+        (r'^([ \t]*)(:\w+)',
+          bygroups(Whitespace, Name.Tag),
+          "decl"),
+
+        # Error-Raising Calls/Names
+        (r'((\w+|\+|\-|\*)\!)', Generic.Deleted),
+
+        # Numeric Values
+        (r'\b\d([\d_]*(\.[\d_]+)?)\b', Number),
+
+        # Hex Numeric Values
+        (r'\b0x([0-9a-fA-F_]+)\b', Number.Hex),
+
+        # Binary Numeric Values
+        (r'\b0b([01_]+)\b', Number.Bin),
+
+        # Function Call (with braces)
+        (r'\w+(?=\()', Name.Function),
+
+        # Function Call (with receiver)
+        (r'(\.)(\s*)(\w+)', bygroups(Punctuation, Whitespace, Name.Function)),
+
+        # Function Call (with self receiver)
+        (r'(@)(\w+)', bygroups(Punctuation, Name.Function)),
+
+        # Parenthesis
+        (r'\(', Punctuation, "root"),
+        (r'\)', Punctuation, "#pop"),
+
+        # Brace
+        (r'\{', Punctuation, "root"),
+        (r'\}', Punctuation, "#pop"),
+
+        # Bracket
+        (r'\[', Punctuation, "root"),
+        (r'(\])(\!)', bygroups(Punctuation, Generic.Deleted), "#pop"),
+        (r'\]', Punctuation, "#pop"),
+
+        # Punctuation
+        (r'[,;:\.@]', Punctuation),
+
+        # Piping Operators
+        (r'(\|\>)', Operator),
+
+        # Branching Operators
+        (r'(\&\&|\|\||\?\?|\&\?|\|\?|\.\?)', Operator),
+
+        # Comparison Operators
+        (r'(\<\=\>|\=\~|\=\=|\<\=|\>\=|\<|\>)', Operator),
+
+        # Arithmetic Operators
+        (r'(\+|\-|\/|\*|\%)', Operator),
+
+        # Assignment Operators
+        (r'(\=)', Operator),
+
+        # Other Operators
+        (r'(\!|\<\<|\<|\&|\|)', Operator),
+
+        # Identifiers
+        (r'\b\w+\b', Name),
+
+        # Whitespace
+        (r'[ \t\r]+\n*|\n+', Whitespace),
+      ],
+
+      # Declare (nested rules)
+      "decl": [
+        (r'\b[a-z_]\w*\b(?!\!)', Keyword.Declaration),
+        (r':', Punctuation, "#pop"),
+        (r'\n', Whitespace, "#pop"),
+        include("root"),
+      ],
+
+      # Double-Quote String (nested rules)
+      "string.double": [
+        (r'\\\(', String.Interpol, "string.interpolation"),
+        (r'\\u[0-9a-fA-F]{4}', String.Escape),
+        (r'\\x[0-9a-fA-F]{2}', String.Escape),
+        (r'\\[bfnrt\\\']', String.Escape),
+        (r'\\"', String.Escape),
+        (r'"', String.Double, "#pop"),
+        (r'[^\\"]+', String.Double),
+        (r'.', Error),
+      ],
+
+      # Single-Char String (nested rules)
+      "string.char": [
+        (r'\\u[0-9a-fA-F]{4}', String.Escape),
+        (r'\\x[0-9a-fA-F]{2}', String.Escape),
+        (r'\\[bfnrt\\\']', String.Escape),
+        (r"\\'", String.Escape),
+        (r"'", String.Char, "#pop"),
+        (r"[^\\']+", String.Char),
+        (r'.', Error),
+      ],
+
+      # Interpolation inside String (nested rules)
+      "string.interpolation": [
+        (r"\)", String.Interpol, "#pop"),
+        include("root"),
+      ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/scdoc.py b/.venv/Lib/site-packages/pygments/lexers/scdoc.py
new file mode 100644
index 0000000..8e850d0
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/scdoc.py
@@ -0,0 +1,85 @@
+"""
+    pygments.lexers.scdoc
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for scdoc, a simple man page generator.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, bygroups, using, this
+from pygments.token import Text, Comment, Keyword, String, Generic
+
+__all__ = ['ScdocLexer']
+
+
+class ScdocLexer(RegexLexer):
+    """
+    `scdoc` is a simple man page generator for POSIX systems written in C99.
+    """
+    name = 'scdoc'
+    url = 'https://git.sr.ht/~sircmpwn/scdoc'
+    aliases = ['scdoc', 'scd']
+    filenames = ['*.scd', '*.scdoc']
+    version_added = '2.5'
+    flags = re.MULTILINE
+
+    tokens = {
+        'root': [
+            # comment
+            (r'^(;.+\n)', bygroups(Comment)),
+
+            # heading with pound prefix
+            (r'^(#)([^#].+\n)', bygroups(Generic.Heading, Text)),
+            (r'^(#{2})(.+\n)', bygroups(Generic.Subheading, Text)),
+            # bulleted lists
+            (r'^(\s*)([*-])(\s)(.+\n)',
+            bygroups(Text, Keyword, Text, using(this, state='inline'))),
+            # numbered lists
+            (r'^(\s*)(\.+\.)( .+\n)',
+            bygroups(Text, Keyword, using(this, state='inline'))),
+            # quote
+            (r'^(\s*>\s)(.+\n)', bygroups(Keyword, Generic.Emph)),
+            # text block
+            (r'^(```\n)([\w\W]*?)(^```$)', bygroups(String, Text, String)),
+
+            include('inline'),
+        ],
+        'inline': [
+            # escape
+            (r'\\.', Text),
+            # underlines
+            (r'(\s)(_[^_]+_)(\W|\n)', bygroups(Text, Generic.Emph, Text)),
+            # bold
+            (r'(\s)(\*[^*]+\*)(\W|\n)', bygroups(Text, Generic.Strong, Text)),
+            # inline code
+            (r'`[^`]+`', String.Backtick),
+
+            # general text, must come last!
+            (r'[^\\\s]+', Text),
+            (r'.', Text),
+        ],
+    }
+
+    def analyse_text(text):
+        """We checks for bold and underline text with * and _. Also
+        every scdoc file must start with a strictly defined first line."""
+        result = 0
+
+        if '*' in text:
+            result += 0.01
+
+        if '_' in text:
+            result += 0.01
+
+        # name(section) ["left_footer" ["center_header"]]
+        first_line = text.partition('\n')[0]
+        scdoc_preamble_pattern = r'^.*\([1-7]\)( "[^"]+"){0,2}$'
+
+        if re.search(scdoc_preamble_pattern, first_line):
+            result += 0.5
+
+        return result
diff --git a/.venv/Lib/site-packages/pygments/lexers/scripting.py b/.venv/Lib/site-packages/pygments/lexers/scripting.py
new file mode 100644
index 0000000..17deae9
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/scripting.py
@@ -0,0 +1,1614 @@
+"""
+    pygments.lexers.scripting
+    ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for scripting and embedded languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import RegexLexer, include, bygroups, default, combined, \
+    words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Error, Whitespace, Other
+from pygments.util import get_bool_opt, get_list_opt
+
+__all__ = ['LuaLexer', 'LuauLexer', 'MoonScriptLexer', 'ChaiscriptLexer', 'LSLLexer',
+           'AppleScriptLexer', 'RexxLexer', 'MOOCodeLexer', 'HybrisLexer',
+           'EasytrieveLexer', 'JclLexer', 'MiniScriptLexer']
+
+
+def all_lua_builtins():
+    from pygments.lexers._lua_builtins import MODULES
+    return [w for values in MODULES.values() for w in values]
+
+class LuaLexer(RegexLexer):
+    """
+    For Lua source code.
+
+    Additional options accepted:
+
+    `func_name_highlighting`
+        If given and ``True``, highlight builtin function names
+        (default: ``True``).
+    `disabled_modules`
+        If given, must be a list of module names whose function names
+        should not be highlighted. By default all modules are highlighted.
+
+        To get a list of allowed modules have a look into the
+        `_lua_builtins` module:
+
+        .. sourcecode:: pycon
+
+            >>> from pygments.lexers._lua_builtins import MODULES
+            >>> MODULES.keys()
+            ['string', 'coroutine', 'modules', 'io', 'basic', ...]
+    """
+
+    name = 'Lua'
+    url = 'https://www.lua.org/'
+    aliases = ['lua']
+    filenames = ['*.lua', '*.wlua']
+    mimetypes = ['text/x-lua', 'application/x-lua']
+    version_added = ''
+
+    _comment_multiline = r'(?:--\[(?P=*)\[[\w\W]*?\](?P=level)\])'
+    _comment_single = r'(?:--.*$)'
+    _space = r'(?:\s+)'
+    _s = rf'(?:{_comment_multiline}|{_comment_single}|{_space})'
+    _name = r'(?:[^\W\d]\w*)'
+
+    tokens = {
+        'root': [
+            # Lua allows a file to start with a shebang.
+            (r'#!.*', Comment.Preproc),
+            default('base'),
+        ],
+        'ws': [
+            (_comment_multiline, Comment.Multiline),
+            (_comment_single, Comment.Single),
+            (_space, Whitespace),
+        ],
+        'base': [
+            include('ws'),
+
+            (r'(?i)0x[\da-f]*(\.[\da-f]*)?(p[+-]?\d+)?', Number.Hex),
+            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
+            (r'(?i)\d+e[+-]?\d+', Number.Float),
+            (r'\d+', Number.Integer),
+
+            # multiline strings
+            (r'(?s)\[(=*)\[.*?\]\1\]', String),
+
+            (r'::', Punctuation, 'label'),
+            (r'\.{3}', Punctuation),
+            (r'[=<>|~&+\-*/%#^]+|\.\.', Operator),
+            (r'[\[\]{}().,:;]+', Punctuation),
+            (r'(and|or|not)\b', Operator.Word),
+
+            ('(break|do|else|elseif|end|for|if|in|repeat|return|then|until|'
+             r'while)\b', Keyword.Reserved),
+            (r'goto\b', Keyword.Reserved, 'goto'),
+            (r'(local)\b', Keyword.Declaration),
+            (r'(true|false|nil)\b', Keyword.Constant),
+
+            (r'(function)\b', Keyword.Reserved, 'funcname'),
+
+            (words(all_lua_builtins(), suffix=r"\b"), Name.Builtin),
+            (fr'[A-Za-z_]\w*(?={_s}*[.:])', Name.Variable, 'varname'),
+            (fr'[A-Za-z_]\w*(?={_s}*\()', Name.Function),
+            (r'[A-Za-z_]\w*', Name.Variable),
+
+            ("'", String.Single, combined('stringescape', 'sqs')),
+            ('"', String.Double, combined('stringescape', 'dqs'))
+        ],
+
+        'varname': [
+            include('ws'),
+            (r'\.\.', Operator, '#pop'),
+            (r'[.:]', Punctuation),
+            (rf'{_name}(?={_s}*[.:])', Name.Property),
+            (rf'{_name}(?={_s}*\()', Name.Function, '#pop'),
+            (_name, Name.Property, '#pop'),
+        ],
+
+        'funcname': [
+            include('ws'),
+            (r'[.:]', Punctuation),
+            (rf'{_name}(?={_s}*[.:])', Name.Class),
+            (_name, Name.Function, '#pop'),
+            # inline function
+            (r'\(', Punctuation, '#pop'),
+        ],
+
+        'goto': [
+            include('ws'),
+            (_name, Name.Label, '#pop'),
+        ],
+
+        'label': [
+            include('ws'),
+            (r'::', Punctuation, '#pop'),
+            (_name, Name.Label),
+        ],
+
+        'stringescape': [
+            (r'\\([abfnrtv\\"\']|[\r\n]{1,2}|z\s*|x[0-9a-fA-F]{2}|\d{1,3}|'
+             r'u\{[0-9a-fA-F]+\})', String.Escape),
+        ],
+
+        'sqs': [
+            (r"'", String.Single, '#pop'),
+            (r"[^\\']+", String.Single),
+        ],
+
+        'dqs': [
+            (r'"', String.Double, '#pop'),
+            (r'[^\\"]+', String.Double),
+        ]
+    }
+
+    def __init__(self, **options):
+        self.func_name_highlighting = get_bool_opt(
+            options, 'func_name_highlighting', True)
+        self.disabled_modules = get_list_opt(options, 'disabled_modules', [])
+
+        self._functions = set()
+        if self.func_name_highlighting:
+            from pygments.lexers._lua_builtins import MODULES
+            for mod, func in MODULES.items():
+                if mod not in self.disabled_modules:
+                    self._functions.update(func)
+        RegexLexer.__init__(self, **options)
+
+    def get_tokens_unprocessed(self, text):
+        for index, token, value in \
+                RegexLexer.get_tokens_unprocessed(self, text):
+            if token is Name.Builtin and value not in self._functions:
+                if '.' in value:
+                    a, b = value.split('.')
+                    yield index, Name, a
+                    yield index + len(a), Punctuation, '.'
+                    yield index + len(a) + 1, Name, b
+                else:
+                    yield index, Name, value
+                continue
+            yield index, token, value
+
+def _luau_make_expression(should_pop, _s):
+    temp_list = [
+        (r'0[xX][\da-fA-F_]*', Number.Hex, '#pop'),
+        (r'0[bB][\d_]*', Number.Bin, '#pop'),
+        (r'\.?\d[\d_]*(?:\.[\d_]*)?(?:[eE][+-]?[\d_]+)?', Number.Float, '#pop'),
+
+        (words((
+            'true', 'false', 'nil'
+        ), suffix=r'\b'), Keyword.Constant, '#pop'),
+
+        (r'\[(=*)\[[.\n]*?\]\1\]', String, '#pop'),
+
+        (r'(\.)([a-zA-Z_]\w*)(?=%s*[({"\'])', bygroups(Punctuation, Name.Function), '#pop'),
+        (r'(\.)([a-zA-Z_]\w*)', bygroups(Punctuation, Name.Variable), '#pop'),
+
+        (rf'[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*(?={_s}*[({{"\'])', Name.Other, '#pop'),
+        (r'[a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*', Name, '#pop'),
+    ]
+    if should_pop:
+        return temp_list
+    return [entry[:2] for entry in temp_list]
+
+def _luau_make_expression_special(should_pop):
+    temp_list = [
+        (r'\{', Punctuation, ('#pop', 'closing_brace_base', 'expression')),
+        (r'\(', Punctuation, ('#pop', 'closing_parenthesis_base', 'expression')),
+
+        (r'::?', Punctuation, ('#pop', 'type_end', 'type_start')),
+
+        (r"'", String.Single, ('#pop', 'string_single')),
+        (r'"', String.Double, ('#pop', 'string_double')),
+        (r'`', String.Backtick, ('#pop', 'string_interpolated')),
+    ]
+    if should_pop:
+        return temp_list
+    return [(entry[0], entry[1], entry[2][1:]) for entry in temp_list]
+
+class LuauLexer(RegexLexer):
+    """
+    For Luau source code.
+
+    Additional options accepted:
+
+    `include_luau_builtins`
+        If given and ``True``, automatically highlight Luau builtins
+        (default: ``True``).
+    `include_roblox_builtins`
+        If given and ``True``, automatically highlight Roblox-specific builtins
+        (default: ``False``).
+    `additional_builtins`
+        If given, must be a list of additional builtins to highlight.
+    `disabled_builtins`
+        If given, must be a list of builtins that will not be highlighted.
+    """
+
+    name = 'Luau'
+    url = 'https://luau-lang.org/'
+    aliases = ['luau']
+    filenames = ['*.luau']
+    version_added = '2.18'
+
+    _comment_multiline = r'(?:--\[(?P=*)\[[\w\W]*?\](?P=level)\])'
+    _comment_single = r'(?:--.*$)'
+    _s = r'(?:{}|{}|{})'.format(_comment_multiline, _comment_single, r'\s+')
+
+    tokens = {
+        'root': [
+            (r'#!.*', Comment.Hashbang, 'base'),
+            default('base'),
+        ],
+
+        'ws': [
+            (_comment_multiline, Comment.Multiline),
+            (_comment_single, Comment.Single),
+            (r'\s+', Whitespace),
+        ],
+
+        'base': [
+            include('ws'),
+
+            *_luau_make_expression_special(False),
+            (r'\.\.\.', Punctuation),
+
+            (rf'type\b(?={_s}+[a-zA-Z_])', Keyword.Reserved, 'type_declaration'),
+            (rf'export\b(?={_s}+[a-zA-Z_])', Keyword.Reserved),
+
+            (r'(?:\.\.|//|[+\-*\/%^<>=])=?', Operator, 'expression'),
+            (r'~=', Operator, 'expression'),
+
+            (words((
+                'and', 'or', 'not'
+            ), suffix=r'\b'), Operator.Word, 'expression'),
+
+            (words((
+                'elseif', 'for', 'if', 'in', 'repeat', 'return', 'until',
+                'while'), suffix=r'\b'), Keyword.Reserved, 'expression'),
+            (r'local\b', Keyword.Declaration, 'expression'),
+
+            (r'function\b', Keyword.Reserved, ('expression', 'func_name')),
+
+            (r'[\])};]+', Punctuation),
+
+            include('expression_static'),
+            *_luau_make_expression(False, _s),
+
+            (r'[\[.,]', Punctuation, 'expression'),
+        ],
+        'expression_static': [
+            (words((
+                'break', 'continue', 'do', 'else', 'elseif', 'end', 'for',
+                'if', 'in', 'repeat', 'return', 'then', 'until', 'while'),
+                suffix=r'\b'), Keyword.Reserved),
+        ],
+        'expression': [
+            include('ws'),
+
+            (r'if\b', Keyword.Reserved, ('ternary', 'expression')),
+
+            (r'local\b', Keyword.Declaration),
+            *_luau_make_expression_special(True),
+            (r'\.\.\.', Punctuation, '#pop'),
+
+            (r'function\b', Keyword.Reserved, 'func_name'),
+
+            include('expression_static'),
+            *_luau_make_expression(True, _s),
+
+            default('#pop'),
+        ],
+        'ternary': [
+            include('ws'),
+
+            (r'else\b', Keyword.Reserved, '#pop'),
+            (words((
+                'then', 'elseif',
+            ), suffix=r'\b'), Operator.Reserved, 'expression'),
+
+            default('#pop'),
+        ],
+
+        'closing_brace_pop': [
+            (r'\}', Punctuation, '#pop'),
+        ],
+        'closing_parenthesis_pop': [
+            (r'\)', Punctuation, '#pop'),
+        ],
+        'closing_gt_pop': [
+            (r'>', Punctuation, '#pop'),
+        ],
+
+        'closing_parenthesis_base': [
+            include('closing_parenthesis_pop'),
+            include('base'),
+        ],
+        'closing_parenthesis_type': [
+            include('closing_parenthesis_pop'),
+            include('type'),
+        ],
+        'closing_brace_base': [
+            include('closing_brace_pop'),
+            include('base'),
+        ],
+        'closing_brace_type': [
+            include('closing_brace_pop'),
+            include('type'),
+        ],
+        'closing_gt_type': [
+            include('closing_gt_pop'),
+            include('type'),
+        ],
+
+        'string_escape': [
+            (r'\\z\s*', String.Escape),
+            (r'\\(?:[abfnrtvz\\"\'`\{\n])|[\r\n]{1,2}|x[\da-fA-F]{2}|\d{1,3}|'
+             r'u\{\}[\da-fA-F]*\}', String.Escape),
+        ],
+        'string_single': [
+            include('string_escape'),
+
+            (r"'", String.Single, "#pop"),
+            (r"[^\\']+", String.Single),
+        ],
+        'string_double': [
+            include('string_escape'),
+
+            (r'"', String.Double, "#pop"),
+            (r'[^\\"]+', String.Double),
+        ],
+        'string_interpolated': [
+            include('string_escape'),
+
+            (r'\{', Punctuation, ('closing_brace_base', 'expression')),
+
+            (r'`', String.Backtick, "#pop"),
+            (r'[^\\`\{]+', String.Backtick),
+        ],
+
+        'func_name': [
+            include('ws'),
+
+            (r'[.:]', Punctuation),
+            (rf'[a-zA-Z_]\w*(?={_s}*[.:])', Name.Class),
+            (r'[a-zA-Z_]\w*', Name.Function),
+
+            (r'<', Punctuation, 'closing_gt_type'),
+
+            (r'\(', Punctuation, '#pop'),
+        ],
+
+        'type': [
+            include('ws'),
+
+            (r'\(', Punctuation, 'closing_parenthesis_type'),
+            (r'\{', Punctuation, 'closing_brace_type'),
+            (r'<', Punctuation, 'closing_gt_type'),
+
+            (r"'", String.Single, 'string_single'),
+            (r'"', String.Double, 'string_double'),
+
+            (r'[|&\.,\[\]:=]+', Punctuation),
+            (r'->', Punctuation),
+
+            (r'typeof\(', Name.Builtin, ('closing_parenthesis_base',
+                                         'expression')),
+            (r'[a-zA-Z_]\w*', Name.Class),
+        ],
+        'type_start': [
+            include('ws'),
+
+            (r'\(', Punctuation, ('#pop', 'closing_parenthesis_type')),
+            (r'\{', Punctuation, ('#pop', 'closing_brace_type')),
+            (r'<', Punctuation, ('#pop', 'closing_gt_type')),
+
+            (r"'", String.Single, ('#pop', 'string_single')),
+            (r'"', String.Double, ('#pop', 'string_double')),
+
+            (r'typeof\(', Name.Builtin, ('#pop', 'closing_parenthesis_base',
+                                         'expression')),
+            (r'[a-zA-Z_]\w*', Name.Class, '#pop'),
+        ],
+        'type_end': [
+            include('ws'),
+
+            (r'[|&\.]', Punctuation, 'type_start'),
+            (r'->', Punctuation, 'type_start'),
+
+            (r'<', Punctuation, 'closing_gt_type'),
+
+            default('#pop'),
+        ],
+        'type_declaration': [
+            include('ws'),
+
+            (r'[a-zA-Z_]\w*', Name.Class),
+            (r'<', Punctuation, 'closing_gt_type'),
+
+            (r'=', Punctuation, ('#pop', 'type_end', 'type_start')),
+        ],
+    }
+
+    def __init__(self, **options):
+        self.include_luau_builtins = get_bool_opt(
+            options, 'include_luau_builtins', True)
+        self.include_roblox_builtins = get_bool_opt(
+            options, 'include_roblox_builtins', False)
+        self.additional_builtins = get_list_opt(options, 'additional_builtins', [])
+        self.disabled_builtins = get_list_opt(options, 'disabled_builtins', [])
+
+        self._builtins = set(self.additional_builtins)
+        if self.include_luau_builtins:
+            from pygments.lexers._luau_builtins import LUAU_BUILTINS
+            self._builtins.update(LUAU_BUILTINS)
+        if self.include_roblox_builtins:
+            from pygments.lexers._luau_builtins import ROBLOX_BUILTINS
+            self._builtins.update(ROBLOX_BUILTINS)
+        if self.additional_builtins:
+            self._builtins.update(self.additional_builtins)
+        self._builtins.difference_update(self.disabled_builtins)
+
+        RegexLexer.__init__(self, **options)
+
+    def get_tokens_unprocessed(self, text):
+        for index, token, value in \
+                RegexLexer.get_tokens_unprocessed(self, text):
+            if token is Name or token is Name.Other:
+                split_value = value.split('.')
+                complete_value = []
+                new_index = index
+                for position in range(len(split_value), 0, -1):
+                    potential_string = '.'.join(split_value[:position])
+                    if potential_string in self._builtins:
+                        yield index, Name.Builtin, potential_string
+                        new_index += len(potential_string)
+
+                        if complete_value:
+                            yield new_index, Punctuation, '.'
+                            new_index += 1
+                        break
+                    complete_value.insert(0, split_value[position - 1])
+
+                for position, substring in enumerate(complete_value):
+                    if position + 1 == len(complete_value):
+                        if token is Name:
+                            yield new_index, Name.Variable, substring
+                            continue
+                        yield new_index, Name.Function, substring
+                        continue
+                    yield new_index, Name.Variable, substring
+                    new_index += len(substring)
+                    yield new_index, Punctuation, '.'
+                    new_index += 1
+
+                continue
+            yield index, token, value
+
+class MoonScriptLexer(LuaLexer):
+    """
+    For MoonScript source code.
+    """
+
+    name = 'MoonScript'
+    url = 'http://moonscript.org'
+    aliases = ['moonscript', 'moon']
+    filenames = ['*.moon']
+    mimetypes = ['text/x-moonscript', 'application/x-moonscript']
+    version_added = '1.5'
+
+    tokens = {
+        'root': [
+            (r'#!(.*?)$', Comment.Preproc),
+            default('base'),
+        ],
+        'base': [
+            ('--.*$', Comment.Single),
+            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number.Float),
+            (r'(?i)\d+e[+-]?\d+', Number.Float),
+            (r'(?i)0x[0-9a-f]*', Number.Hex),
+            (r'\d+', Number.Integer),
+            (r'\n', Whitespace),
+            (r'[^\S\n]+', Text),
+            (r'(?s)\[(=*)\[.*?\]\1\]', String),
+            (r'(->|=>)', Name.Function),
+            (r':[a-zA-Z_]\w*', Name.Variable),
+            (r'(==|!=|~=|<=|>=|\.\.\.|\.\.|[=+\-*/%^<>#!.\\:])', Operator),
+            (r'[;,]', Punctuation),
+            (r'[\[\]{}()]', Keyword.Type),
+            (r'[a-zA-Z_]\w*:', Name.Variable),
+            (words((
+                'class', 'extends', 'if', 'then', 'super', 'do', 'with',
+                'import', 'export', 'while', 'elseif', 'return', 'for', 'in',
+                'from', 'when', 'using', 'else', 'and', 'or', 'not', 'switch',
+                'break'), suffix=r'\b'),
+             Keyword),
+            (r'(true|false|nil)\b', Keyword.Constant),
+            (r'(and|or|not)\b', Operator.Word),
+            (r'(self)\b', Name.Builtin.Pseudo),
+            (r'@@?([a-zA-Z_]\w*)?', Name.Variable.Class),
+            (r'[A-Z]\w*', Name.Class),  # proper name
+            (words(all_lua_builtins(), suffix=r"\b"), Name.Builtin),
+            (r'[A-Za-z_]\w*', Name),
+            ("'", String.Single, combined('stringescape', 'sqs')),
+            ('"', String.Double, combined('stringescape', 'dqs'))
+        ],
+        'stringescape': [
+            (r'''\\([abfnrtv\\"']|\d{1,3})''', String.Escape)
+        ],
+        'sqs': [
+            ("'", String.Single, '#pop'),
+            ("[^']+", String)
+        ],
+        'dqs': [
+            ('"', String.Double, '#pop'),
+            ('[^"]+', String)
+        ]
+    }
+
+    def get_tokens_unprocessed(self, text):
+        # set . as Operator instead of Punctuation
+        for index, token, value in LuaLexer.get_tokens_unprocessed(self, text):
+            if token == Punctuation and value == ".":
+                token = Operator
+            yield index, token, value
+
+
+class ChaiscriptLexer(RegexLexer):
+    """
+    For ChaiScript source code.
+    """
+
+    name = 'ChaiScript'
+    url = 'http://chaiscript.com/'
+    aliases = ['chaiscript', 'chai']
+    filenames = ['*.chai']
+    mimetypes = ['text/x-chaiscript', 'application/x-chaiscript']
+    version_added = '2.0'
+
+    flags = re.DOTALL | re.MULTILINE
+
+    tokens = {
+        'commentsandwhitespace': [
+            (r'\s+', Text),
+            (r'//.*?\n', Comment.Single),
+            (r'/\*.*?\*/', Comment.Multiline),
+            (r'^\#.*?\n', Comment.Single)
+        ],
+        'slashstartsregex': [
+            include('commentsandwhitespace'),
+            (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
+             r'([gim]+\b|\B)', String.Regex, '#pop'),
+            (r'(?=/)', Text, ('#pop', 'badregex')),
+            default('#pop')
+        ],
+        'badregex': [
+            (r'\n', Text, '#pop')
+        ],
+        'root': [
+            include('commentsandwhitespace'),
+            (r'\n', Text),
+            (r'[^\S\n]+', Text),
+            (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|\.\.'
+             r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, 'slashstartsregex'),
+            (r'[{(\[;,]', Punctuation, 'slashstartsregex'),
+            (r'[})\].]', Punctuation),
+            (r'[=+\-*/]', Operator),
+            (r'(for|in|while|do|break|return|continue|if|else|'
+             r'throw|try|catch'
+             r')\b', Keyword, 'slashstartsregex'),
+            (r'(var)\b', Keyword.Declaration, 'slashstartsregex'),
+            (r'(attr|def|fun)\b', Keyword.Reserved),
+            (r'(true|false)\b', Keyword.Constant),
+            (r'(eval|throw)\b', Name.Builtin),
+            (r'`\S+`', Name.Builtin),
+            (r'[$a-zA-Z_]\w*', Name.Other),
+            (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'[0-9]+', Number.Integer),
+            (r'"', String.Double, 'dqstring'),
+            (r"'(\\\\|\\[^\\]|[^'\\])*'", String.Single),
+        ],
+        'dqstring': [
+            (r'\$\{[^"}]+?\}', String.Interpol),
+            (r'\$', String.Double),
+            (r'\\\\', String.Double),
+            (r'\\"', String.Double),
+            (r'[^\\"$]+', String.Double),
+            (r'"', String.Double, '#pop'),
+        ],
+    }
+
+
+class LSLLexer(RegexLexer):
+    """
+    For Second Life's Linden Scripting Language source code.
+    """
+
+    name = 'LSL'
+    aliases = ['lsl']
+    filenames = ['*.lsl']
+    mimetypes = ['text/x-lsl']
+    url = 'https://wiki.secondlife.com/wiki/Linden_Scripting_Language'
+    version_added = '2.0'
+
+    flags = re.MULTILINE
+
+    lsl_keywords = r'\b(?:do|else|for|if|jump|return|while)\b'
+    lsl_types = r'\b(?:float|integer|key|list|quaternion|rotation|string|vector)\b'
+    lsl_states = r'\b(?:(?:state)\s+\w+|default)\b'
+    lsl_events = r'\b(?:state_(?:entry|exit)|touch(?:_(?:start|end))?|(?:land_)?collision(?:_(?:start|end))?|timer|listen|(?:no_)?sensor|control|(?:not_)?at_(?:rot_)?target|money|email|run_time_permissions|changed|attach|dataserver|moving_(?:start|end)|link_message|(?:on|object)_rez|remote_data|http_re(?:sponse|quest)|path_update|transaction_result)\b'
+    lsl_functions_builtin = r'\b(?:ll(?:ReturnObjectsBy(?:ID|Owner)|Json(?:2List|[GS]etValue|ValueType)|Sin|Cos|Tan|Atan2|Sqrt|Pow|Abs|Fabs|Frand|Floor|Ceil|Round|Vec(?:Mag|Norm|Dist)|Rot(?:Between|2(?:Euler|Fwd|Left|Up))|(?:Euler|Axes)2Rot|Whisper|(?:Region|Owner)?Say|Shout|Listen(?:Control|Remove)?|Sensor(?:Repeat|Remove)?|Detected(?:Name|Key|Owner|Type|Pos|Vel|Grab|Rot|Group|LinkNumber)|Die|Ground|Wind|(?:[GS]et)(?:AnimationOverride|MemoryLimit|PrimMediaParams|ParcelMusicURL|Object(?:Desc|Name)|PhysicsMaterial|Status|Scale|Color|Alpha|Texture|Pos|Rot|Force|Torque)|ResetAnimationOverride|(?:Scale|Offset|Rotate)Texture|(?:Rot)?Target(?:Remove)?|(?:Stop)?MoveToTarget|Apply(?:Rotational)?Impulse|Set(?:KeyframedMotion|ContentType|RegionPos|(?:Angular)?Velocity|Buoyancy|HoverHeight|ForceAndTorque|TimerEvent|ScriptState|Damage|TextureAnim|Sound(?:Queueing|Radius)|Vehicle(?:Type|(?:Float|Vector|Rotation)Param)|(?:Touch|Sit)?Text|Camera(?:Eye|At)Offset|PrimitiveParams|ClickAction|Link(?:Alpha|Color|PrimitiveParams(?:Fast)?|Texture(?:Anim)?|Camera|Media)|RemoteScriptAccessPin|PayPrice|LocalRot)|ScaleByFactor|Get(?:(?:Max|Min)ScaleFactor|ClosestNavPoint|StaticPath|SimStats|Env|PrimitiveParams|Link(?:PrimitiveParams|Number(?:OfSides)?|Key|Name|Media)|HTTPHeader|FreeURLs|Object(?:Details|PermMask|PrimCount)|Parcel(?:MaxPrims|Details|Prim(?:Count|Owners))|Attached|(?:SPMax|Free|Used)Memory|Region(?:Name|TimeDilation|FPS|Corner|AgentCount)|Root(?:Position|Rotation)|UnixTime|(?:Parcel|Region)Flags|(?:Wall|GMT)clock|SimulatorHostname|BoundingBox|GeometricCenter|Creator|NumberOf(?:Prims|NotecardLines|Sides)|Animation(?:List)?|(?:Camera|Local)(?:Pos|Rot)|Vel|Accel|Omega|Time(?:stamp|OfDay)|(?:Object|CenterOf)?Mass|MassMKS|Energy|Owner|(?:Owner)?Key|SunDirection|Texture(?:Offset|Scale|Rot)|Inventory(?:Number|Name|Key|Type|Creator|PermMask)|Permissions(?:Key)?|StartParameter|List(?:Length|EntryType)|Date|Agent(?:Size|Info|Language|List)|LandOwnerAt|NotecardLine|Script(?:Name|State))|(?:Get|Reset|GetAndReset)Time|PlaySound(?:Slave)?|LoopSound(?:Master|Slave)?|(?:Trigger|Stop|Preload)Sound|(?:(?:Get|Delete)Sub|Insert)String|To(?:Upper|Lower)|Give(?:InventoryList|Money)|RezObject|(?:Stop)?LookAt|Sleep|CollisionFilter|(?:Take|Release)Controls|DetachFromAvatar|AttachToAvatar(?:Temp)?|InstantMessage|(?:GetNext)?Email|StopHover|MinEventDelay|RotLookAt|String(?:Length|Trim)|(?:Start|Stop)Animation|TargetOmega|RequestPermissions|(?:Create|Break)Link|BreakAllLinks|(?:Give|Remove)Inventory|Water|PassTouches|Request(?:Agent|Inventory)Data|TeleportAgent(?:Home|GlobalCoords)?|ModifyLand|CollisionSound|ResetScript|MessageLinked|PushObject|PassCollisions|AxisAngle2Rot|Rot2(?:Axis|Angle)|A(?:cos|sin)|AngleBetween|AllowInventoryDrop|SubStringIndex|List2(?:CSV|Integer|Json|Float|String|Key|Vector|Rot|List(?:Strided)?)|DeleteSubList|List(?:Statistics|Sort|Randomize|(?:Insert|Find|Replace)List)|EdgeOfWorld|AdjustSoundVolume|Key2Name|TriggerSoundLimited|EjectFromLand|(?:CSV|ParseString)2List|OverMyLand|SameGroup|UnSit|Ground(?:Slope|Normal|Contour)|GroundRepel|(?:Set|Remove)VehicleFlags|(?:AvatarOn)?(?:Link)?SitTarget|Script(?:Danger|Profiler)|Dialog|VolumeDetect|ResetOtherScript|RemoteLoadScriptPin|(?:Open|Close)RemoteDataChannel|SendRemoteData|RemoteDataReply|(?:Integer|String)ToBase64|XorBase64|Log(?:10)?|Base64To(?:String|Integer)|ParseStringKeepNulls|RezAtRoot|RequestSimulatorData|ForceMouselook|(?:Load|Release|(?:E|Une)scape)URL|ParcelMedia(?:CommandList|Query)|ModPow|MapDestination|(?:RemoveFrom|AddTo|Reset)Land(?:Pass|Ban)List|(?:Set|Clear)CameraParams|HTTP(?:Request|Response)|TextBox|DetectedTouch(?:UV|Face|Pos|(?:N|Bin)ormal|ST)|(?:MD5|SHA1|DumpList2)String|Request(?:Secure)?URL|Clear(?:Prim|Link)Media|(?:Link)?ParticleSystem|(?:Get|Request)(?:Username|DisplayName)|RegionSayTo|CastRay|GenerateKey|TransferLindenDollars|ManageEstateAccess|(?:Create|Delete)Character|ExecCharacterCmd|Evade|FleeFrom|NavigateTo|PatrolPoints|Pursue|UpdateCharacter|WanderWithin))\b'
+    lsl_constants_float = r'\b(?:DEG_TO_RAD|PI(?:_BY_TWO)?|RAD_TO_DEG|SQRT2|TWO_PI)\b'
+    lsl_constants_integer = r'\b(?:JSON_APPEND|STATUS_(?:PHYSICS|ROTATE_[XYZ]|PHANTOM|SANDBOX|BLOCK_GRAB(?:_OBJECT)?|(?:DIE|RETURN)_AT_EDGE|CAST_SHADOWS|OK|MALFORMED_PARAMS|TYPE_MISMATCH|BOUNDS_ERROR|NOT_(?:FOUND|SUPPORTED)|INTERNAL_ERROR|WHITELIST_FAILED)|AGENT(?:_(?:BY_(?:LEGACY_|USER)NAME|FLYING|ATTACHMENTS|SCRIPTED|MOUSELOOK|SITTING|ON_OBJECT|AWAY|WALKING|IN_AIR|TYPING|CROUCHING|BUSY|ALWAYS_RUN|AUTOPILOT|LIST_(?:PARCEL(?:_OWNER)?|REGION)))?|CAMERA_(?:PITCH|DISTANCE|BEHINDNESS_(?:ANGLE|LAG)|(?:FOCUS|POSITION)(?:_(?:THRESHOLD|LOCKED|LAG))?|FOCUS_OFFSET|ACTIVE)|ANIM_ON|LOOP|REVERSE|PING_PONG|SMOOTH|ROTATE|SCALE|ALL_SIDES|LINK_(?:ROOT|SET|ALL_(?:OTHERS|CHILDREN)|THIS)|ACTIVE|PASSIVE|SCRIPTED|CONTROL_(?:FWD|BACK|(?:ROT_)?(?:LEFT|RIGHT)|UP|DOWN|(?:ML_)?LBUTTON)|PERMISSION_(?:RETURN_OBJECTS|DEBIT|OVERRIDE_ANIMATIONS|SILENT_ESTATE_MANAGEMENT|TAKE_CONTROLS|TRIGGER_ANIMATION|ATTACH|CHANGE_LINKS|(?:CONTROL|TRACK)_CAMERA|TELEPORT)|INVENTORY_(?:TEXTURE|SOUND|OBJECT|SCRIPT|LANDMARK|CLOTHING|NOTECARD|BODYPART|ANIMATION|GESTURE|ALL|NONE)|CHANGED_(?:INVENTORY|COLOR|SHAPE|SCALE|TEXTURE|LINK|ALLOWED_DROP|OWNER|REGION(?:_START)?|TELEPORT|MEDIA)|OBJECT_(?:(?:PHYSICS|SERVER|STREAMING)_COST|UNKNOWN_DETAIL|CHARACTER_TIME|PHANTOM|PHYSICS|TEMP_ON_REZ|NAME|DESC|POS|PRIM_EQUIVALENCE|RETURN_(?:PARCEL(?:_OWNER)?|REGION)|ROO?T|VELOCITY|OWNER|GROUP|CREATOR|ATTACHED_POINT|RENDER_WEIGHT|PATHFINDING_TYPE|(?:RUNNING|TOTAL)_SCRIPT_COUNT|SCRIPT_(?:MEMORY|TIME))|TYPE_(?:INTEGER|FLOAT|STRING|KEY|VECTOR|ROTATION|INVALID)|(?:DEBUG|PUBLIC)_CHANNEL|ATTACH_(?:AVATAR_CENTER|CHEST|HEAD|BACK|PELVIS|MOUTH|CHIN|NECK|NOSE|BELLY|[LR](?:SHOULDER|HAND|FOOT|EAR|EYE|[UL](?:ARM|LEG)|HIP)|(?:LEFT|RIGHT)_PEC|HUD_(?:CENTER_[12]|TOP_(?:RIGHT|CENTER|LEFT)|BOTTOM(?:_(?:RIGHT|LEFT))?))|LAND_(?:LEVEL|RAISE|LOWER|SMOOTH|NOISE|REVERT)|DATA_(?:ONLINE|NAME|BORN|SIM_(?:POS|STATUS|RATING)|PAYINFO)|PAYMENT_INFO_(?:ON_FILE|USED)|REMOTE_DATA_(?:CHANNEL|REQUEST|REPLY)|PSYS_(?:PART_(?:BF_(?:ZERO|ONE(?:_MINUS_(?:DEST_COLOR|SOURCE_(ALPHA|COLOR)))?|DEST_COLOR|SOURCE_(ALPHA|COLOR))|BLEND_FUNC_(DEST|SOURCE)|FLAGS|(?:START|END)_(?:COLOR|ALPHA|SCALE|GLOW)|MAX_AGE|(?:RIBBON|WIND|INTERP_(?:COLOR|SCALE)|BOUNCE|FOLLOW_(?:SRC|VELOCITY)|TARGET_(?:POS|LINEAR)|EMISSIVE)_MASK)|SRC_(?:MAX_AGE|PATTERN|ANGLE_(?:BEGIN|END)|BURST_(?:RATE|PART_COUNT|RADIUS|SPEED_(?:MIN|MAX))|ACCEL|TEXTURE|TARGET_KEY|OMEGA|PATTERN_(?:DROP|EXPLODE|ANGLE(?:_CONE(?:_EMPTY)?)?)))|VEHICLE_(?:REFERENCE_FRAME|TYPE_(?:NONE|SLED|CAR|BOAT|AIRPLANE|BALLOON)|(?:LINEAR|ANGULAR)_(?:FRICTION_TIMESCALE|MOTOR_DIRECTION)|LINEAR_MOTOR_OFFSET|HOVER_(?:HEIGHT|EFFICIENCY|TIMESCALE)|BUOYANCY|(?:LINEAR|ANGULAR)_(?:DEFLECTION_(?:EFFICIENCY|TIMESCALE)|MOTOR_(?:DECAY_)?TIMESCALE)|VERTICAL_ATTRACTION_(?:EFFICIENCY|TIMESCALE)|BANKING_(?:EFFICIENCY|MIX|TIMESCALE)|FLAG_(?:NO_DEFLECTION_UP|LIMIT_(?:ROLL_ONLY|MOTOR_UP)|HOVER_(?:(?:WATER|TERRAIN|UP)_ONLY|GLOBAL_HEIGHT)|MOUSELOOK_(?:STEER|BANK)|CAMERA_DECOUPLED))|PRIM_(?:TYPE(?:_(?:BOX|CYLINDER|PRISM|SPHERE|TORUS|TUBE|RING|SCULPT))?|HOLE_(?:DEFAULT|CIRCLE|SQUARE|TRIANGLE)|MATERIAL(?:_(?:STONE|METAL|GLASS|WOOD|FLESH|PLASTIC|RUBBER))?|SHINY_(?:NONE|LOW|MEDIUM|HIGH)|BUMP_(?:NONE|BRIGHT|DARK|WOOD|BARK|BRICKS|CHECKER|CONCRETE|TILE|STONE|DISKS|GRAVEL|BLOBS|SIDING|LARGETILE|STUCCO|SUCTION|WEAVE)|TEXGEN_(?:DEFAULT|PLANAR)|SCULPT_(?:TYPE_(?:SPHERE|TORUS|PLANE|CYLINDER|MASK)|FLAG_(?:MIRROR|INVERT))|PHYSICS(?:_(?:SHAPE_(?:CONVEX|NONE|PRIM|TYPE)))?|(?:POS|ROT)_LOCAL|SLICE|TEXT|FLEXIBLE|POINT_LIGHT|TEMP_ON_REZ|PHANTOM|POSITION|SIZE|ROTATION|TEXTURE|NAME|OMEGA|DESC|LINK_TARGET|COLOR|BUMP_SHINY|FULLBRIGHT|TEXGEN|GLOW|MEDIA_(?:ALT_IMAGE_ENABLE|CONTROLS|(?:CURRENT|HOME)_URL|AUTO_(?:LOOP|PLAY|SCALE|ZOOM)|FIRST_CLICK_INTERACT|(?:WIDTH|HEIGHT)_PIXELS|WHITELIST(?:_ENABLE)?|PERMS_(?:INTERACT|CONTROL)|PARAM_MAX|CONTROLS_(?:STANDARD|MINI)|PERM_(?:NONE|OWNER|GROUP|ANYONE)|MAX_(?:URL_LENGTH|WHITELIST_(?:SIZE|COUNT)|(?:WIDTH|HEIGHT)_PIXELS)))|MASK_(?:BASE|OWNER|GROUP|EVERYONE|NEXT)|PERM_(?:TRANSFER|MODIFY|COPY|MOVE|ALL)|PARCEL_(?:MEDIA_COMMAND_(?:STOP|PAUSE|PLAY|LOOP|TEXTURE|URL|TIME|AGENT|UNLOAD|AUTO_ALIGN|TYPE|SIZE|DESC|LOOP_SET)|FLAG_(?:ALLOW_(?:FLY|(?:GROUP_)?SCRIPTS|LANDMARK|TERRAFORM|DAMAGE|CREATE_(?:GROUP_)?OBJECTS)|USE_(?:ACCESS_(?:GROUP|LIST)|BAN_LIST|LAND_PASS_LIST)|LOCAL_SOUND_ONLY|RESTRICT_PUSHOBJECT|ALLOW_(?:GROUP|ALL)_OBJECT_ENTRY)|COUNT_(?:TOTAL|OWNER|GROUP|OTHER|SELECTED|TEMP)|DETAILS_(?:NAME|DESC|OWNER|GROUP|AREA|ID|SEE_AVATARS))|LIST_STAT_(?:MAX|MIN|MEAN|MEDIAN|STD_DEV|SUM(?:_SQUARES)?|NUM_COUNT|GEOMETRIC_MEAN|RANGE)|PAY_(?:HIDE|DEFAULT)|REGION_FLAG_(?:ALLOW_DAMAGE|FIXED_SUN|BLOCK_TERRAFORM|SANDBOX|DISABLE_(?:COLLISIONS|PHYSICS)|BLOCK_FLY|ALLOW_DIRECT_TELEPORT|RESTRICT_PUSHOBJECT)|HTTP_(?:METHOD|MIMETYPE|BODY_(?:MAXLENGTH|TRUNCATED)|CUSTOM_HEADER|PRAGMA_NO_CACHE|VERBOSE_THROTTLE|VERIFY_CERT)|STRING_(?:TRIM(?:_(?:HEAD|TAIL))?)|CLICK_ACTION_(?:NONE|TOUCH|SIT|BUY|PAY|OPEN(?:_MEDIA)?|PLAY|ZOOM)|TOUCH_INVALID_FACE|PROFILE_(?:NONE|SCRIPT_MEMORY)|RC_(?:DATA_FLAGS|DETECT_PHANTOM|GET_(?:LINK_NUM|NORMAL|ROOT_KEY)|MAX_HITS|REJECT_(?:TYPES|AGENTS|(?:NON)?PHYSICAL|LAND))|RCERR_(?:CAST_TIME_EXCEEDED|SIM_PERF_LOW|UNKNOWN)|ESTATE_ACCESS_(?:ALLOWED_(?:AGENT|GROUP)_(?:ADD|REMOVE)|BANNED_AGENT_(?:ADD|REMOVE))|DENSITY|FRICTION|RESTITUTION|GRAVITY_MULTIPLIER|KFM_(?:COMMAND|CMD_(?:PLAY|STOP|PAUSE|SET_MODE)|MODE|FORWARD|LOOP|PING_PONG|REVERSE|DATA|ROTATION|TRANSLATION)|ERR_(?:GENERIC|PARCEL_PERMISSIONS|MALFORMED_PARAMS|RUNTIME_PERMISSIONS|THROTTLED)|CHARACTER_(?:CMD_(?:(?:SMOOTH_)?STOP|JUMP)|DESIRED_(?:TURN_)?SPEED|RADIUS|STAY_WITHIN_PARCEL|LENGTH|ORIENTATION|ACCOUNT_FOR_SKIPPED_FRAMES|AVOIDANCE_MODE|TYPE(?:_(?:[A-D]|NONE))?|MAX_(?:DECEL|TURN_RADIUS|(?:ACCEL|SPEED)))|PURSUIT_(?:OFFSET|FUZZ_FACTOR|GOAL_TOLERANCE|INTERCEPT)|REQUIRE_LINE_OF_SIGHT|FORCE_DIRECT_PATH|VERTICAL|HORIZONTAL|AVOID_(?:CHARACTERS|DYNAMIC_OBSTACLES|NONE)|PU_(?:EVADE_(?:HIDDEN|SPOTTED)|FAILURE_(?:DYNAMIC_PATHFINDING_DISABLED|INVALID_(?:GOAL|START)|NO_(?:NAVMESH|VALID_DESTINATION)|OTHER|TARGET_GONE|(?:PARCEL_)?UNREACHABLE)|(?:GOAL|SLOWDOWN_DISTANCE)_REACHED)|TRAVERSAL_TYPE(?:_(?:FAST|NONE|SLOW))?|CONTENT_TYPE_(?:ATOM|FORM|HTML|JSON|LLSD|RSS|TEXT|XHTML|XML)|GCNP_(?:RADIUS|STATIC)|(?:PATROL|WANDER)_PAUSE_AT_WAYPOINTS|OPT_(?:AVATAR|CHARACTER|EXCLUSION_VOLUME|LEGACY_LINKSET|MATERIAL_VOLUME|OTHER|STATIC_OBSTACLE|WALKABLE)|SIM_STAT_PCT_CHARS_STEPPED)\b'
+    lsl_constants_integer_boolean = r'\b(?:FALSE|TRUE)\b'
+    lsl_constants_rotation = r'\b(?:ZERO_ROTATION)\b'
+    lsl_constants_string = r'\b(?:EOF|JSON_(?:ARRAY|DELETE|FALSE|INVALID|NULL|NUMBER|OBJECT|STRING|TRUE)|NULL_KEY|TEXTURE_(?:BLANK|DEFAULT|MEDIA|PLYWOOD|TRANSPARENT)|URL_REQUEST_(?:GRANTED|DENIED))\b'
+    lsl_constants_vector = r'\b(?:TOUCH_INVALID_(?:TEXCOORD|VECTOR)|ZERO_VECTOR)\b'
+    lsl_invalid_broken = r'\b(?:LAND_(?:LARGE|MEDIUM|SMALL)_BRUSH)\b'
+    lsl_invalid_deprecated = r'\b(?:ATTACH_[LR]PEC|DATA_RATING|OBJECT_ATTACHMENT_(?:GEOMETRY_BYTES|SURFACE_AREA)|PRIM_(?:CAST_SHADOWS|MATERIAL_LIGHT|TYPE_LEGACY)|PSYS_SRC_(?:INNER|OUTER)ANGLE|VEHICLE_FLAG_NO_FLY_UP|ll(?:Cloud|Make(?:Explosion|Fountain|Smoke|Fire)|RemoteDataSetRegion|Sound(?:Preload)?|XorBase64Strings(?:Correct)?))\b'
+    lsl_invalid_illegal = r'\b(?:event)\b'
+    lsl_invalid_unimplemented = r'\b(?:CHARACTER_(?:MAX_ANGULAR_(?:ACCEL|SPEED)|TURN_SPEED_MULTIPLIER)|PERMISSION_(?:CHANGE_(?:JOINTS|PERMISSIONS)|RELEASE_OWNERSHIP|REMAP_CONTROLS)|PRIM_PHYSICS_MATERIAL|PSYS_SRC_OBJ_REL_MASK|ll(?:CollisionSprite|(?:Stop)?PointAt|(?:(?:Refresh|Set)Prim)URL|(?:Take|Release)Camera|RemoteLoadScript))\b'
+    lsl_reserved_godmode = r'\b(?:ll(?:GodLikeRezObject|Set(?:Inventory|Object)PermMask))\b'
+    lsl_reserved_log = r'\b(?:print)\b'
+    lsl_operators = r'\+\+|\-\-|<<|>>|&&?|\|\|?|\^|~|[!%<>=*+\-/]=?'
+
+    tokens = {
+        'root':
+        [
+            (r'//.*?\n',                          Comment.Single),
+            (r'/\*',                              Comment.Multiline, 'comment'),
+            (r'"',                                String.Double, 'string'),
+            (lsl_keywords,                        Keyword),
+            (lsl_types,                           Keyword.Type),
+            (lsl_states,                          Name.Class),
+            (lsl_events,                          Name.Builtin),
+            (lsl_functions_builtin,               Name.Function),
+            (lsl_constants_float,                 Keyword.Constant),
+            (lsl_constants_integer,               Keyword.Constant),
+            (lsl_constants_integer_boolean,       Keyword.Constant),
+            (lsl_constants_rotation,              Keyword.Constant),
+            (lsl_constants_string,                Keyword.Constant),
+            (lsl_constants_vector,                Keyword.Constant),
+            (lsl_invalid_broken,                  Error),
+            (lsl_invalid_deprecated,              Error),
+            (lsl_invalid_illegal,                 Error),
+            (lsl_invalid_unimplemented,           Error),
+            (lsl_reserved_godmode,                Keyword.Reserved),
+            (lsl_reserved_log,                    Keyword.Reserved),
+            (r'\b([a-zA-Z_]\w*)\b',     Name.Variable),
+            (r'(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d*', Number.Float),
+            (r'(\d+\.\d*|\.\d+)',                 Number.Float),
+            (r'0[xX][0-9a-fA-F]+',                Number.Hex),
+            (r'\d+',                              Number.Integer),
+            (lsl_operators,                       Operator),
+            (r':=?',                              Error),
+            (r'[,;{}()\[\]]',                     Punctuation),
+            (r'\n+',                              Whitespace),
+            (r'\s+',                              Whitespace)
+        ],
+        'comment':
+        [
+            (r'[^*/]+',                           Comment.Multiline),
+            (r'/\*',                              Comment.Multiline, '#push'),
+            (r'\*/',                              Comment.Multiline, '#pop'),
+            (r'[*/]',                             Comment.Multiline)
+        ],
+        'string':
+        [
+            (r'\\([nt"\\])',                      String.Escape),
+            (r'"',                                String.Double, '#pop'),
+            (r'\\.',                              Error),
+            (r'[^"\\]+',                          String.Double),
+        ]
+    }
+
+
+class AppleScriptLexer(RegexLexer):
+    """
+    For AppleScript source code,
+    including `AppleScript Studio
+    `_.
+    Contributed by Andreas Amann .
+    """
+
+    name = 'AppleScript'
+    url = 'https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html'
+    aliases = ['applescript']
+    filenames = ['*.applescript']
+    version_added = '1.0'
+
+    flags = re.MULTILINE | re.DOTALL
+
+    Identifiers = r'[a-zA-Z]\w*'
+
+    # XXX: use words() for all of these
+    Literals = ('AppleScript', 'current application', 'false', 'linefeed',
+                'missing value', 'pi', 'quote', 'result', 'return', 'space',
+                'tab', 'text item delimiters', 'true', 'version')
+    Classes = ('alias ', 'application ', 'boolean ', 'class ', 'constant ',
+               'date ', 'file ', 'integer ', 'list ', 'number ', 'POSIX file ',
+               'real ', 'record ', 'reference ', 'RGB color ', 'script ',
+               'text ', 'unit types', '(?:Unicode )?text', 'string')
+    BuiltIn = ('attachment', 'attribute run', 'character', 'day', 'month',
+               'paragraph', 'word', 'year')
+    HandlerParams = ('about', 'above', 'against', 'apart from', 'around',
+                     'aside from', 'at', 'below', 'beneath', 'beside',
+                     'between', 'for', 'given', 'instead of', 'on', 'onto',
+                     'out of', 'over', 'since')
+    Commands = ('ASCII (character|number)', 'activate', 'beep', 'choose URL',
+                'choose application', 'choose color', 'choose file( name)?',
+                'choose folder', 'choose from list',
+                'choose remote application', 'clipboard info',
+                'close( access)?', 'copy', 'count', 'current date', 'delay',
+                'delete', 'display (alert|dialog)', 'do shell script',
+                'duplicate', 'exists', 'get eof', 'get volume settings',
+                'info for', 'launch', 'list (disks|folder)', 'load script',
+                'log', 'make', 'mount volume', 'new', 'offset',
+                'open( (for access|location))?', 'path to', 'print', 'quit',
+                'random number', 'read', 'round', 'run( script)?',
+                'say', 'scripting components',
+                'set (eof|the clipboard to|volume)', 'store script',
+                'summarize', 'system attribute', 'system info',
+                'the clipboard', 'time to GMT', 'write', 'quoted form')
+    References = ('(in )?back of', '(in )?front of', '[0-9]+(st|nd|rd|th)',
+                  'first', 'second', 'third', 'fourth', 'fifth', 'sixth',
+                  'seventh', 'eighth', 'ninth', 'tenth', 'after', 'back',
+                  'before', 'behind', 'every', 'front', 'index', 'last',
+                  'middle', 'some', 'that', 'through', 'thru', 'where', 'whose')
+    Operators = ("and", "or", "is equal", "equals", "(is )?equal to", "is not",
+                 "isn't", "isn't equal( to)?", "is not equal( to)?",
+                 "doesn't equal", "does not equal", "(is )?greater than",
+                 "comes after", "is not less than or equal( to)?",
+                 "isn't less than or equal( to)?", "(is )?less than",
+                 "comes before", "is not greater than or equal( to)?",
+                 "isn't greater than or equal( to)?",
+                 "(is  )?greater than or equal( to)?", "is not less than",
+                 "isn't less than", "does not come before",
+                 "doesn't come before", "(is )?less than or equal( to)?",
+                 "is not greater than", "isn't greater than",
+                 "does not come after", "doesn't come after", "starts? with",
+                 "begins? with", "ends? with", "contains?", "does not contain",
+                 "doesn't contain", "is in", "is contained by", "is not in",
+                 "is not contained by", "isn't contained by", "div", "mod",
+                 "not", "(a  )?(ref( to)?|reference to)", "is", "does")
+    Control = ('considering', 'else', 'error', 'exit', 'from', 'if',
+               'ignoring', 'in', 'repeat', 'tell', 'then', 'times', 'to',
+               'try', 'until', 'using terms from', 'while', 'whith',
+               'with timeout( of)?', 'with transaction', 'by', 'continue',
+               'end', 'its?', 'me', 'my', 'return', 'of', 'as')
+    Declarations = ('global', 'local', 'prop(erty)?', 'set', 'get')
+    Reserved = ('but', 'put', 'returning', 'the')
+    StudioClasses = ('action cell', 'alert reply', 'application', 'box',
+                     'browser( cell)?', 'bundle', 'button( cell)?', 'cell',
+                     'clip view', 'color well', 'color-panel',
+                     'combo box( item)?', 'control',
+                     'data( (cell|column|item|row|source))?', 'default entry',
+                     'dialog reply', 'document', 'drag info', 'drawer',
+                     'event', 'font(-panel)?', 'formatter',
+                     'image( (cell|view))?', 'matrix', 'menu( item)?', 'item',
+                     'movie( view)?', 'open-panel', 'outline view', 'panel',
+                     'pasteboard', 'plugin', 'popup button',
+                     'progress indicator', 'responder', 'save-panel',
+                     'scroll view', 'secure text field( cell)?', 'slider',
+                     'sound', 'split view', 'stepper', 'tab view( item)?',
+                     'table( (column|header cell|header view|view))',
+                     'text( (field( cell)?|view))?', 'toolbar( item)?',
+                     'user-defaults', 'view', 'window')
+    StudioEvents = ('accept outline drop', 'accept table drop', 'action',
+                    'activated', 'alert ended', 'awake from nib', 'became key',
+                    'became main', 'begin editing', 'bounds changed',
+                    'cell value', 'cell value changed', 'change cell value',
+                    'change item value', 'changed', 'child of item',
+                    'choose menu item', 'clicked', 'clicked toolbar item',
+                    'closed', 'column clicked', 'column moved',
+                    'column resized', 'conclude drop', 'data representation',
+                    'deminiaturized', 'dialog ended', 'document nib name',
+                    'double clicked', 'drag( (entered|exited|updated))?',
+                    'drop', 'end editing', 'exposed', 'idle', 'item expandable',
+                    'item value', 'item value changed', 'items changed',
+                    'keyboard down', 'keyboard up', 'launched',
+                    'load data representation', 'miniaturized', 'mouse down',
+                    'mouse dragged', 'mouse entered', 'mouse exited',
+                    'mouse moved', 'mouse up', 'moved',
+                    'number of browser rows', 'number of items',
+                    'number of rows', 'open untitled', 'opened', 'panel ended',
+                    'parameters updated', 'plugin loaded', 'prepare drop',
+                    'prepare outline drag', 'prepare outline drop',
+                    'prepare table drag', 'prepare table drop',
+                    'read from file', 'resigned active', 'resigned key',
+                    'resigned main', 'resized( sub views)?',
+                    'right mouse down', 'right mouse dragged',
+                    'right mouse up', 'rows changed', 'scroll wheel',
+                    'selected tab view item', 'selection changed',
+                    'selection changing', 'should begin editing',
+                    'should close', 'should collapse item',
+                    'should end editing', 'should expand item',
+                    'should open( untitled)?',
+                    'should quit( after last window closed)?',
+                    'should select column', 'should select item',
+                    'should select row', 'should select tab view item',
+                    'should selection change', 'should zoom', 'shown',
+                    'update menu item', 'update parameters',
+                    'update toolbar item', 'was hidden', 'was miniaturized',
+                    'will become active', 'will close', 'will dismiss',
+                    'will display browser cell', 'will display cell',
+                    'will display item cell', 'will display outline cell',
+                    'will finish launching', 'will hide', 'will miniaturize',
+                    'will move', 'will open', 'will pop up', 'will quit',
+                    'will resign active', 'will resize( sub views)?',
+                    'will select tab view item', 'will show', 'will zoom',
+                    'write to file', 'zoomed')
+    StudioCommands = ('animate', 'append', 'call method', 'center',
+                      'close drawer', 'close panel', 'display',
+                      'display alert', 'display dialog', 'display panel', 'go',
+                      'hide', 'highlight', 'increment', 'item for',
+                      'load image', 'load movie', 'load nib', 'load panel',
+                      'load sound', 'localized string', 'lock focus', 'log',
+                      'open drawer', 'path for', 'pause', 'perform action',
+                      'play', 'register', 'resume', 'scroll', 'select( all)?',
+                      'show', 'size to fit', 'start', 'step back',
+                      'step forward', 'stop', 'synchronize', 'unlock focus',
+                      'update')
+    StudioProperties = ('accepts arrow key', 'action method', 'active',
+                        'alignment', 'allowed identifiers',
+                        'allows branch selection', 'allows column reordering',
+                        'allows column resizing', 'allows column selection',
+                        'allows customization',
+                        'allows editing text attributes',
+                        'allows empty selection', 'allows mixed state',
+                        'allows multiple selection', 'allows reordering',
+                        'allows undo', 'alpha( value)?', 'alternate image',
+                        'alternate increment value', 'alternate title',
+                        'animation delay', 'associated file name',
+                        'associated object', 'auto completes', 'auto display',
+                        'auto enables items', 'auto repeat',
+                        'auto resizes( outline column)?',
+                        'auto save expanded items', 'auto save name',
+                        'auto save table columns', 'auto saves configuration',
+                        'auto scroll', 'auto sizes all columns to fit',
+                        'auto sizes cells', 'background color', 'bezel state',
+                        'bezel style', 'bezeled', 'border rect', 'border type',
+                        'bordered', 'bounds( rotation)?', 'box type',
+                        'button returned', 'button type',
+                        'can choose directories', 'can choose files',
+                        'can draw', 'can hide',
+                        'cell( (background color|size|type))?', 'characters',
+                        'class', 'click count', 'clicked( data)? column',
+                        'clicked data item', 'clicked( data)? row',
+                        'closeable', 'collating', 'color( (mode|panel))',
+                        'command key down', 'configuration',
+                        'content(s| (size|view( margins)?))?', 'context',
+                        'continuous', 'control key down', 'control size',
+                        'control tint', 'control view',
+                        'controller visible', 'coordinate system',
+                        'copies( on scroll)?', 'corner view', 'current cell',
+                        'current column', 'current( field)?  editor',
+                        'current( menu)? item', 'current row',
+                        'current tab view item', 'data source',
+                        'default identifiers', 'delta (x|y|z)',
+                        'destination window', 'directory', 'display mode',
+                        'displayed cell', 'document( (edited|rect|view))?',
+                        'double value', 'dragged column', 'dragged distance',
+                        'dragged items', 'draws( cell)? background',
+                        'draws grid', 'dynamically scrolls', 'echos bullets',
+                        'edge', 'editable', 'edited( data)? column',
+                        'edited data item', 'edited( data)? row', 'enabled',
+                        'enclosing scroll view', 'ending page',
+                        'error handling', 'event number', 'event type',
+                        'excluded from windows menu', 'executable path',
+                        'expanded', 'fax number', 'field editor', 'file kind',
+                        'file name', 'file type', 'first responder',
+                        'first visible column', 'flipped', 'floating',
+                        'font( panel)?', 'formatter', 'frameworks path',
+                        'frontmost', 'gave up', 'grid color', 'has data items',
+                        'has horizontal ruler', 'has horizontal scroller',
+                        'has parent data item', 'has resize indicator',
+                        'has shadow', 'has sub menu', 'has vertical ruler',
+                        'has vertical scroller', 'header cell', 'header view',
+                        'hidden', 'hides when deactivated', 'highlights by',
+                        'horizontal line scroll', 'horizontal page scroll',
+                        'horizontal ruler view', 'horizontally resizable',
+                        'icon image', 'id', 'identifier',
+                        'ignores multiple clicks',
+                        'image( (alignment|dims when disabled|frame style|scaling))?',
+                        'imports graphics', 'increment value',
+                        'indentation per level', 'indeterminate', 'index',
+                        'integer value', 'intercell spacing', 'item height',
+                        'key( (code|equivalent( modifier)?|window))?',
+                        'knob thickness', 'label', 'last( visible)? column',
+                        'leading offset', 'leaf', 'level', 'line scroll',
+                        'loaded', 'localized sort', 'location', 'loop mode',
+                        'main( (bunde|menu|window))?', 'marker follows cell',
+                        'matrix mode', 'maximum( content)? size',
+                        'maximum visible columns',
+                        'menu( form representation)?', 'miniaturizable',
+                        'miniaturized', 'minimized image', 'minimized title',
+                        'minimum column width', 'minimum( content)? size',
+                        'modal', 'modified', 'mouse down state',
+                        'movie( (controller|file|rect))?', 'muted', 'name',
+                        'needs display', 'next state', 'next text',
+                        'number of tick marks', 'only tick mark values',
+                        'opaque', 'open panel', 'option key down',
+                        'outline table column', 'page scroll', 'pages across',
+                        'pages down', 'palette label', 'pane splitter',
+                        'parent data item', 'parent window', 'pasteboard',
+                        'path( (names|separator))?', 'playing',
+                        'plays every frame', 'plays selection only', 'position',
+                        'preferred edge', 'preferred type', 'pressure',
+                        'previous text', 'prompt', 'properties',
+                        'prototype cell', 'pulls down', 'rate',
+                        'released when closed', 'repeated',
+                        'requested print time', 'required file type',
+                        'resizable', 'resized column', 'resource path',
+                        'returns records', 'reuses columns', 'rich text',
+                        'roll over', 'row height', 'rulers visible',
+                        'save panel', 'scripts path', 'scrollable',
+                        'selectable( identifiers)?', 'selected cell',
+                        'selected( data)? columns?', 'selected data items?',
+                        'selected( data)? rows?', 'selected item identifier',
+                        'selection by rect', 'send action on arrow key',
+                        'sends action when done editing', 'separates columns',
+                        'separator item', 'sequence number', 'services menu',
+                        'shared frameworks path', 'shared support path',
+                        'sheet', 'shift key down', 'shows alpha',
+                        'shows state by', 'size( mode)?',
+                        'smart insert delete enabled', 'sort case sensitivity',
+                        'sort column', 'sort order', 'sort type',
+                        'sorted( data rows)?', 'sound', 'source( mask)?',
+                        'spell checking enabled', 'starting page', 'state',
+                        'string value', 'sub menu', 'super menu', 'super view',
+                        'tab key traverses cells', 'tab state', 'tab type',
+                        'tab view', 'table view', 'tag', 'target( printer)?',
+                        'text color', 'text container insert',
+                        'text container origin', 'text returned',
+                        'tick mark position', 'time stamp',
+                        'title(d| (cell|font|height|position|rect))?',
+                        'tool tip', 'toolbar', 'trailing offset', 'transparent',
+                        'treat packages as directories', 'truncated labels',
+                        'types', 'unmodified characters', 'update views',
+                        'use sort indicator', 'user defaults',
+                        'uses data source', 'uses ruler',
+                        'uses threaded animation',
+                        'uses title from previous column', 'value wraps',
+                        'version',
+                        'vertical( (line scroll|page scroll|ruler view))?',
+                        'vertically resizable', 'view',
+                        'visible( document rect)?', 'volume', 'width', 'window',
+                        'windows menu', 'wraps', 'zoomable', 'zoomed')
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+            (r'¬\n', String.Escape),
+            (r"'s\s+", Text),  # This is a possessive, consider moving
+            (r'(--|#).*?$', Comment),
+            (r'\(\*', Comment.Multiline, 'comment'),
+            (r'[(){}!,.:]', Punctuation),
+            (r'(«)([^»]+)(»)',
+             bygroups(Text, Name.Builtin, Text)),
+            (r'\b((?:considering|ignoring)\s*)'
+             r'(application responses|case|diacriticals|hyphens|'
+             r'numeric strings|punctuation|white space)',
+             bygroups(Keyword, Name.Builtin)),
+            (r'(-|\*|\+|&|≠|>=?|<=?|=|≥|≤|/|÷|\^)', Operator),
+            (r"\b({})\b".format('|'.join(Operators)), Operator.Word),
+            (r'^(\s*(?:on|end)\s+)'
+             r'({})'.format('|'.join(StudioEvents[::-1])),
+             bygroups(Keyword, Name.Function)),
+            (r'^(\s*)(in|on|script|to)(\s+)', bygroups(Text, Keyword, Text)),
+            (r'\b(as )({})\b'.format('|'.join(Classes)),
+             bygroups(Keyword, Name.Class)),
+            (r'\b({})\b'.format('|'.join(Literals)), Name.Constant),
+            (r'\b({})\b'.format('|'.join(Commands)), Name.Builtin),
+            (r'\b({})\b'.format('|'.join(Control)), Keyword),
+            (r'\b({})\b'.format('|'.join(Declarations)), Keyword),
+            (r'\b({})\b'.format('|'.join(Reserved)), Name.Builtin),
+            (r'\b({})s?\b'.format('|'.join(BuiltIn)), Name.Builtin),
+            (r'\b({})\b'.format('|'.join(HandlerParams)), Name.Builtin),
+            (r'\b({})\b'.format('|'.join(StudioProperties)), Name.Attribute),
+            (r'\b({})s?\b'.format('|'.join(StudioClasses)), Name.Builtin),
+            (r'\b({})\b'.format('|'.join(StudioCommands)), Name.Builtin),
+            (r'\b({})\b'.format('|'.join(References)), Name.Builtin),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String.Double),
+            (rf'\b({Identifiers})\b', Name.Variable),
+            (r'[-+]?(\d+\.\d*|\d*\.\d+)(E[-+][0-9]+)?', Number.Float),
+            (r'[-+]?\d+', Number.Integer),
+        ],
+        'comment': [
+            (r'\(\*', Comment.Multiline, '#push'),
+            (r'\*\)', Comment.Multiline, '#pop'),
+            ('[^*(]+', Comment.Multiline),
+            ('[*(]', Comment.Multiline),
+        ],
+    }
+
+
+class RexxLexer(RegexLexer):
+    """
+    Rexx is a scripting language available for
+    a wide range of different platforms with its roots found on mainframe
+    systems. It is popular for I/O- and data based tasks and can act as glue
+    language to bind different applications together.
+    """
+    name = 'Rexx'
+    url = 'http://www.rexxinfo.org/'
+    aliases = ['rexx', 'arexx']
+    filenames = ['*.rexx', '*.rex', '*.rx', '*.arexx']
+    mimetypes = ['text/x-rexx']
+    version_added = '2.0'
+    flags = re.IGNORECASE
+
+    tokens = {
+        'root': [
+            (r'\s+', Whitespace),
+            (r'/\*', Comment.Multiline, 'comment'),
+            (r'"', String, 'string_double'),
+            (r"'", String, 'string_single'),
+            (r'[0-9]+(\.[0-9]+)?(e[+-]?[0-9])?', Number),
+            (r'([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b',
+             bygroups(Name.Function, Whitespace, Operator, Whitespace,
+                      Keyword.Declaration)),
+            (r'([a-z_]\w*)(\s*)(:)',
+             bygroups(Name.Label, Whitespace, Operator)),
+            include('function'),
+            include('keyword'),
+            include('operator'),
+            (r'[a-z_]\w*', Text),
+        ],
+        'function': [
+            (words((
+                'abbrev', 'abs', 'address', 'arg', 'b2x', 'bitand', 'bitor', 'bitxor',
+                'c2d', 'c2x', 'center', 'charin', 'charout', 'chars', 'compare',
+                'condition', 'copies', 'd2c', 'd2x', 'datatype', 'date', 'delstr',
+                'delword', 'digits', 'errortext', 'form', 'format', 'fuzz', 'insert',
+                'lastpos', 'left', 'length', 'linein', 'lineout', 'lines', 'max',
+                'min', 'overlay', 'pos', 'queued', 'random', 'reverse', 'right', 'sign',
+                'sourceline', 'space', 'stream', 'strip', 'substr', 'subword', 'symbol',
+                'time', 'trace', 'translate', 'trunc', 'value', 'verify', 'word',
+                'wordindex', 'wordlength', 'wordpos', 'words', 'x2b', 'x2c', 'x2d',
+                'xrange'), suffix=r'(\s*)(\()'),
+             bygroups(Name.Builtin, Whitespace, Operator)),
+        ],
+        'keyword': [
+            (r'(address|arg|by|call|do|drop|else|end|exit|for|forever|if|'
+             r'interpret|iterate|leave|nop|numeric|off|on|options|parse|'
+             r'pull|push|queue|return|say|select|signal|to|then|trace|until|'
+             r'while)\b', Keyword.Reserved),
+        ],
+        'operator': [
+            (r'(-|//|/|\(|\)|\*\*|\*|\\<<|\\<|\\==|\\=|\\>>|\\>|\\|\|\||\||'
+             r'&&|&|%|\+|<<=|<<|<=|<>|<|==|=|><|>=|>>=|>>|>|¬<<|¬<|¬==|¬=|'
+             r'¬>>|¬>|¬|\.|,)', Operator),
+        ],
+        'string_double': [
+            (r'[^"\n]+', String),
+            (r'""', String),
+            (r'"', String, '#pop'),
+            (r'\n', Text, '#pop'),  # Stray linefeed also terminates strings.
+        ],
+        'string_single': [
+            (r'[^\'\n]+', String),
+            (r'\'\'', String),
+            (r'\'', String, '#pop'),
+            (r'\n', Text, '#pop'),  # Stray linefeed also terminates strings.
+        ],
+        'comment': [
+            (r'[^*]+', Comment.Multiline),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'\*', Comment.Multiline),
+        ]
+    }
+
+    def _c(s):
+        return re.compile(s, re.MULTILINE)
+    _ADDRESS_COMMAND_PATTERN = _c(r'^\s*address\s+command\b')
+    _ADDRESS_PATTERN = _c(r'^\s*address\s+')
+    _DO_WHILE_PATTERN = _c(r'^\s*do\s+while\b')
+    _IF_THEN_DO_PATTERN = _c(r'^\s*if\b.+\bthen\s+do\s*$')
+    _PROCEDURE_PATTERN = _c(r'^\s*([a-z_]\w*)(\s*)(:)(\s*)(procedure)\b')
+    _ELSE_DO_PATTERN = _c(r'\belse\s+do\s*$')
+    _PARSE_ARG_PATTERN = _c(r'^\s*parse\s+(upper\s+)?(arg|value)\b')
+    PATTERNS_AND_WEIGHTS = (
+        (_ADDRESS_COMMAND_PATTERN, 0.2),
+        (_ADDRESS_PATTERN, 0.05),
+        (_DO_WHILE_PATTERN, 0.1),
+        (_ELSE_DO_PATTERN, 0.1),
+        (_IF_THEN_DO_PATTERN, 0.1),
+        (_PROCEDURE_PATTERN, 0.5),
+        (_PARSE_ARG_PATTERN, 0.2),
+    )
+
+    def analyse_text(text):
+        """
+        Check for initial comment and patterns that distinguish Rexx from other
+        C-like languages.
+        """
+        if re.search(r'/\*\**\s*rexx', text, re.IGNORECASE):
+            # Header matches MVS Rexx requirements, this is certainly a Rexx
+            # script.
+            return 1.0
+        elif text.startswith('/*'):
+            # Header matches general Rexx requirements; the source code might
+            # still be any language using C comments such as C++, C# or Java.
+            lowerText = text.lower()
+            result = sum(weight
+                         for (pattern, weight) in RexxLexer.PATTERNS_AND_WEIGHTS
+                         if pattern.search(lowerText)) + 0.01
+            return min(result, 1.0)
+
+
+class MOOCodeLexer(RegexLexer):
+    """
+    For MOOCode (the MOO scripting language).
+    """
+    name = 'MOOCode'
+    url = 'http://www.moo.mud.org/'
+    filenames = ['*.moo']
+    aliases = ['moocode', 'moo']
+    mimetypes = ['text/x-moocode']
+    version_added = '0.9'
+
+    tokens = {
+        'root': [
+            # Numbers
+            (r'(0|[1-9][0-9_]*)', Number.Integer),
+            # Strings
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
+            # exceptions
+            (r'(E_PERM|E_DIV)', Name.Exception),
+            # db-refs
+            (r'((#[-0-9]+)|(\$\w+))', Name.Entity),
+            # Keywords
+            (r'\b(if|else|elseif|endif|for|endfor|fork|endfork|while'
+             r'|endwhile|break|continue|return|try'
+             r'|except|endtry|finally|in)\b', Keyword),
+            # builtins
+            (r'(random|length)', Name.Builtin),
+            # special variables
+            (r'(player|caller|this|args)', Name.Variable.Instance),
+            # skip whitespace
+            (r'\s+', Text),
+            (r'\n', Text),
+            # other operators
+            (r'([!;=,{}&|:.\[\]@()<>?]+)', Operator),
+            # function call
+            (r'(\w+)(\()', bygroups(Name.Function, Operator)),
+            # variables
+            (r'(\w+)', Text),
+        ]
+    }
+
+
+class HybrisLexer(RegexLexer):
+    """
+    For Hybris source code.
+    """
+
+    name = 'Hybris'
+    aliases = ['hybris']
+    filenames = ['*.hyb']
+    mimetypes = ['text/x-hybris', 'application/x-hybris']
+    url = 'https://github.com/evilsocket/hybris'
+    version_added = '1.4'
+
+    flags = re.MULTILINE | re.DOTALL
+
+    tokens = {
+        'root': [
+            # method names
+            (r'^(\s*(?:function|method|operator\s+)+?)'
+             r'([a-zA-Z_]\w*)'
+             r'(\s*)(\()', bygroups(Keyword, Name.Function, Text, Operator)),
+            (r'[^\S\n]+', Text),
+            (r'//.*?\n', Comment.Single),
+            (r'/\*.*?\*/', Comment.Multiline),
+            (r'@[a-zA-Z_][\w.]*', Name.Decorator),
+            (r'(break|case|catch|next|default|do|else|finally|for|foreach|of|'
+             r'unless|if|new|return|switch|me|throw|try|while)\b', Keyword),
+            (r'(extends|private|protected|public|static|throws|function|method|'
+             r'operator)\b', Keyword.Declaration),
+            (r'(true|false|null|__FILE__|__LINE__|__VERSION__|__LIB_PATH__|'
+             r'__INC_PATH__)\b', Keyword.Constant),
+            (r'(class|struct)(\s+)',
+             bygroups(Keyword.Declaration, Text), 'class'),
+            (r'(import|include)(\s+)',
+             bygroups(Keyword.Namespace, Text), 'import'),
+            (words((
+                'gc_collect', 'gc_mm_items', 'gc_mm_usage', 'gc_collect_threshold',
+                'urlencode', 'urldecode', 'base64encode', 'base64decode', 'sha1', 'crc32',
+                'sha2', 'md5', 'md5_file', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos',
+                'cosh', 'exp', 'fabs', 'floor', 'fmod', 'log', 'log10', 'pow', 'sin',
+                'sinh', 'sqrt', 'tan', 'tanh', 'isint', 'isfloat', 'ischar', 'isstring',
+                'isarray', 'ismap', 'isalias', 'typeof', 'sizeof', 'toint', 'tostring',
+                'fromxml', 'toxml', 'binary', 'pack', 'load', 'eval', 'var_names',
+                'var_values', 'user_functions', 'dyn_functions', 'methods', 'call',
+                'call_method', 'mknod', 'mkfifo', 'mount', 'umount2', 'umount', 'ticks',
+                'usleep', 'sleep', 'time', 'strtime', 'strdate', 'dllopen', 'dlllink',
+                'dllcall', 'dllcall_argv', 'dllclose', 'env', 'exec', 'fork', 'getpid',
+                'wait', 'popen', 'pclose', 'exit', 'kill', 'pthread_create',
+                'pthread_create_argv', 'pthread_exit', 'pthread_join', 'pthread_kill',
+                'smtp_send', 'http_get', 'http_post', 'http_download', 'socket', 'bind',
+                'listen', 'accept', 'getsockname', 'getpeername', 'settimeout', 'connect',
+                'server', 'recv', 'send', 'close', 'print', 'println', 'printf', 'input',
+                'readline', 'serial_open', 'serial_fcntl', 'serial_get_attr',
+                'serial_get_ispeed', 'serial_get_ospeed', 'serial_set_attr',
+                'serial_set_ispeed', 'serial_set_ospeed', 'serial_write', 'serial_read',
+                'serial_close', 'xml_load', 'xml_parse', 'fopen', 'fseek', 'ftell',
+                'fsize', 'fread', 'fwrite', 'fgets', 'fclose', 'file', 'readdir',
+                'pcre_replace', 'size', 'pop', 'unmap', 'has', 'keys', 'values',
+                'length', 'find', 'substr', 'replace', 'split', 'trim', 'remove',
+                'contains', 'join'), suffix=r'\b'),
+             Name.Builtin),
+            (words((
+                'MethodReference', 'Runner', 'Dll', 'Thread', 'Pipe', 'Process',
+                'Runnable', 'CGI', 'ClientSocket', 'Socket', 'ServerSocket',
+                'File', 'Console', 'Directory', 'Exception'), suffix=r'\b'),
+             Keyword.Type),
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
+            (r"'\\.'|'[^\\]'|'\\u[0-9a-f]{4}'", String.Char),
+            (r'(\.)([a-zA-Z_]\w*)',
+             bygroups(Operator, Name.Attribute)),
+            (r'[a-zA-Z_]\w*:', Name.Label),
+            (r'[a-zA-Z_$]\w*', Name),
+            (r'[~^*!%&\[\](){}<>|+=:;,./?\-@]+', Operator),
+            (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
+            (r'0x[0-9a-f]+', Number.Hex),
+            (r'[0-9]+L?', Number.Integer),
+            (r'\n', Text),
+        ],
+        'class': [
+            (r'[a-zA-Z_]\w*', Name.Class, '#pop')
+        ],
+        'import': [
+            (r'[\w.]+\*?', Name.Namespace, '#pop')
+        ],
+    }
+
+    def analyse_text(text):
+        """public method and private method don't seem to be quite common
+        elsewhere."""
+        result = 0
+        if re.search(r'\b(?:public|private)\s+method\b', text):
+            result += 0.01
+        return result
+
+
+
+class EasytrieveLexer(RegexLexer):
+    """
+    Easytrieve Plus is a programming language for extracting, filtering and
+    converting sequential data. Furthermore it can layout data for reports.
+    It is mainly used on mainframe platforms and can access several of the
+    mainframe's native file formats. It is somewhat comparable to awk.
+    """
+    name = 'Easytrieve'
+    aliases = ['easytrieve']
+    filenames = ['*.ezt', '*.mac']
+    mimetypes = ['text/x-easytrieve']
+    url = 'https://www.broadcom.com/products/mainframe/application-development/easytrieve-report-generator'
+    version_added = '2.1'
+    flags = 0
+
+    # Note: We cannot use r'\b' at the start and end of keywords because
+    # Easytrieve Plus delimiter characters are:
+    #
+    #   * space ( )
+    #   * apostrophe (')
+    #   * period (.)
+    #   * comma (,)
+    #   * parenthesis ( and )
+    #   * colon (:)
+    #
+    # Additionally words end once a '*' appears, indicatins a comment.
+    _DELIMITERS = r' \'.,():\n'
+    _DELIMITERS_OR_COMENT = _DELIMITERS + '*'
+    _DELIMITER_PATTERN = '[' + _DELIMITERS + ']'
+    _DELIMITER_PATTERN_CAPTURE = '(' + _DELIMITER_PATTERN + ')'
+    _NON_DELIMITER_OR_COMMENT_PATTERN = '[^' + _DELIMITERS_OR_COMENT + ']'
+    _OPERATORS_PATTERN = '[.+\\-/=\\[\\](){}<>;,&%¬]'
+    _KEYWORDS = [
+        'AFTER-BREAK', 'AFTER-LINE', 'AFTER-SCREEN', 'AIM', 'AND', 'ATTR',
+        'BEFORE', 'BEFORE-BREAK', 'BEFORE-LINE', 'BEFORE-SCREEN', 'BUSHU',
+        'BY', 'CALL', 'CASE', 'CHECKPOINT', 'CHKP', 'CHKP-STATUS', 'CLEAR',
+        'CLOSE', 'COL', 'COLOR', 'COMMIT', 'CONTROL', 'COPY', 'CURSOR', 'D',
+        'DECLARE', 'DEFAULT', 'DEFINE', 'DELETE', 'DENWA', 'DISPLAY', 'DLI',
+        'DO', 'DUPLICATE', 'E', 'ELSE', 'ELSE-IF', 'END', 'END-CASE',
+        'END-DO', 'END-IF', 'END-PROC', 'ENDPAGE', 'ENDTABLE', 'ENTER', 'EOF',
+        'EQ', 'ERROR', 'EXIT', 'EXTERNAL', 'EZLIB', 'F1', 'F10', 'F11', 'F12',
+        'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F2', 'F20', 'F21',
+        'F22', 'F23', 'F24', 'F25', 'F26', 'F27', 'F28', 'F29', 'F3', 'F30',
+        'F31', 'F32', 'F33', 'F34', 'F35', 'F36', 'F4', 'F5', 'F6', 'F7',
+        'F8', 'F9', 'FETCH', 'FILE-STATUS', 'FILL', 'FINAL', 'FIRST',
+        'FIRST-DUP', 'FOR', 'GE', 'GET', 'GO', 'GOTO', 'GQ', 'GR', 'GT',
+        'HEADING', 'HEX', 'HIGH-VALUES', 'IDD', 'IDMS', 'IF', 'IN', 'INSERT',
+        'JUSTIFY', 'KANJI-DATE', 'KANJI-DATE-LONG', 'KANJI-TIME', 'KEY',
+        'KEY-PRESSED', 'KOKUGO', 'KUN', 'LAST-DUP', 'LE', 'LEVEL', 'LIKE',
+        'LINE', 'LINE-COUNT', 'LINE-NUMBER', 'LINK', 'LIST', 'LOW-VALUES',
+        'LQ', 'LS', 'LT', 'MACRO', 'MASK', 'MATCHED', 'MEND', 'MESSAGE',
+        'MOVE', 'MSTART', 'NE', 'NEWPAGE', 'NOMASK', 'NOPRINT', 'NOT',
+        'NOTE', 'NOVERIFY', 'NQ', 'NULL', 'OF', 'OR', 'OTHERWISE', 'PA1',
+        'PA2', 'PA3', 'PAGE-COUNT', 'PAGE-NUMBER', 'PARM-REGISTER',
+        'PATH-ID', 'PATTERN', 'PERFORM', 'POINT', 'POS', 'PRIMARY', 'PRINT',
+        'PROCEDURE', 'PROGRAM', 'PUT', 'READ', 'RECORD', 'RECORD-COUNT',
+        'RECORD-LENGTH', 'REFRESH', 'RELEASE', 'RENUM', 'REPEAT', 'REPORT',
+        'REPORT-INPUT', 'RESHOW', 'RESTART', 'RETRIEVE', 'RETURN-CODE',
+        'ROLLBACK', 'ROW', 'S', 'SCREEN', 'SEARCH', 'SECONDARY', 'SELECT',
+        'SEQUENCE', 'SIZE', 'SKIP', 'SOKAKU', 'SORT', 'SQL', 'STOP', 'SUM',
+        'SYSDATE', 'SYSDATE-LONG', 'SYSIN', 'SYSIPT', 'SYSLST', 'SYSPRINT',
+        'SYSSNAP', 'SYSTIME', 'TALLY', 'TERM-COLUMNS', 'TERM-NAME',
+        'TERM-ROWS', 'TERMINATION', 'TITLE', 'TO', 'TRANSFER', 'TRC',
+        'UNIQUE', 'UNTIL', 'UPDATE', 'UPPERCASE', 'USER', 'USERID', 'VALUE',
+        'VERIFY', 'W', 'WHEN', 'WHILE', 'WORK', 'WRITE', 'X', 'XDM', 'XRST'
+    ]
+
+    tokens = {
+        'root': [
+            (r'\*.*\n', Comment.Single),
+            (r'\n+', Whitespace),
+            # Macro argument
+            (r'&' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+\.', Name.Variable,
+             'after_macro_argument'),
+            # Macro call
+            (r'%' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Variable),
+            (r'(FILE|MACRO|REPORT)(\s+)',
+             bygroups(Keyword.Declaration, Whitespace), 'after_declaration'),
+            (r'(JOB|PARM)' + r'(' + _DELIMITER_PATTERN + r')',
+             bygroups(Keyword.Declaration, Operator)),
+            (words(_KEYWORDS, suffix=_DELIMITER_PATTERN_CAPTURE),
+             bygroups(Keyword.Reserved, Operator)),
+            (_OPERATORS_PATTERN, Operator),
+            # Procedure declaration
+            (r'(' + _NON_DELIMITER_OR_COMMENT_PATTERN + r'+)(\s*)(\.?)(\s*)(PROC)(\s*\n)',
+             bygroups(Name.Function, Whitespace, Operator, Whitespace,
+                      Keyword.Declaration, Whitespace)),
+            (r'[0-9]+\.[0-9]*', Number.Float),
+            (r'[0-9]+', Number.Integer),
+            (r"'(''|[^'])*'", String),
+            (r'\s+', Whitespace),
+            # Everything else just belongs to a name
+            (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
+         ],
+        'after_declaration': [
+            (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name.Function),
+            default('#pop'),
+        ],
+        'after_macro_argument': [
+            (r'\*.*\n', Comment.Single, '#pop'),
+            (r'\s+', Whitespace, '#pop'),
+            (_OPERATORS_PATTERN, Operator, '#pop'),
+            (r"'(''|[^'])*'", String, '#pop'),
+            # Everything else just belongs to a name
+            (_NON_DELIMITER_OR_COMMENT_PATTERN + r'+', Name),
+        ],
+    }
+    _COMMENT_LINE_REGEX = re.compile(r'^\s*\*')
+    _MACRO_HEADER_REGEX = re.compile(r'^\s*MACRO')
+
+    def analyse_text(text):
+        """
+        Perform a structural analysis for basic Easytrieve constructs.
+        """
+        result = 0.0
+        lines = text.split('\n')
+        hasEndProc = False
+        hasHeaderComment = False
+        hasFile = False
+        hasJob = False
+        hasProc = False
+        hasParm = False
+        hasReport = False
+
+        def isCommentLine(line):
+            return EasytrieveLexer._COMMENT_LINE_REGEX.match(lines[0]) is not None
+
+        def isEmptyLine(line):
+            return not bool(line.strip())
+
+        # Remove possible empty lines and header comments.
+        while lines and (isEmptyLine(lines[0]) or isCommentLine(lines[0])):
+            if not isEmptyLine(lines[0]):
+                hasHeaderComment = True
+            del lines[0]
+
+        if EasytrieveLexer._MACRO_HEADER_REGEX.match(lines[0]):
+            # Looks like an Easytrieve macro.
+            result = 0.4
+            if hasHeaderComment:
+                result += 0.4
+        else:
+            # Scan the source for lines starting with indicators.
+            for line in lines:
+                words = line.split()
+                if (len(words) >= 2):
+                    firstWord = words[0]
+                    if not hasReport:
+                        if not hasJob:
+                            if not hasFile:
+                                if not hasParm:
+                                    if firstWord == 'PARM':
+                                        hasParm = True
+                                if firstWord == 'FILE':
+                                    hasFile = True
+                            if firstWord == 'JOB':
+                                hasJob = True
+                        elif firstWord == 'PROC':
+                            hasProc = True
+                        elif firstWord == 'END-PROC':
+                            hasEndProc = True
+                        elif firstWord == 'REPORT':
+                            hasReport = True
+
+            # Weight the findings.
+            if hasJob and (hasProc == hasEndProc):
+                if hasHeaderComment:
+                    result += 0.1
+                if hasParm:
+                    if hasProc:
+                        # Found PARM, JOB and PROC/END-PROC:
+                        # pretty sure this is Easytrieve.
+                        result += 0.8
+                    else:
+                        # Found PARAM and  JOB: probably this is Easytrieve
+                        result += 0.5
+                else:
+                    # Found JOB and possibly other keywords: might be Easytrieve
+                    result += 0.11
+                    if hasParm:
+                        # Note: PARAM is not a proper English word, so this is
+                        # regarded a much better indicator for Easytrieve than
+                        # the other words.
+                        result += 0.2
+                    if hasFile:
+                        result += 0.01
+                    if hasReport:
+                        result += 0.01
+        assert 0.0 <= result <= 1.0
+        return result
+
+
+class JclLexer(RegexLexer):
+    """
+    Job Control Language (JCL)
+    is a scripting language used on mainframe platforms to instruct the system
+    on how to run a batch job or start a subsystem. It is somewhat
+    comparable to MS DOS batch and Unix shell scripts.
+    """
+    name = 'JCL'
+    aliases = ['jcl']
+    filenames = ['*.jcl']
+    mimetypes = ['text/x-jcl']
+    url = 'https://en.wikipedia.org/wiki/Job_Control_Language'
+    version_added = '2.1'
+
+    flags = re.IGNORECASE
+
+    tokens = {
+        'root': [
+            (r'//\*.*\n', Comment.Single),
+            (r'//', Keyword.Pseudo, 'statement'),
+            (r'/\*', Keyword.Pseudo, 'jes2_statement'),
+            # TODO: JES3 statement
+            (r'.*\n', Other)  # Input text or inline code in any language.
+        ],
+        'statement': [
+            (r'\s*\n', Whitespace, '#pop'),
+            (r'([a-z]\w*)(\s+)(exec|job)(\s*)',
+             bygroups(Name.Label, Whitespace, Keyword.Reserved, Whitespace),
+             'option'),
+            (r'[a-z]\w*', Name.Variable, 'statement_command'),
+            (r'\s+', Whitespace, 'statement_command'),
+        ],
+        'statement_command': [
+            (r'\s+(command|cntl|dd|endctl|endif|else|include|jcllib|'
+             r'output|pend|proc|set|then|xmit)\s+', Keyword.Reserved, 'option'),
+            include('option')
+        ],
+        'jes2_statement': [
+            (r'\s*\n', Whitespace, '#pop'),
+            (r'\$', Keyword, 'option'),
+            (r'\b(jobparam|message|netacct|notify|output|priority|route|'
+             r'setup|signoff|xeq|xmit)\b', Keyword, 'option'),
+        ],
+        'option': [
+            # (r'\n', Text, 'root'),
+            (r'\*', Name.Builtin),
+            (r'[\[\](){}<>;,]', Punctuation),
+            (r'[-+*/=&%]', Operator),
+            (r'[a-z_]\w*', Name),
+            (r'\d+\.\d*', Number.Float),
+            (r'\.\d+', Number.Float),
+            (r'\d+', Number.Integer),
+            (r"'", String, 'option_string'),
+            (r'[ \t]+', Whitespace, 'option_comment'),
+            (r'\.', Punctuation),
+        ],
+        'option_string': [
+            (r"(\n)(//)", bygroups(Text, Keyword.Pseudo)),
+            (r"''", String),
+            (r"[^']", String),
+            (r"'", String, '#pop'),
+        ],
+        'option_comment': [
+            # (r'\n', Text, 'root'),
+            (r'.+', Comment.Single),
+        ]
+    }
+
+    _JOB_HEADER_PATTERN = re.compile(r'^//[a-z#$@][a-z0-9#$@]{0,7}\s+job(\s+.*)?$',
+                                     re.IGNORECASE)
+
+    def analyse_text(text):
+        """
+        Recognize JCL job by header.
+        """
+        result = 0.0
+        lines = text.split('\n')
+        if len(lines) > 0:
+            if JclLexer._JOB_HEADER_PATTERN.match(lines[0]):
+                result = 1.0
+        assert 0.0 <= result <= 1.0
+        return result
+
+
+class MiniScriptLexer(RegexLexer):
+    """
+    For MiniScript source code.
+    """
+
+    name = 'MiniScript'
+    url = 'https://miniscript.org'
+    aliases = ['miniscript', 'ms']
+    filenames = ['*.ms']
+    mimetypes = ['text/x-minicript', 'application/x-miniscript']
+    version_added = '2.6'
+
+    tokens = {
+        'root': [
+            (r'#!(.*?)$', Comment.Preproc),
+            default('base'),
+        ],
+        'base': [
+            ('//.*$', Comment.Single),
+            (r'(?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?', Number),
+            (r'(?i)\d+e[+-]?\d+', Number),
+            (r'\d+', Number),
+            (r'\n', Text),
+            (r'[^\S\n]+', Text),
+            (r'"', String, 'string_double'),
+            (r'(==|!=|<=|>=|[=+\-*/%^<>.:])', Operator),
+            (r'[;,\[\]{}()]', Punctuation),
+            (words((
+                'break', 'continue', 'else', 'end', 'for', 'function', 'if',
+                'in', 'isa', 'then', 'repeat', 'return', 'while'), suffix=r'\b'),
+             Keyword),
+            (words((
+                'abs', 'acos', 'asin', 'atan', 'ceil', 'char', 'cos', 'floor',
+                'log', 'round', 'rnd', 'pi', 'sign', 'sin', 'sqrt', 'str', 'tan',
+                'hasIndex', 'indexOf', 'len', 'val', 'code', 'remove', 'lower',
+                'upper', 'replace', 'split', 'indexes', 'values', 'join', 'sum',
+                'sort', 'shuffle', 'push', 'pop', 'pull', 'range',
+                'print', 'input', 'time', 'wait', 'locals', 'globals', 'outer',
+                'yield'), suffix=r'\b'),
+             Name.Builtin),
+            (r'(true|false|null)\b', Keyword.Constant),
+            (r'(and|or|not|new)\b', Operator.Word),
+            (r'(self|super|__isa)\b', Name.Builtin.Pseudo),
+            (r'[a-zA-Z_]\w*', Name.Variable)
+        ],
+        'string_double': [
+            (r'[^"\n]+', String),
+            (r'""', String),
+            (r'"', String, '#pop'),
+            (r'\n', Text, '#pop'),  # Stray linefeed also terminates strings.
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/sgf.py b/.venv/Lib/site-packages/pygments/lexers/sgf.py
new file mode 100644
index 0000000..f0e56cb
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/sgf.py
@@ -0,0 +1,59 @@
+"""
+    pygments.lexers.sgf
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Smart Game Format (sgf) file format.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.token import Name, Literal, String, Punctuation, Whitespace
+
+__all__ = ["SmartGameFormatLexer"]
+
+
+class SmartGameFormatLexer(RegexLexer):
+    """
+    Lexer for Smart Game Format (sgf) file format.
+
+    The format is used to store game records of board games for two players
+    (mainly Go game).
+    """
+    name = 'SmartGameFormat'
+    url = 'https://www.red-bean.com/sgf/'
+    aliases = ['sgf']
+    filenames = ['*.sgf']
+    version_added = '2.4'
+
+    tokens = {
+        'root': [
+            (r'[():;]+', Punctuation),
+            # tokens:
+            (r'(A[BW]|AE|AN|AP|AR|AS|[BW]L|BM|[BW]R|[BW]S|[BW]T|CA|CH|CP|CR|'
+             r'DD|DM|DO|DT|EL|EV|EX|FF|FG|G[BW]|GC|GM|GN|HA|HO|ID|IP|IT|IY|KM|'
+             r'KO|LB|LN|LT|L|MA|MN|M|N|OB|OM|ON|OP|OT|OV|P[BW]|PC|PL|PM|RE|RG|'
+             r'RO|RU|SO|SC|SE|SI|SL|SO|SQ|ST|SU|SZ|T[BW]|TC|TE|TM|TR|UC|US|VW|'
+             r'V|[BW]|C)',
+             Name.Builtin),
+            # number:
+            (r'(\[)([0-9.]+)(\])',
+             bygroups(Punctuation, Literal.Number, Punctuation)),
+            # date:
+            (r'(\[)([0-9]{4}-[0-9]{2}-[0-9]{2})(\])',
+             bygroups(Punctuation, Literal.Date, Punctuation)),
+            # point:
+            (r'(\[)([a-z]{2})(\])',
+             bygroups(Punctuation, String, Punctuation)),
+            # double points:
+            (r'(\[)([a-z]{2})(:)([a-z]{2})(\])',
+             bygroups(Punctuation, String, Punctuation, String, Punctuation)),
+
+            (r'(\[)([\w\s#()+,\-.:?]+)(\])',
+             bygroups(Punctuation, String, Punctuation)),
+            (r'(\[)(\s.*)(\])',
+             bygroups(Punctuation, Whitespace, Punctuation)),
+            (r'\s+', Whitespace)
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/shell.py b/.venv/Lib/site-packages/pygments/lexers/shell.py
new file mode 100644
index 0000000..744767a
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/shell.py
@@ -0,0 +1,902 @@
+"""
+    pygments.lexers.shell
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for various shells.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import re
+
+from pygments.lexer import Lexer, RegexLexer, do_insertions, bygroups, \
+    include, default, this, using, words, line_re
+from pygments.token import Punctuation, Whitespace, \
+    Text, Comment, Operator, Keyword, Name, String, Number, Generic
+from pygments.util import shebang_matches
+
+__all__ = ['BashLexer', 'BashSessionLexer', 'TcshLexer', 'BatchLexer',
+           'SlurmBashLexer', 'MSDOSSessionLexer', 'PowerShellLexer',
+           'PowerShellSessionLexer', 'TcshSessionLexer', 'FishShellLexer',
+           'ExeclineLexer']
+
+
+class BashLexer(RegexLexer):
+    """
+    Lexer for (ba|k|z|)sh shell scripts.
+    """
+
+    name = 'Bash'
+    aliases = ['bash', 'sh', 'ksh', 'zsh', 'shell', 'openrc']
+    filenames = ['*.sh', '*.ksh', '*.bash', '*.ebuild', '*.eclass',
+                 '*.exheres-0', '*.exlib', '*.zsh',
+                 '.bashrc', 'bashrc', '.bash_*', 'bash_*', 'zshrc', '.zshrc',
+                 '.kshrc', 'kshrc',
+                 'PKGBUILD']
+    mimetypes = ['application/x-sh', 'application/x-shellscript', 'text/x-shellscript']
+    url = 'https://en.wikipedia.org/wiki/Unix_shell'
+    version_added = '0.6'
+
+    tokens = {
+        'root': [
+            include('basic'),
+            (r'`', String.Backtick, 'backticks'),
+            include('data'),
+            include('interp'),
+        ],
+        'interp': [
+            (r'\$\(\(', Keyword, 'math'),
+            (r'\$\(', Keyword, 'paren'),
+            (r'\$\{#?', String.Interpol, 'curly'),
+            (r'\$[a-zA-Z_]\w*', Name.Variable),  # user variable
+            (r'\$(?:\d+|[#$?!_*@-])', Name.Variable),      # builtin
+            (r'\$', Text),
+        ],
+        'basic': [
+            (r'\b(if|fi|else|while|in|do|done|for|then|return|function|case|'
+             r'select|break|continue|until|esac|elif)(\s*)\b',
+             bygroups(Keyword, Whitespace)),
+            (r'\b(alias|bg|bind|builtin|caller|cd|command|compgen|'
+             r'complete|declare|dirs|disown|echo|enable|eval|exec|exit|'
+             r'export|false|fc|fg|getopts|hash|help|history|jobs|kill|let|'
+             r'local|logout|popd|printf|pushd|pwd|read|readonly|set|shift|'
+             r'shopt|source|suspend|test|time|times|trap|true|type|typeset|'
+             r'ulimit|umask|unalias|unset|wait)(?=[\s)`])',
+             Name.Builtin),
+            (r'\A#!.+\n', Comment.Hashbang),
+            (r'#.*\n', Comment.Single),
+            (r'\\[\w\W]', String.Escape),
+            (r'(\b\w+)(\s*)(\+?=)', bygroups(Name.Variable, Whitespace, Operator)),
+            (r'[\[\]{}()=]', Operator),
+            (r'<<<', Operator),  # here-string
+            (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
+            (r'&&|\|\|', Operator),
+        ],
+        'data': [
+            (r'(?s)\$?"(\\.|[^"\\$])*"', String.Double),
+            (r'"', String.Double, 'string'),
+            (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
+            (r"(?s)'.*?'", String.Single),
+            (r';', Punctuation),
+            (r'&', Punctuation),
+            (r'\|', Punctuation),
+            (r'\s+', Whitespace),
+            (r'\d+\b', Number),
+            (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
+            (r'<', Text),
+        ],
+        'string': [
+            (r'"', String.Double, '#pop'),
+            (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double),
+            include('interp'),
+        ],
+        'curly': [
+            (r'\}', String.Interpol, '#pop'),
+            (r':-', Keyword),
+            (r'\w+', Name.Variable),
+            (r'[^}:"\'`$\\]+', Punctuation),
+            (r':', Punctuation),
+            include('root'),
+        ],
+        'paren': [
+            (r'\)', Keyword, '#pop'),
+            include('root'),
+        ],
+        'math': [
+            (r'\)\)', Keyword, '#pop'),
+            (r'\*\*|\|\||<<|>>|[-+*/%^|&<>]', Operator),
+            (r'\d+#[\da-zA-Z]+', Number),
+            (r'\d+#(?! )', Number),
+            (r'0[xX][\da-fA-F]+', Number),
+            (r'\d+', Number),
+            (r'[a-zA-Z_]\w*', Name.Variable),  # user variable
+            include('root'),
+        ],
+        'backticks': [
+            (r'`', String.Backtick, '#pop'),
+            include('root'),
+        ],
+    }
+
+    def analyse_text(text):
+        if shebang_matches(text, r'(ba|z|)sh'):
+            return 1
+        if text.startswith('$ '):
+            return 0.2
+
+
+class SlurmBashLexer(BashLexer):
+    """
+    Lexer for (ba|k|z|)sh Slurm scripts.
+    """
+
+    name = 'Slurm'
+    aliases = ['slurm', 'sbatch']
+    filenames = ['*.sl']
+    mimetypes = []
+    version_added = '2.4'
+    EXTRA_KEYWORDS = {'srun'}
+
+    def get_tokens_unprocessed(self, text):
+        for index, token, value in BashLexer.get_tokens_unprocessed(self, text):
+            if token is Text and value in self.EXTRA_KEYWORDS:
+                yield index, Name.Builtin, value
+            elif token is Comment.Single and 'SBATCH' in value:
+                yield index, Keyword.Pseudo, value
+            else:
+                yield index, token, value
+
+
+class ShellSessionBaseLexer(Lexer):
+    """
+    Base lexer for shell sessions.
+
+    .. versionadded:: 2.1
+    """
+
+    _bare_continuation = False
+    _venv = re.compile(r'^(\([^)]*\))(\s*)')
+
+    def get_tokens_unprocessed(self, text):
+        innerlexer = self._innerLexerCls(**self.options)
+
+        pos = 0
+        curcode = ''
+        insertions = []
+        backslash_continuation = False
+
+        for match in line_re.finditer(text):
+            line = match.group()
+
+            venv_match = self._venv.match(line)
+            if venv_match:
+                venv = venv_match.group(1)
+                venv_whitespace = venv_match.group(2)
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt.VirtualEnv, venv)]))
+                if venv_whitespace:
+                    insertions.append((len(curcode),
+                                       [(0, Text, venv_whitespace)]))
+                line = line[venv_match.end():]
+
+            m = self._ps1rgx.match(line)
+            if m:
+                # To support output lexers (say diff output), the output
+                # needs to be broken by prompts whenever the output lexer
+                # changes.
+                if not insertions:
+                    pos = match.start()
+
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt, m.group(1))]))
+                curcode += m.group(2)
+                backslash_continuation = curcode.endswith('\\\n')
+            elif backslash_continuation:
+                if line.startswith(self._ps2):
+                    insertions.append((len(curcode),
+                                       [(0, Generic.Prompt,
+                                         line[:len(self._ps2)])]))
+                    curcode += line[len(self._ps2):]
+                else:
+                    curcode += line
+                backslash_continuation = curcode.endswith('\\\n')
+            elif self._bare_continuation and line.startswith(self._ps2):
+                insertions.append((len(curcode),
+                                   [(0, Generic.Prompt,
+                                     line[:len(self._ps2)])]))
+                curcode += line[len(self._ps2):]
+            else:
+                if insertions:
+                    toks = innerlexer.get_tokens_unprocessed(curcode)
+                    for i, t, v in do_insertions(insertions, toks):
+                        yield pos+i, t, v
+                yield match.start(), Generic.Output, line
+                insertions = []
+                curcode = ''
+        if insertions:
+            for i, t, v in do_insertions(insertions,
+                                         innerlexer.get_tokens_unprocessed(curcode)):
+                yield pos+i, t, v
+
+
+class BashSessionLexer(ShellSessionBaseLexer):
+    """
+    Lexer for Bash shell sessions, i.e. command lines, including a
+    prompt, interspersed with output.
+    """
+
+    name = 'Bash Session'
+    aliases = ['console', 'shell-session']
+    filenames = ['*.sh-session', '*.shell-session']
+    mimetypes = ['application/x-shell-session', 'application/x-sh-session']
+    url = 'https://en.wikipedia.org/wiki/Unix_shell'
+    version_added = '1.1'
+    _example = "console/example.sh-session"
+
+    _innerLexerCls = BashLexer
+    _ps1rgx = re.compile(
+        r'^((?:(?:\[.*?\])|(?:\(\S+\))?(?:| |sh\S*?|\w+\S+[@:]\S+(?:\s+\S+)' \
+        r'?|\[\S+[@:][^\n]+\].+))\s*[$#%]\s*)(.*\n?)')
+    _ps2 = '> '
+
+
+class BatchLexer(RegexLexer):
+    """
+    Lexer for the DOS/Windows Batch file format.
+    """
+    name = 'Batchfile'
+    aliases = ['batch', 'bat', 'dosbatch', 'winbatch']
+    filenames = ['*.bat', '*.cmd']
+    mimetypes = ['application/x-dos-batch']
+    url = 'https://en.wikipedia.org/wiki/Batch_file'
+    version_added = '0.7'
+
+    flags = re.MULTILINE | re.IGNORECASE
+
+    _nl = r'\n\x1a'
+    _punct = r'&<>|'
+    _ws = r'\t\v\f\r ,;=\xa0'
+    _nlws = r'\s\x1a\xa0,;='
+    _space = rf'(?:(?:(?:\^[{_nl}])?[{_ws}])+)'
+    _keyword_terminator = (rf'(?=(?:\^[{_nl}]?)?[{_ws}+./:[\\\]]|[{_nl}{_punct}(])')
+    _token_terminator = rf'(?=\^?[{_ws}]|[{_punct}{_nl}])'
+    _start_label = rf'((?:(?<=^[^:])|^[^:]?)[{_ws}]*)(:)'
+    _label = rf'(?:(?:[^{_nlws}{_punct}+:^]|\^[{_nl}]?[\w\W])*)'
+    _label_compound = rf'(?:(?:[^{_nlws}{_punct}+:^)]|\^[{_nl}]?[^)])*)'
+    _number = rf'(?:-?(?:0[0-7]+|0x[\da-f]+|\d+){_token_terminator})'
+    _opword = r'(?:equ|geq|gtr|leq|lss|neq)'
+    _string = rf'(?:"[^{_nl}"]*(?:"|(?=[{_nl}])))'
+    _variable = (r'(?:(?:%(?:\*|(?:~[a-z]*(?:\$[^:]+:)?)?\d|'
+                 rf'[^%:{_nl}]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:[^%{_nl}^]|'
+                 rf'\^[^%{_nl}])[^={_nl}]*=(?:[^%{_nl}^]|\^[^%{_nl}])*)?)?%))|'
+                 rf'(?:\^?![^!:{_nl}]+(?::(?:~(?:-?\d+)?(?:,(?:-?\d+)?)?|(?:'
+                 rf'[^!{_nl}^]|\^[^!{_nl}])[^={_nl}]*=(?:[^!{_nl}^]|\^[^!{_nl}])*)?)?\^?!))')
+    _core_token = rf'(?:(?:(?:\^[{_nl}]?)?[^"{_nlws}{_punct}])+)'
+    _core_token_compound = rf'(?:(?:(?:\^[{_nl}]?)?[^"{_nlws}{_punct})])+)'
+    _token = rf'(?:[{_punct}]+|{_core_token})'
+    _token_compound = rf'(?:[{_punct}]+|{_core_token_compound})'
+    _stoken = (rf'(?:[{_punct}]+|(?:{_string}|{_variable}|{_core_token})+)')
+
+    def _make_begin_state(compound, _core_token=_core_token,
+                          _core_token_compound=_core_token_compound,
+                          _keyword_terminator=_keyword_terminator,
+                          _nl=_nl, _punct=_punct, _string=_string,
+                          _space=_space, _start_label=_start_label,
+                          _stoken=_stoken, _token_terminator=_token_terminator,
+                          _variable=_variable, _ws=_ws):
+        rest = '(?:{}|{}|[^"%{}{}{}])*'.format(_string, _variable, _nl, _punct,
+                                            ')' if compound else '')
+        rest_of_line = rf'(?:(?:[^{_nl}^]|\^[{_nl}]?[\w\W])*)'
+        rest_of_line_compound = rf'(?:(?:[^{_nl}^)]|\^[{_nl}]?[^)])*)'
+        set_space = rf'((?:(?:\^[{_nl}]?)?[^\S\n])*)'
+        suffix = ''
+        if compound:
+            _keyword_terminator = rf'(?:(?=\))|{_keyword_terminator})'
+            _token_terminator = rf'(?:(?=\))|{_token_terminator})'
+            suffix = '/compound'
+        return [
+            ((r'\)', Punctuation, '#pop') if compound else
+             (rf'\)((?=\()|{_token_terminator}){rest_of_line}',
+              Comment.Single)),
+            (rf'(?={_start_label})', Text, f'follow{suffix}'),
+            (_space, using(this, state='text')),
+            include(f'redirect{suffix}'),
+            (rf'[{_nl}]+', Text),
+            (r'\(', Punctuation, 'root/compound'),
+            (r'@+', Punctuation),
+            (rf'((?:for|if|rem)(?:(?=(?:\^[{_nl}]?)?/)|(?:(?!\^)|'
+             rf'(?<=m))(?:(?=\()|{_token_terminator})))({_space}?{_core_token_compound if compound else _core_token}?(?:\^[{_nl}]?)?/(?:\^[{_nl}]?)?\?)',
+             bygroups(Keyword, using(this, state='text')),
+             f'follow{suffix}'),
+            (rf'(goto{_keyword_terminator})({rest}(?:\^[{_nl}]?)?/(?:\^[{_nl}]?)?\?{rest})',
+             bygroups(Keyword, using(this, state='text')),
+             f'follow{suffix}'),
+            (words(('assoc', 'break', 'cd', 'chdir', 'cls', 'color', 'copy',
+                    'date', 'del', 'dir', 'dpath', 'echo', 'endlocal', 'erase',
+                    'exit', 'ftype', 'keys', 'md', 'mkdir', 'mklink', 'move',
+                    'path', 'pause', 'popd', 'prompt', 'pushd', 'rd', 'ren',
+                    'rename', 'rmdir', 'setlocal', 'shift', 'start', 'time',
+                    'title', 'type', 'ver', 'verify', 'vol'),
+                   suffix=_keyword_terminator), Keyword, f'follow{suffix}'),
+            (rf'(call)({_space}?)(:)',
+             bygroups(Keyword, using(this, state='text'), Punctuation),
+             f'call{suffix}'),
+            (rf'call{_keyword_terminator}', Keyword),
+            (rf'(for{_token_terminator}(?!\^))({_space})(/f{_token_terminator})',
+             bygroups(Keyword, using(this, state='text'), Keyword),
+             ('for/f', 'for')),
+            (rf'(for{_token_terminator}(?!\^))({_space})(/l{_token_terminator})',
+             bygroups(Keyword, using(this, state='text'), Keyword),
+             ('for/l', 'for')),
+            (rf'for{_token_terminator}(?!\^)', Keyword, ('for2', 'for')),
+            (rf'(goto{_keyword_terminator})({_space}?)(:?)',
+             bygroups(Keyword, using(this, state='text'), Punctuation),
+             f'label{suffix}'),
+            (rf'(if(?:(?=\()|{_token_terminator})(?!\^))({_space}?)((?:/i{_token_terminator})?)({_space}?)((?:not{_token_terminator})?)({_space}?)',
+             bygroups(Keyword, using(this, state='text'), Keyword,
+                      using(this, state='text'), Keyword,
+                      using(this, state='text')), ('(?', 'if')),
+            (rf'rem(((?=\()|{_token_terminator}){_space}?{_stoken}?.*|{_keyword_terminator}{rest_of_line_compound if compound else rest_of_line})',
+             Comment.Single, f'follow{suffix}'),
+            (rf'(set{_keyword_terminator}){set_space}(/a)',
+             bygroups(Keyword, using(this, state='text'), Keyword),
+             f'arithmetic{suffix}'),
+            (r'(set{}){}((?:/p)?){}((?:(?:(?:\^[{}]?)?[^"{}{}^={}]|'
+             r'\^[{}]?[^"=])+)?)((?:(?:\^[{}]?)?=)?)'.format(_keyword_terminator, set_space, set_space, _nl, _nl, _punct,
+              ')' if compound else '', _nl, _nl),
+             bygroups(Keyword, using(this, state='text'), Keyword,
+                      using(this, state='text'), using(this, state='variable'),
+                      Punctuation),
+             f'follow{suffix}'),
+            default(f'follow{suffix}')
+        ]
+
+    def _make_follow_state(compound, _label=_label,
+                           _label_compound=_label_compound, _nl=_nl,
+                           _space=_space, _start_label=_start_label,
+                           _token=_token, _token_compound=_token_compound,
+                           _ws=_ws):
+        suffix = '/compound' if compound else ''
+        state = []
+        if compound:
+            state.append((r'(?=\))', Text, '#pop'))
+        state += [
+            (rf'{_start_label}([{_ws}]*)({_label_compound if compound else _label})(.*)',
+             bygroups(Text, Punctuation, Text, Name.Label, Comment.Single)),
+            include(f'redirect{suffix}'),
+            (rf'(?=[{_nl}])', Text, '#pop'),
+            (r'\|\|?|&&?', Punctuation, '#pop'),
+            include('text')
+        ]
+        return state
+
+    def _make_arithmetic_state(compound, _nl=_nl, _punct=_punct,
+                               _string=_string, _variable=_variable,
+                               _ws=_ws, _nlws=_nlws):
+        op = r'=+\-*/!~'
+        state = []
+        if compound:
+            state.append((r'(?=\))', Text, '#pop'))
+        state += [
+            (r'0[0-7]+', Number.Oct),
+            (r'0x[\da-f]+', Number.Hex),
+            (r'\d+', Number.Integer),
+            (r'[(),]+', Punctuation),
+            (rf'([{op}]|%|\^\^)+', Operator),
+            (r'({}|{}|(\^[{}]?)?[^(){}%\^"{}{}]|\^[{}]?{})+'.format(_string, _variable, _nl, op, _nlws, _punct, _nlws,
+              r'[^)]' if compound else r'[\w\W]'),
+             using(this, state='variable')),
+            (r'(?=[\x00|&])', Text, '#pop'),
+            include('follow')
+        ]
+        return state
+
+    def _make_call_state(compound, _label=_label,
+                         _label_compound=_label_compound):
+        state = []
+        if compound:
+            state.append((r'(?=\))', Text, '#pop'))
+        state.append((r'(:?)(%s)' % (_label_compound if compound else _label),
+                      bygroups(Punctuation, Name.Label), '#pop'))
+        return state
+
+    def _make_label_state(compound, _label=_label,
+                          _label_compound=_label_compound, _nl=_nl,
+                          _punct=_punct, _string=_string, _variable=_variable):
+        state = []
+        if compound:
+            state.append((r'(?=\))', Text, '#pop'))
+        state.append((r'({}?)((?:{}|{}|\^[{}]?{}|[^"%^{}{}{}])*)'.format(_label_compound if compound else _label, _string,
+                       _variable, _nl, r'[^)]' if compound else r'[\w\W]', _nl,
+                       _punct, r')' if compound else ''),
+                      bygroups(Name.Label, Comment.Single), '#pop'))
+        return state
+
+    def _make_redirect_state(compound,
+                             _core_token_compound=_core_token_compound,
+                             _nl=_nl, _punct=_punct, _stoken=_stoken,
+                             _string=_string, _space=_space,
+                             _variable=_variable, _nlws=_nlws):
+        stoken_compound = (rf'(?:[{_punct}]+|(?:{_string}|{_variable}|{_core_token_compound})+)')
+        return [
+            (rf'((?:(?<=[{_nlws}])\d)?)(>>?&|<&)([{_nlws}]*)(\d)',
+             bygroups(Number.Integer, Punctuation, Text, Number.Integer)),
+            (rf'((?:(?<=[{_nlws}])(?>?|<)({_space}?{stoken_compound if compound else _stoken})',
+             bygroups(Number.Integer, Punctuation, using(this, state='text')))
+        ]
+
+    tokens = {
+        'root': _make_begin_state(False),
+        'follow': _make_follow_state(False),
+        'arithmetic': _make_arithmetic_state(False),
+        'call': _make_call_state(False),
+        'label': _make_label_state(False),
+        'redirect': _make_redirect_state(False),
+        'root/compound': _make_begin_state(True),
+        'follow/compound': _make_follow_state(True),
+        'arithmetic/compound': _make_arithmetic_state(True),
+        'call/compound': _make_call_state(True),
+        'label/compound': _make_label_state(True),
+        'redirect/compound': _make_redirect_state(True),
+        'variable-or-escape': [
+            (_variable, Name.Variable),
+            (rf'%%|\^[{_nl}]?(\^!|[\w\W])', String.Escape)
+        ],
+        'string': [
+            (r'"', String.Double, '#pop'),
+            (_variable, Name.Variable),
+            (r'\^!|%%', String.Escape),
+            (rf'[^"%^{_nl}]+|[%^]', String.Double),
+            default('#pop')
+        ],
+        'sqstring': [
+            include('variable-or-escape'),
+            (r'[^%]+|%', String.Single)
+        ],
+        'bqstring': [
+            include('variable-or-escape'),
+            (r'[^%]+|%', String.Backtick)
+        ],
+        'text': [
+            (r'"', String.Double, 'string'),
+            include('variable-or-escape'),
+            (rf'[^"%^{_nlws}{_punct}\d)]+|.', Text)
+        ],
+        'variable': [
+            (r'"', String.Double, 'string'),
+            include('variable-or-escape'),
+            (rf'[^"%^{_nl}]+|.', Name.Variable)
+        ],
+        'for': [
+            (rf'({_space})(in)({_space})(\()',
+             bygroups(using(this, state='text'), Keyword,
+                      using(this, state='text'), Punctuation), '#pop'),
+            include('follow')
+        ],
+        'for2': [
+            (r'\)', Punctuation),
+            (rf'({_space})(do{_token_terminator})',
+             bygroups(using(this, state='text'), Keyword), '#pop'),
+            (rf'[{_nl}]+', Text),
+            include('follow')
+        ],
+        'for/f': [
+            (rf'(")((?:{_variable}|[^"])*?")([{_nlws}]*)(\))',
+             bygroups(String.Double, using(this, state='string'), Text,
+                      Punctuation)),
+            (r'"', String.Double, ('#pop', 'for2', 'string')),
+            (rf"('(?:%%|{_variable}|[\w\W])*?')([{_nlws}]*)(\))",
+             bygroups(using(this, state='sqstring'), Text, Punctuation)),
+            (rf'(`(?:%%|{_variable}|[\w\W])*?`)([{_nlws}]*)(\))',
+             bygroups(using(this, state='bqstring'), Text, Punctuation)),
+            include('for2')
+        ],
+        'for/l': [
+            (r'-?\d+', Number.Integer),
+            include('for2')
+        ],
+        'if': [
+            (rf'((?:cmdextversion|errorlevel){_token_terminator})({_space})(\d+)',
+             bygroups(Keyword, using(this, state='text'),
+                      Number.Integer), '#pop'),
+            (rf'(defined{_token_terminator})({_space})({_stoken})',
+             bygroups(Keyword, using(this, state='text'),
+                      using(this, state='variable')), '#pop'),
+            (rf'(exist{_token_terminator})({_space}{_stoken})',
+             bygroups(Keyword, using(this, state='text')), '#pop'),
+            (rf'({_number}{_space})({_opword})({_space}{_number})',
+             bygroups(using(this, state='arithmetic'), Operator.Word,
+                      using(this, state='arithmetic')), '#pop'),
+            (_stoken, using(this, state='text'), ('#pop', 'if2')),
+        ],
+        'if2': [
+            (rf'({_space}?)(==)({_space}?{_stoken})',
+             bygroups(using(this, state='text'), Operator,
+                      using(this, state='text')), '#pop'),
+            (rf'({_space})({_opword})({_space}{_stoken})',
+             bygroups(using(this, state='text'), Operator.Word,
+                      using(this, state='text')), '#pop')
+        ],
+        '(?': [
+            (_space, using(this, state='text')),
+            (r'\(', Punctuation, ('#pop', 'else?', 'root/compound')),
+            default('#pop')
+        ],
+        'else?': [
+            (_space, using(this, state='text')),
+            (rf'else{_token_terminator}', Keyword, '#pop'),
+            default('#pop')
+        ]
+    }
+
+
+class MSDOSSessionLexer(ShellSessionBaseLexer):
+    """
+    Lexer for MS DOS shell sessions, i.e. command lines, including a
+    prompt, interspersed with output.
+    """
+
+    name = 'MSDOS Session'
+    aliases = ['doscon']
+    filenames = []
+    mimetypes = []
+    url = 'https://en.wikipedia.org/wiki/MS-DOS'
+    version_added = '2.1'
+    _example = "doscon/session"
+
+    _innerLexerCls = BatchLexer
+    _ps1rgx = re.compile(r'^([^>]*>)(.*\n?)')
+    _ps2 = 'More? '
+
+
+class TcshLexer(RegexLexer):
+    """
+    Lexer for tcsh scripts.
+    """
+
+    name = 'Tcsh'
+    aliases = ['tcsh', 'csh']
+    filenames = ['*.tcsh', '*.csh']
+    mimetypes = ['application/x-csh']
+    url = 'https://www.tcsh.org'
+    version_added = '0.10'
+
+    tokens = {
+        'root': [
+            include('basic'),
+            (r'\$\(', Keyword, 'paren'),
+            (r'\$\{#?', Keyword, 'curly'),
+            (r'`', String.Backtick, 'backticks'),
+            include('data'),
+        ],
+        'basic': [
+            (r'\b(if|endif|else|while|then|foreach|case|default|'
+             r'break|continue|goto|breaksw|end|switch|endsw)\s*\b',
+             Keyword),
+            (r'\b(alias|alloc|bg|bindkey|builtins|bye|caller|cd|chdir|'
+             r'complete|dirs|echo|echotc|eval|exec|exit|fg|filetest|getxvers|'
+             r'glob|getspath|hashstat|history|hup|inlib|jobs|kill|'
+             r'limit|log|login|logout|ls-F|migrate|newgrp|nice|nohup|notify|'
+             r'onintr|popd|printenv|pushd|rehash|repeat|rootnode|popd|pushd|'
+             r'set|shift|sched|setenv|setpath|settc|setty|setxvers|shift|'
+             r'source|stop|suspend|source|suspend|telltc|time|'
+             r'umask|unalias|uncomplete|unhash|universe|unlimit|unset|unsetenv|'
+             r'ver|wait|warp|watchlog|where|which)\s*\b',
+             Name.Builtin),
+            (r'#.*', Comment),
+            (r'\\[\w\W]', String.Escape),
+            (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Text, Operator)),
+            (r'[\[\]{}()=]+', Operator),
+            (r'<<\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
+            (r';', Punctuation),
+        ],
+        'data': [
+            (r'(?s)"(\\\\|\\[0-7]+|\\.|[^"\\])*"', String.Double),
+            (r"(?s)'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
+            (r'\s+', Text),
+            (r'[^=\s\[\]{}()$"\'`\\;#]+', Text),
+            (r'\d+(?= |\Z)', Number),
+            (r'\$#?(\w+|.)', Name.Variable),
+        ],
+        'curly': [
+            (r'\}', Keyword, '#pop'),
+            (r':-', Keyword),
+            (r'\w+', Name.Variable),
+            (r'[^}:"\'`$]+', Punctuation),
+            (r':', Punctuation),
+            include('root'),
+        ],
+        'paren': [
+            (r'\)', Keyword, '#pop'),
+            include('root'),
+        ],
+        'backticks': [
+            (r'`', String.Backtick, '#pop'),
+            include('root'),
+        ],
+    }
+
+
+class TcshSessionLexer(ShellSessionBaseLexer):
+    """
+    Lexer for Tcsh sessions, i.e. command lines, including a
+    prompt, interspersed with output.
+    """
+
+    name = 'Tcsh Session'
+    aliases = ['tcshcon']
+    filenames = []
+    mimetypes = []
+    url = 'https://www.tcsh.org'
+    version_added = '2.1'
+    _example = "tcshcon/session"
+
+    _innerLexerCls = TcshLexer
+    _ps1rgx = re.compile(r'^([^>]+>)(.*\n?)')
+    _ps2 = '? '
+
+
+class PowerShellLexer(RegexLexer):
+    """
+    For Windows PowerShell code.
+    """
+    name = 'PowerShell'
+    aliases = ['powershell', 'pwsh', 'posh', 'ps1', 'psm1']
+    filenames = ['*.ps1', '*.psm1']
+    mimetypes = ['text/x-powershell']
+    url = 'https://learn.microsoft.com/en-us/powershell'
+    version_added = '1.5'
+
+    flags = re.DOTALL | re.IGNORECASE | re.MULTILINE
+
+    keywords = (
+        'while validateset validaterange validatepattern validatelength '
+        'validatecount until trap switch return ref process param parameter in '
+        'if global: local: function foreach for finally filter end elseif else '
+        'dynamicparam do default continue cmdletbinding break begin alias \\? '
+        '% #script #private #local #global mandatory parametersetname position '
+        'valuefrompipeline valuefrompipelinebypropertyname '
+        'valuefromremainingarguments helpmessage try catch throw').split()
+
+    operators = (
+        'and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle '
+        'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains '
+        'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt '
+        'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like '
+        'lt match ne not notcontains notlike notmatch or regex replace '
+        'wildcard').split()
+
+    verbs = (
+        'write where watch wait use update unregister unpublish unprotect '
+        'unlock uninstall undo unblock trace test tee take sync switch '
+        'suspend submit stop step start split sort skip show set send select '
+        'search scroll save revoke resume restore restart resolve resize '
+        'reset request repair rename remove register redo receive read push '
+        'publish protect pop ping out optimize open new move mount merge '
+        'measure lock limit join invoke install initialize import hide group '
+        'grant get format foreach find export expand exit enter enable edit '
+        'dismount disconnect disable deny debug cxnew copy convertto '
+        'convertfrom convert connect confirm compress complete compare close '
+        'clear checkpoint block backup assert approve aggregate add').split()
+
+    aliases_ = (
+        'ac asnp cat cd cfs chdir clc clear clhy cli clp cls clv cnsn '
+        'compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo epal '
+        'epcsv epsn erase etsn exsn fc fhx fl foreach ft fw gal gbp gc gci gcm '
+        'gcs gdr ghy gi gjb gl gm gmo gp gps gpv group gsn gsnp gsv gu gv gwmi '
+        'h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp '
+        'ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv '
+        'oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo '
+        'rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc select '
+        'set shcm si sl sleep sls sort sp spjb spps spsv start sujb sv swmi tee '
+        'trcm type wget where wjb write').split()
+
+    commenthelp = (
+        'component description example externalhelp forwardhelpcategory '
+        'forwardhelptargetname functionality inputs link '
+        'notes outputs parameter remotehelprunspace role synopsis').split()
+
+    tokens = {
+        'root': [
+            # we need to count pairs of parentheses for correct highlight
+            # of '$(...)' blocks in strings
+            (r'\(', Punctuation, 'child'),
+            (r'\s+', Text),
+            (r'^(\s*#[#\s]*)(\.(?:{}))([^\n]*$)'.format('|'.join(commenthelp)),
+             bygroups(Comment, String.Doc, Comment)),
+            (r'#[^\n]*?$', Comment),
+            (r'(<|<)#', Comment.Multiline, 'multline'),
+            (r'@"\n', String.Heredoc, 'heredoc-double'),
+            (r"@'\n.*?\n'@", String.Heredoc),
+            # escaped syntax
+            (r'`[\'"$@-]', Punctuation),
+            (r'"', String.Double, 'string'),
+            (r"'([^']|'')*'", String.Single),
+            (r'(\$|@@|@)((global|script|private|env):)?\w+',
+             Name.Variable),
+            (r'({})\b'.format('|'.join(keywords)), Keyword),
+            (r'-({})\b'.format('|'.join(operators)), Operator),
+            (r'({})-[a-z_]\w*\b'.format('|'.join(verbs)), Name.Builtin),
+            (r'({})\s'.format('|'.join(aliases_)), Name.Builtin),
+            (r'\[[a-z_\[][\w. `,\[\]]*\]', Name.Constant),  # .net [type]s
+            (r'-[a-z_]\w*', Name),
+            (r'\w+', Name),
+            (r'[.,;:@{}\[\]$()=+*/\\&%!~?^`|<>-]', Punctuation),
+        ],
+        'child': [
+            (r'\)', Punctuation, '#pop'),
+            include('root'),
+        ],
+        'multline': [
+            (r'[^#&.]+', Comment.Multiline),
+            (r'#(>|>)', Comment.Multiline, '#pop'),
+            (r'\.({})'.format('|'.join(commenthelp)), String.Doc),
+            (r'[#&.]', Comment.Multiline),
+        ],
+        'string': [
+            (r"`[0abfnrtv'\"$`]", String.Escape),
+            (r'[^$`"]+', String.Double),
+            (r'\$\(', Punctuation, 'child'),
+            (r'""', String.Double),
+            (r'[`$]', String.Double),
+            (r'"', String.Double, '#pop'),
+        ],
+        'heredoc-double': [
+            (r'\n"@', String.Heredoc, '#pop'),
+            (r'\$\(', Punctuation, 'child'),
+            (r'[^@\n]+"]', String.Heredoc),
+            (r".", String.Heredoc),
+        ]
+    }
+
+
+class PowerShellSessionLexer(ShellSessionBaseLexer):
+    """
+    Lexer for PowerShell sessions, i.e. command lines, including a
+    prompt, interspersed with output.
+    """
+
+    name = 'PowerShell Session'
+    aliases = ['pwsh-session', 'ps1con']
+    filenames = []
+    mimetypes = []
+    url = 'https://learn.microsoft.com/en-us/powershell'
+    version_added = '2.1'
+    _example = "pwsh-session/session"
+
+    _innerLexerCls = PowerShellLexer
+    _bare_continuation = True
+    _ps1rgx = re.compile(r'^((?:\[[^]]+\]: )?PS[^>]*> ?)(.*\n?)')
+    _ps2 = '> '
+
+
+class FishShellLexer(RegexLexer):
+    """
+    Lexer for Fish shell scripts.
+    """
+
+    name = 'Fish'
+    aliases = ['fish', 'fishshell']
+    filenames = ['*.fish', '*.load']
+    mimetypes = ['application/x-fish']
+    url = 'https://fishshell.com'
+    version_added = '2.1'
+
+    tokens = {
+        'root': [
+            include('basic'),
+            include('data'),
+            include('interp'),
+        ],
+        'interp': [
+            (r'\$\(\(', Keyword, 'math'),
+            (r'\(', Keyword, 'paren'),
+            (r'\$#?(\w+|.)', Name.Variable),
+        ],
+        'basic': [
+            (r'\b(begin|end|if|else|while|break|for|in|return|function|block|'
+             r'case|continue|switch|not|and|or|set|echo|exit|pwd|true|false|'
+             r'cd|count|test)(\s*)\b',
+             bygroups(Keyword, Text)),
+            (r'\b(alias|bg|bind|breakpoint|builtin|command|commandline|'
+             r'complete|contains|dirh|dirs|emit|eval|exec|fg|fish|fish_config|'
+             r'fish_indent|fish_pager|fish_prompt|fish_right_prompt|'
+             r'fish_update_completions|fishd|funced|funcsave|functions|help|'
+             r'history|isatty|jobs|math|mimedb|nextd|open|popd|prevd|psub|'
+             r'pushd|random|read|set_color|source|status|trap|type|ulimit|'
+             r'umask|vared|fc|getopts|hash|kill|printf|time|wait)\s*\b(?!\.)',
+             Name.Builtin),
+            (r'#.*\n', Comment),
+            (r'\\[\w\W]', String.Escape),
+            (r'(\b\w+)(\s*)(=)', bygroups(Name.Variable, Whitespace, Operator)),
+            (r'[\[\]()=]', Operator),
+            (r'<<-?\s*(\'?)\\?(\w+)[\w\W]+?\2', String),
+        ],
+        'data': [
+            (r'(?s)\$?"(\\\\|\\[0-7]+|\\.|[^"\\$])*"', String.Double),
+            (r'"', String.Double, 'string'),
+            (r"(?s)\$'(\\\\|\\[0-7]+|\\.|[^'\\])*'", String.Single),
+            (r"(?s)'.*?'", String.Single),
+            (r';', Punctuation),
+            (r'&|\||\^|<|>', Operator),
+            (r'\s+', Text),
+            (r'\d+(?= |\Z)', Number),
+            (r'[^=\s\[\]{}()$"\'`\\<&|;]+', Text),
+        ],
+        'string': [
+            (r'"', String.Double, '#pop'),
+            (r'(?s)(\\\\|\\[0-7]+|\\.|[^"\\$])+', String.Double),
+            include('interp'),
+        ],
+        'paren': [
+            (r'\)', Keyword, '#pop'),
+            include('root'),
+        ],
+        'math': [
+            (r'\)\)', Keyword, '#pop'),
+            (r'[-+*/%^|&]|\*\*|\|\|', Operator),
+            (r'\d+#\d+', Number),
+            (r'\d+#(?! )', Number),
+            (r'\d+', Number),
+            include('root'),
+        ],
+    }
+
+class ExeclineLexer(RegexLexer):
+    """
+    Lexer for Laurent Bercot's execline language.
+    """
+
+    name = 'execline'
+    aliases = ['execline']
+    filenames = ['*.exec']
+    url = 'https://skarnet.org/software/execline'
+    version_added = '2.7'
+
+    tokens = {
+        'root': [
+            include('basic'),
+            include('data'),
+            include('interp')
+        ],
+        'interp': [
+            (r'\$\{', String.Interpol, 'curly'),
+            (r'\$[\w@#]+', Name.Variable),  # user variable
+            (r'\$', Text),
+        ],
+        'basic': [
+            (r'\b(background|backtick|cd|define|dollarat|elgetopt|'
+             r'elgetpositionals|elglob|emptyenv|envfile|exec|execlineb|'
+             r'exit|export|fdblock|fdclose|fdmove|fdreserve|fdswap|'
+             r'forbacktickx|foreground|forstdin|forx|getcwd|getpid|heredoc|'
+             r'homeof|if|ifelse|ifte|ifthenelse|importas|loopwhilex|'
+             r'multidefine|multisubstitute|pipeline|piperw|posix-cd|'
+             r'redirfd|runblock|shift|trap|tryexec|umask|unexport|wait|'
+             r'withstdinas)\b', Name.Builtin),
+            (r'\A#!.+\n', Comment.Hashbang),
+            (r'#.*\n', Comment.Single),
+            (r'[{}]', Operator)
+        ],
+        'data': [
+            (r'(?s)"(\\.|[^"\\$])*"', String.Double),
+            (r'"', String.Double, 'string'),
+            (r'\s+', Text),
+            (r'[^\s{}$"\\]+', Text)
+        ],
+        'string': [
+            (r'"', String.Double, '#pop'),
+            (r'(?s)(\\\\|\\.|[^"\\$])+', String.Double),
+            include('interp'),
+        ],
+        'curly': [
+            (r'\}', String.Interpol, '#pop'),
+            (r'[\w#@]+', Name.Variable),
+            include('root')
+        ]
+
+    }
+
+    def analyse_text(text):
+        if shebang_matches(text, r'execlineb'):
+            return 1
diff --git a/.venv/Lib/site-packages/pygments/lexers/sieve.py b/.venv/Lib/site-packages/pygments/lexers/sieve.py
new file mode 100644
index 0000000..fc48980
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/sieve.py
@@ -0,0 +1,78 @@
+"""
+    pygments.lexers.sieve
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Sieve file format.
+
+    https://tools.ietf.org/html/rfc5228
+    https://tools.ietf.org/html/rfc5173
+    https://tools.ietf.org/html/rfc5229
+    https://tools.ietf.org/html/rfc5230
+    https://tools.ietf.org/html/rfc5232
+    https://tools.ietf.org/html/rfc5235
+    https://tools.ietf.org/html/rfc5429
+    https://tools.ietf.org/html/rfc8580
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.token import Comment, Name, Literal, String, Text, Punctuation, \
+    Keyword
+
+__all__ = ["SieveLexer"]
+
+
+class SieveLexer(RegexLexer):
+    """
+    Lexer for sieve format.
+    """
+    name = 'Sieve'
+    filenames = ['*.siv', '*.sieve']
+    aliases = ['sieve']
+    url = 'https://en.wikipedia.org/wiki/Sieve_(mail_filtering_language)'
+    version_added = '2.6'
+
+    tokens = {
+        'root': [
+            (r'\s+', Text),
+            (r'[();,{}\[\]]', Punctuation),
+            # import:
+            (r'(?i)require',
+             Keyword.Namespace),
+            # tags:
+            (r'(?i)(:)(addresses|all|contains|content|create|copy|comparator|'
+             r'count|days|detail|domain|fcc|flags|from|handle|importance|is|'
+             r'localpart|length|lowerfirst|lower|matches|message|mime|options|'
+             r'over|percent|quotewildcard|raw|regex|specialuse|subject|text|'
+             r'under|upperfirst|upper|value)',
+             bygroups(Name.Tag, Name.Tag)),
+            # tokens:
+            (r'(?i)(address|addflag|allof|anyof|body|discard|elsif|else|envelope|'
+             r'ereject|exists|false|fileinto|if|hasflag|header|keep|'
+             r'notify_method_capability|notify|not|redirect|reject|removeflag|'
+             r'setflag|size|spamtest|stop|string|true|vacation|virustest)',
+             Name.Builtin),
+            (r'(?i)set',
+             Keyword.Declaration),
+            # number:
+            (r'([0-9.]+)([kmgKMG])?',
+             bygroups(Literal.Number, Literal.Number)),
+            # comment:
+            (r'#.*$',
+             Comment.Single),
+            (r'/\*.*\*/',
+             Comment.Multiline),
+            # string:
+            (r'"[^"]*?"',
+             String),
+            # text block:
+            (r'text:',
+             Name.Tag, 'text'),
+        ],
+        'text': [
+            (r'[^.].*?\n', String),
+            (r'^\.', Punctuation, "#pop"),
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/slash.py b/.venv/Lib/site-packages/pygments/lexers/slash.py
new file mode 100644
index 0000000..1c439d0
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/slash.py
@@ -0,0 +1,183 @@
+"""
+    pygments.lexers.slash
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for the Slash programming language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import ExtendedRegexLexer, bygroups, DelegatingLexer
+from pygments.token import Name, Number, String, Comment, Punctuation, \
+    Other, Keyword, Operator, Whitespace
+
+__all__ = ['SlashLexer']
+
+
+class SlashLanguageLexer(ExtendedRegexLexer):
+    _nkw = r'(?=[^a-zA-Z_0-9])'
+
+    def move_state(new_state):
+        return ("#pop", new_state)
+
+    def right_angle_bracket(lexer, match, ctx):
+        if len(ctx.stack) > 1 and ctx.stack[-2] == "string":
+            ctx.stack.pop()
+        yield match.start(), String.Interpol, '}'
+        ctx.pos = match.end()
+        pass
+
+    tokens = {
+        "root": [
+            (r"<%=",        Comment.Preproc,    move_state("slash")),
+            (r"<%!!",       Comment.Preproc,    move_state("slash")),
+            (r"<%#.*?%>",   Comment.Multiline),
+            (r"<%",         Comment.Preproc,    move_state("slash")),
+            (r".|\n",       Other),
+        ],
+        "string": [
+            (r"\\",         String.Escape,      move_state("string_e")),
+            (r"\"",         String,             move_state("slash")),
+            (r"#\{",        String.Interpol,    "slash"),
+            (r'.|\n',       String),
+        ],
+        "string_e": [
+            (r'n',                  String.Escape,      move_state("string")),
+            (r't',                  String.Escape,      move_state("string")),
+            (r'r',                  String.Escape,      move_state("string")),
+            (r'e',                  String.Escape,      move_state("string")),
+            (r'x[a-fA-F0-9]{2}',    String.Escape,      move_state("string")),
+            (r'.',                  String.Escape,      move_state("string")),
+        ],
+        "regexp": [
+            (r'}[a-z]*',            String.Regex,       move_state("slash")),
+            (r'\\(.|\n)',           String.Regex),
+            (r'{',                  String.Regex,       "regexp_r"),
+            (r'.|\n',               String.Regex),
+        ],
+        "regexp_r": [
+            (r'}[a-z]*',            String.Regex,       "#pop"),
+            (r'\\(.|\n)',           String.Regex),
+            (r'{',                  String.Regex,       "regexp_r"),
+        ],
+        "slash": [
+            (r"%>",                     Comment.Preproc,    move_state("root")),
+            (r"\"",                     String,             move_state("string")),
+            (r"'[a-zA-Z0-9_]+",         String),
+            (r'%r{',                    String.Regex,       move_state("regexp")),
+            (r'/\*.*?\*/',              Comment.Multiline),
+            (r"(#|//).*?\n",            Comment.Single),
+            (r'-?[0-9]+e[+-]?[0-9]+',   Number.Float),
+            (r'-?[0-9]+\.[0-9]+(e[+-]?[0-9]+)?', Number.Float),
+            (r'-?[0-9]+',               Number.Integer),
+            (r'nil'+_nkw,               Name.Builtin),
+            (r'true'+_nkw,              Name.Builtin),
+            (r'false'+_nkw,             Name.Builtin),
+            (r'self'+_nkw,              Name.Builtin),
+            (r'(class)(\s+)([A-Z][a-zA-Z0-9_\']*)',
+                bygroups(Keyword, Whitespace, Name.Class)),
+            (r'class'+_nkw,             Keyword),
+            (r'extends'+_nkw,           Keyword),
+            (r'(def)(\s+)(self)(\s*)(\.)(\s*)([a-z_][a-zA-Z0-9_\']*=?|<<|>>|==|<=>|<=|<|>=|>|\+|-(self)?|~(self)?|\*|/|%|^|&&|&|\||\[\]=?)',
+                bygroups(Keyword, Whitespace, Name.Builtin, Whitespace, Punctuation, Whitespace, Name.Function)),
+            (r'(def)(\s+)([a-z_][a-zA-Z0-9_\']*=?|<<|>>|==|<=>|<=|<|>=|>|\+|-(self)?|~(self)?|\*|/|%|^|&&|&|\||\[\]=?)',
+                bygroups(Keyword, Whitespace, Name.Function)),
+            (r'def'+_nkw,               Keyword),
+            (r'if'+_nkw,                Keyword),
+            (r'elsif'+_nkw,             Keyword),
+            (r'else'+_nkw,              Keyword),
+            (r'unless'+_nkw,            Keyword),
+            (r'for'+_nkw,               Keyword),
+            (r'in'+_nkw,                Keyword),
+            (r'while'+_nkw,             Keyword),
+            (r'until'+_nkw,             Keyword),
+            (r'and'+_nkw,               Keyword),
+            (r'or'+_nkw,                Keyword),
+            (r'not'+_nkw,               Keyword),
+            (r'lambda'+_nkw,            Keyword),
+            (r'try'+_nkw,               Keyword),
+            (r'catch'+_nkw,             Keyword),
+            (r'return'+_nkw,            Keyword),
+            (r'next'+_nkw,              Keyword),
+            (r'last'+_nkw,              Keyword),
+            (r'throw'+_nkw,             Keyword),
+            (r'use'+_nkw,               Keyword),
+            (r'switch'+_nkw,            Keyword),
+            (r'\\',                     Keyword),
+            (r'λ',                      Keyword),
+            (r'__FILE__'+_nkw,          Name.Builtin.Pseudo),
+            (r'__LINE__'+_nkw,          Name.Builtin.Pseudo),
+            (r'[A-Z][a-zA-Z0-9_\']*'+_nkw, Name.Constant),
+            (r'[a-z_][a-zA-Z0-9_\']*'+_nkw, Name),
+            (r'@[a-z_][a-zA-Z0-9_\']*'+_nkw, Name.Variable.Instance),
+            (r'@@[a-z_][a-zA-Z0-9_\']*'+_nkw, Name.Variable.Class),
+            (r'\(',                     Punctuation),
+            (r'\)',                     Punctuation),
+            (r'\[',                     Punctuation),
+            (r'\]',                     Punctuation),
+            (r'\{',                     Punctuation),
+            (r'\}',                     right_angle_bracket),
+            (r';',                      Punctuation),
+            (r',',                      Punctuation),
+            (r'<<=',                    Operator),
+            (r'>>=',                    Operator),
+            (r'<<',                     Operator),
+            (r'>>',                     Operator),
+            (r'==',                     Operator),
+            (r'!=',                     Operator),
+            (r'=>',                     Operator),
+            (r'=',                      Operator),
+            (r'<=>',                    Operator),
+            (r'<=',                     Operator),
+            (r'>=',                     Operator),
+            (r'<',                      Operator),
+            (r'>',                      Operator),
+            (r'\+\+',                   Operator),
+            (r'\+=',                    Operator),
+            (r'-=',                     Operator),
+            (r'\*\*=',                  Operator),
+            (r'\*=',                    Operator),
+            (r'\*\*',                   Operator),
+            (r'\*',                     Operator),
+            (r'/=',                     Operator),
+            (r'\+',                     Operator),
+            (r'-',                      Operator),
+            (r'/',                      Operator),
+            (r'%=',                     Operator),
+            (r'%',                      Operator),
+            (r'^=',                     Operator),
+            (r'&&=',                    Operator),
+            (r'&=',                     Operator),
+            (r'&&',                     Operator),
+            (r'&',                      Operator),
+            (r'\|\|=',                  Operator),
+            (r'\|=',                    Operator),
+            (r'\|\|',                   Operator),
+            (r'\|',                     Operator),
+            (r'!',                      Operator),
+            (r'\.\.\.',                 Operator),
+            (r'\.\.',                   Operator),
+            (r'\.',                     Operator),
+            (r'::',                     Operator),
+            (r':',                      Operator),
+            (r'(\s|\n)+',               Whitespace),
+            (r'[a-z_][a-zA-Z0-9_\']*',  Name.Variable),
+        ],
+    }
+
+
+class SlashLexer(DelegatingLexer):
+    """
+    Lexer for the Slash programming language.
+    """
+
+    name = 'Slash'
+    aliases = ['slash']
+    filenames = ['*.sla']
+    url = 'https://github.com/arturadib/Slash-A'
+    version_added = '2.4'
+
+    def __init__(self, **options):
+        from pygments.lexers.web import HtmlLexer
+        super().__init__(HtmlLexer, SlashLanguageLexer, **options)
diff --git a/.venv/Lib/site-packages/pygments/lexers/smalltalk.py b/.venv/Lib/site-packages/pygments/lexers/smalltalk.py
new file mode 100644
index 0000000..674b7b4
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/smalltalk.py
@@ -0,0 +1,194 @@
+"""
+    pygments.lexers.smalltalk
+    ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Smalltalk and related languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, include, bygroups, default
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['SmalltalkLexer', 'NewspeakLexer']
+
+
+class SmalltalkLexer(RegexLexer):
+    """
+    For Smalltalk syntax.
+    Contributed by Stefan Matthias Aust.
+    Rewritten by Nils Winter.
+    """
+    name = 'Smalltalk'
+    url = 'http://www.smalltalk.org/'
+    filenames = ['*.st']
+    aliases = ['smalltalk', 'squeak', 'st']
+    mimetypes = ['text/x-smalltalk']
+    version_added = '0.10'
+
+    tokens = {
+        'root': [
+            (r'(<)(\w+:)(.*?)(>)', bygroups(Text, Keyword, Text, Text)),
+            include('squeak fileout'),
+            include('whitespaces'),
+            include('method definition'),
+            (r'(\|)([\w\s]*)(\|)', bygroups(Operator, Name.Variable, Operator)),
+            include('objects'),
+            (r'\^|\:=|\_', Operator),
+            # temporaries
+            (r'[\]({}.;!]', Text),
+        ],
+        'method definition': [
+            # Not perfect can't allow whitespaces at the beginning and the
+            # without breaking everything
+            (r'([a-zA-Z]+\w*:)(\s*)(\w+)',
+             bygroups(Name.Function, Text, Name.Variable)),
+            (r'^(\b[a-zA-Z]+\w*\b)(\s*)$', bygroups(Name.Function, Text)),
+            (r'^([-+*/\\~<>=|&!?,@%]+)(\s*)(\w+)(\s*)$',
+             bygroups(Name.Function, Text, Name.Variable, Text)),
+        ],
+        'blockvariables': [
+            include('whitespaces'),
+            (r'(:)(\s*)(\w+)',
+             bygroups(Operator, Text, Name.Variable)),
+            (r'\|', Operator, '#pop'),
+            default('#pop'),  # else pop
+        ],
+        'literals': [
+            (r"'(''|[^'])*'", String, 'afterobject'),
+            (r'\$.', String.Char, 'afterobject'),
+            (r'#\(', String.Symbol, 'parenth'),
+            (r'\)', Text, 'afterobject'),
+            (r'(\d+r)?-?\d+(\.\d+)?(e-?\d+)?', Number, 'afterobject'),
+        ],
+        '_parenth_helper': [
+            include('whitespaces'),
+            (r'(\d+r)?-?\d+(\.\d+)?(e-?\d+)?', Number),
+            (r'[-+*/\\~<>=|&#!?,@%\w:]+', String.Symbol),
+            # literals
+            (r"'(''|[^'])*'", String),
+            (r'\$.', String.Char),
+            (r'#*\(', String.Symbol, 'inner_parenth'),
+        ],
+        'parenth': [
+            # This state is a bit tricky since
+            # we can't just pop this state
+            (r'\)', String.Symbol, ('root', 'afterobject')),
+            include('_parenth_helper'),
+        ],
+        'inner_parenth': [
+            (r'\)', String.Symbol, '#pop'),
+            include('_parenth_helper'),
+        ],
+        'whitespaces': [
+            # skip whitespace and comments
+            (r'\s+', Text),
+            (r'"(""|[^"])*"', Comment),
+        ],
+        'objects': [
+            (r'\[', Text, 'blockvariables'),
+            (r'\]', Text, 'afterobject'),
+            (r'\b(self|super|true|false|nil|thisContext)\b',
+             Name.Builtin.Pseudo, 'afterobject'),
+            (r'\b[A-Z]\w*(?!:)\b', Name.Class, 'afterobject'),
+            (r'\b[a-z]\w*(?!:)\b', Name.Variable, 'afterobject'),
+            (r'#("(""|[^"])*"|[-+*/\\~<>=|&!?,@%]+|[\w:]+)',
+             String.Symbol, 'afterobject'),
+            include('literals'),
+        ],
+        'afterobject': [
+            (r'! !$', Keyword, '#pop'),  # squeak chunk delimiter
+            include('whitespaces'),
+            (r'\b(ifTrue:|ifFalse:|whileTrue:|whileFalse:|timesRepeat:)',
+             Name.Builtin, '#pop'),
+            (r'\b(new\b(?!:))', Name.Builtin),
+            (r'\:=|\_', Operator, '#pop'),
+            (r'\b[a-zA-Z]+\w*:', Name.Function, '#pop'),
+            (r'\b[a-zA-Z]+\w*', Name.Function),
+            (r'\w+:?|[-+*/\\~<>=|&!?,@%]+', Name.Function, '#pop'),
+            (r'\.', Punctuation, '#pop'),
+            (r';', Punctuation),
+            (r'[\])}]', Text),
+            (r'[\[({]', Text, '#pop'),
+        ],
+        'squeak fileout': [
+            # Squeak fileout format (optional)
+            (r'^"(""|[^"])*"!', Keyword),
+            (r"^'(''|[^'])*'!", Keyword),
+            (r'^(!)(\w+)( commentStamp: )(.*?)( prior: .*?!\n)(.*?)(!)',
+                bygroups(Keyword, Name.Class, Keyword, String, Keyword, Text, Keyword)),
+            (r"^(!)(\w+(?: class)?)( methodsFor: )('(?:''|[^'])*')(.*?!)",
+                bygroups(Keyword, Name.Class, Keyword, String, Keyword)),
+            (r'^(\w+)( subclass: )(#\w+)'
+             r'(\s+instanceVariableNames: )(.*?)'
+             r'(\s+classVariableNames: )(.*?)'
+             r'(\s+poolDictionaries: )(.*?)'
+             r'(\s+category: )(.*?)(!)',
+                bygroups(Name.Class, Keyword, String.Symbol, Keyword, String, Keyword,
+                         String, Keyword, String, Keyword, String, Keyword)),
+            (r'^(\w+(?: class)?)(\s+instanceVariableNames: )(.*?)(!)',
+                bygroups(Name.Class, Keyword, String, Keyword)),
+            (r'(!\n)(\].*)(! !)$', bygroups(Keyword, Text, Keyword)),
+            (r'! !$', Keyword),
+        ],
+    }
+
+
+class NewspeakLexer(RegexLexer):
+    """
+    For Newspeak syntax.
+    """
+    name = 'Newspeak'
+    url = 'http://newspeaklanguage.org/'
+    filenames = ['*.ns2']
+    aliases = ['newspeak', ]
+    mimetypes = ['text/x-newspeak']
+    version_added = '1.1'
+
+    tokens = {
+        'root': [
+            (r'\b(Newsqueak2)\b', Keyword.Declaration),
+            (r"'[^']*'", String),
+            (r'\b(class)(\s+)(\w+)(\s*)',
+             bygroups(Keyword.Declaration, Text, Name.Class, Text)),
+            (r'\b(mixin|self|super|private|public|protected|nil|true|false)\b',
+             Keyword),
+            (r'(\w+\:)(\s*)([a-zA-Z_]\w+)',
+             bygroups(Name.Function, Text, Name.Variable)),
+            (r'(\w+)(\s*)(=)',
+             bygroups(Name.Attribute, Text, Operator)),
+            (r'<\w+>', Comment.Special),
+            include('expressionstat'),
+            include('whitespace')
+        ],
+
+        'expressionstat': [
+            (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
+            (r'\d+', Number.Integer),
+            (r':\w+', Name.Variable),
+            (r'(\w+)(::)', bygroups(Name.Variable, Operator)),
+            (r'\w+:', Name.Function),
+            (r'\w+', Name.Variable),
+            (r'\(|\)', Punctuation),
+            (r'\[|\]', Punctuation),
+            (r'\{|\}', Punctuation),
+
+            (r'(\^|\+|\/|~|\*|<|>|=|@|%|\||&|\?|!|,|-|:)', Operator),
+            (r'\.|;', Punctuation),
+            include('whitespace'),
+            include('literals'),
+        ],
+        'literals': [
+            (r'\$.', String),
+            (r"'[^']*'", String),
+            (r"#'[^']*'", String.Symbol),
+            (r"#\w+:?", String.Symbol),
+            (r"#(\+|\/|~|\*|<|>|=|@|%|\||&|\?|!|,|-)+", String.Symbol)
+        ],
+        'whitespace': [
+            (r'\s+', Text),
+            (r'"[^"]*"', Comment)
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/smithy.py b/.venv/Lib/site-packages/pygments/lexers/smithy.py
new file mode 100644
index 0000000..bd479ae
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/smithy.py
@@ -0,0 +1,77 @@
+"""
+    pygments.lexers.smithy
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the Smithy IDL.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, words
+from pygments.token import Text, Comment, Keyword, Name, String, \
+    Number, Whitespace, Punctuation
+
+__all__ = ['SmithyLexer']
+
+
+class SmithyLexer(RegexLexer):
+    """
+    For Smithy IDL
+    """
+    name = 'Smithy'
+    url = 'https://awslabs.github.io/smithy/'
+    filenames = ['*.smithy']
+    aliases = ['smithy']
+    version_added = '2.10'
+
+    unquoted = r'[A-Za-z0-9_\.#$-]+'
+    identifier = r"[A-Za-z0-9_\.#$-]+"
+
+    simple_shapes = (
+        'use', 'byte', 'short', 'integer', 'long', 'float', 'document',
+        'double', 'bigInteger', 'bigDecimal', 'boolean', 'blob', 'string',
+        'timestamp',
+    )
+
+    aggregate_shapes = (
+       'apply', 'list', 'map', 'set', 'structure', 'union', 'resource',
+       'operation', 'service', 'trait'
+    )
+
+    tokens = {
+        'root': [
+            (r'///.*$', Comment.Multiline),
+            (r'//.*$', Comment),
+            (r'@[0-9a-zA-Z\.#-]*', Name.Decorator),
+            (r'(=)', Name.Decorator),
+            (r'^(\$version)(:)(.+)',
+                bygroups(Keyword.Declaration, Name.Decorator, Name.Class)),
+            (r'^(namespace)(\s+' + identifier + r')\b',
+                bygroups(Keyword.Declaration, Name.Class)),
+            (words(simple_shapes,
+                   prefix=r'^', suffix=r'(\s+' + identifier + r')\b'),
+                bygroups(Keyword.Declaration, Name.Class)),
+            (words(aggregate_shapes,
+                   prefix=r'^', suffix=r'(\s+' + identifier + r')'),
+                bygroups(Keyword.Declaration, Name.Class)),
+            (r'^(metadata)(\s+)((?:\S+)|(?:\"[^"]+\"))(\s*)(=)',
+                bygroups(Keyword.Declaration, Whitespace, Name.Class,
+                         Whitespace, Name.Decorator)),
+            (r"(true|false|null)", Keyword.Constant),
+            (r"(-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)", Number),
+            (identifier + ":", Name.Label),
+            (identifier, Name.Variable.Class),
+            (r'\[', Text, "#push"),
+            (r'\]', Text, "#pop"),
+            (r'\(', Text, "#push"),
+            (r'\)', Text, "#pop"),
+            (r'\{', Text, "#push"),
+            (r'\}', Text, "#pop"),
+            (r'"{3}(\\\\|\n|\\")*"{3}', String.Doc),
+            (r'"(\\\\|\n|\\"|[^"])*"', String.Double),
+            (r"'(\\\\|\n|\\'|[^'])*'", String.Single),
+            (r'[:,]+', Punctuation),
+            (r'\s+', Whitespace),
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/smv.py b/.venv/Lib/site-packages/pygments/lexers/smv.py
new file mode 100644
index 0000000..bf97b52
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/smv.py
@@ -0,0 +1,78 @@
+"""
+    pygments.lexers.smv
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the SMV languages.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, words
+from pygments.token import Comment, Keyword, Name, Number, Operator, \
+    Punctuation, Text
+
+__all__ = ['NuSMVLexer']
+
+
+class NuSMVLexer(RegexLexer):
+    """
+    Lexer for the NuSMV language.
+    """
+
+    name = 'NuSMV'
+    aliases = ['nusmv']
+    filenames = ['*.smv']
+    mimetypes = []
+    url = 'https://nusmv.fbk.eu'
+    version_added = '2.2'
+
+    tokens = {
+        'root': [
+            # Comments
+            (r'(?s)\/\-\-.*?\-\-/', Comment),
+            (r'--.*\n', Comment),
+
+            # Reserved
+            (words(('MODULE', 'DEFINE', 'MDEFINE', 'CONSTANTS', 'VAR', 'IVAR',
+                    'FROZENVAR', 'INIT', 'TRANS', 'INVAR', 'SPEC', 'CTLSPEC',
+                    'LTLSPEC', 'PSLSPEC', 'COMPUTE', 'NAME', 'INVARSPEC',
+                    'FAIRNESS', 'JUSTICE', 'COMPASSION', 'ISA', 'ASSIGN',
+                    'CONSTRAINT', 'SIMPWFF', 'CTLWFF', 'LTLWFF', 'PSLWFF',
+                    'COMPWFF', 'IN', 'MIN', 'MAX', 'MIRROR', 'PRED',
+                    'PREDICATES'), suffix=r'(?![\w$#-])'),
+             Keyword.Declaration),
+            (r'process(?![\w$#-])', Keyword),
+            (words(('array', 'of', 'boolean', 'integer', 'real', 'word'),
+                   suffix=r'(?![\w$#-])'), Keyword.Type),
+            (words(('case', 'esac'), suffix=r'(?![\w$#-])'), Keyword),
+            (words(('word1', 'bool', 'signed', 'unsigned', 'extend', 'resize',
+                    'sizeof', 'uwconst', 'swconst', 'init', 'self', 'count',
+                    'abs', 'max', 'min'), suffix=r'(?![\w$#-])'),
+             Name.Builtin),
+            (words(('EX', 'AX', 'EF', 'AF', 'EG', 'AG', 'E', 'F', 'O', 'G',
+                    'H', 'X', 'Y', 'Z', 'A', 'U', 'S', 'V', 'T', 'BU', 'EBF',
+                    'ABF', 'EBG', 'ABG', 'next', 'mod', 'union', 'in', 'xor',
+                    'xnor'), suffix=r'(?![\w$#-])'),
+                Operator.Word),
+            (words(('TRUE', 'FALSE'), suffix=r'(?![\w$#-])'), Keyword.Constant),
+
+            # Names
+            (r'[a-zA-Z_][\w$#-]*', Name.Variable),
+
+            # Operators
+            (r':=', Operator),
+            (r'[-&|+*/<>!=]', Operator),
+
+            # Literals
+            (r'\-?\d+\b', Number.Integer),
+            (r'0[su][bB]\d*_[01_]+', Number.Bin),
+            (r'0[su][oO]\d*_[0-7_]+', Number.Oct),
+            (r'0[su][dD]\d*_[\d_]+', Number.Decimal),
+            (r'0[su][hH]\d*_[\da-fA-F_]+', Number.Hex),
+
+            # Whitespace, punctuation and the rest
+            (r'\s+', Text.Whitespace),
+            (r'[()\[\]{};?:.,]', Punctuation),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/snobol.py b/.venv/Lib/site-packages/pygments/lexers/snobol.py
new file mode 100644
index 0000000..bab51e9
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/snobol.py
@@ -0,0 +1,82 @@
+"""
+    pygments.lexers.snobol
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the SNOBOL language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation
+
+__all__ = ['SnobolLexer']
+
+
+class SnobolLexer(RegexLexer):
+    """
+    Lexer for the SNOBOL4 programming language.
+
+    Recognizes the common ASCII equivalents of the original SNOBOL4 operators.
+    Does not require spaces around binary operators.
+    """
+
+    name = "Snobol"
+    aliases = ["snobol"]
+    filenames = ['*.snobol']
+    mimetypes = ['text/x-snobol']
+    url = 'https://www.regressive.org/snobol4'
+    version_added = '1.5'
+
+    tokens = {
+        # root state, start of line
+        # comments, continuation lines, and directives start in column 1
+        # as do labels
+        'root': [
+            (r'\*.*\n', Comment),
+            (r'[+.] ', Punctuation, 'statement'),
+            (r'-.*\n', Comment),
+            (r'END\s*\n', Name.Label, 'heredoc'),
+            (r'[A-Za-z$][\w$]*', Name.Label, 'statement'),
+            (r'\s+', Text, 'statement'),
+        ],
+        # statement state, line after continuation or label
+        'statement': [
+            (r'\s*\n', Text, '#pop'),
+            (r'\s+', Text),
+            (r'(?<=[^\w.])(LT|LE|EQ|NE|GE|GT|INTEGER|IDENT|DIFFER|LGT|SIZE|'
+             r'REPLACE|TRIM|DUPL|REMDR|DATE|TIME|EVAL|APPLY|OPSYN|LOAD|UNLOAD|'
+             r'LEN|SPAN|BREAK|ANY|NOTANY|TAB|RTAB|REM|POS|RPOS|FAIL|FENCE|'
+             r'ABORT|ARB|ARBNO|BAL|SUCCEED|INPUT|OUTPUT|TERMINAL)(?=[^\w.])',
+             Name.Builtin),
+            (r'[A-Za-z][\w.]*', Name),
+            # ASCII equivalents of original operators
+            # | for the EBCDIC equivalent, ! likewise
+            # \ for EBCDIC negation
+            (r'\*\*|[?$.!%*/#+\-@|&\\=]', Operator),
+            (r'"[^"]*"', String),
+            (r"'[^']*'", String),
+            # Accept SPITBOL syntax for real numbers
+            # as well as Macro SNOBOL4
+            (r'[0-9]+(?=[^.EeDd])', Number.Integer),
+            (r'[0-9]+(\.[0-9]*)?([EDed][-+]?[0-9]+)?', Number.Float),
+            # Goto
+            (r':', Punctuation, 'goto'),
+            (r'[()<>,;]', Punctuation),
+        ],
+        # Goto block
+        'goto': [
+            (r'\s*\n', Text, "#pop:2"),
+            (r'\s+', Text),
+            (r'F|S', Keyword),
+            (r'(\()([A-Za-z][\w.]*)(\))',
+             bygroups(Punctuation, Name.Label, Punctuation))
+        ],
+        # everything after the END statement is basically one
+        # big heredoc.
+        'heredoc': [
+            (r'.*\n', String.Heredoc)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/solidity.py b/.venv/Lib/site-packages/pygments/lexers/solidity.py
new file mode 100644
index 0000000..3182a14
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/solidity.py
@@ -0,0 +1,87 @@
+"""
+    pygments.lexers.solidity
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Solidity.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, include, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Whitespace
+
+__all__ = ['SolidityLexer']
+
+
+class SolidityLexer(RegexLexer):
+    """
+    For Solidity source code.
+    """
+
+    name = 'Solidity'
+    aliases = ['solidity']
+    filenames = ['*.sol']
+    mimetypes = []
+    url = 'https://soliditylang.org'
+    version_added = '2.5'
+
+    datatype = (
+        r'\b(address|bool|(?:(?:bytes|hash|int|string|uint)(?:8|16|24|32|40|48|56|64'
+        r'|72|80|88|96|104|112|120|128|136|144|152|160|168|176|184|192|200|208'
+        r'|216|224|232|240|248|256)?))\b'
+    )
+
+    tokens = {
+        'root': [
+            include('whitespace'),
+            include('comments'),
+            (r'\bpragma\s+solidity\b', Keyword, 'pragma'),
+            (r'\b(contract)(\s+)([a-zA-Z_]\w*)',
+             bygroups(Keyword, Whitespace, Name.Entity)),
+            (datatype + r'(\s+)((?:external|public|internal|private)\s+)?' +
+             r'([a-zA-Z_]\w*)',
+             bygroups(Keyword.Type, Whitespace, Keyword, Name.Variable)),
+            (r'\b(enum|event|function|struct)(\s+)([a-zA-Z_]\w*)',
+             bygroups(Keyword.Type, Whitespace, Name.Variable)),
+            (r'\b(msg|block|tx)\.([A-Za-z_][a-zA-Z0-9_]*)\b', Keyword),
+            (words((
+                'block', 'break', 'constant', 'constructor', 'continue',
+                'contract', 'do', 'else', 'external', 'false', 'for',
+                'function', 'if', 'import', 'inherited', 'internal', 'is',
+                'library', 'mapping', 'memory', 'modifier', 'msg', 'new',
+                'payable', 'private', 'public', 'require', 'return',
+                'returns', 'struct', 'suicide', 'throw', 'this', 'true',
+                'tx', 'var', 'while'), prefix=r'\b', suffix=r'\b'),
+             Keyword.Type),
+            (words(('keccak256',), prefix=r'\b', suffix=r'\b'), Name.Builtin),
+            (datatype, Keyword.Type),
+            include('constants'),
+            (r'[a-zA-Z_]\w*', Text),
+            (r'[~!%^&*+=|?:<>/-]', Operator),
+            (r'[.;{}(),\[\]]', Punctuation)
+        ],
+        'comments': [
+            (r'//(\n|[\w\W]*?[^\\]\n)', Comment.Single),
+            (r'/(\\\n)?[*][\w\W]*?[*](\\\n)?/', Comment.Multiline),
+            (r'/(\\\n)?[*][\w\W]*', Comment.Multiline)
+        ],
+        'constants': [
+            (r'("(\\"|.)*?")', String.Double),
+            (r"('(\\'|.)*?')", String.Single),
+            (r'\b0[xX][0-9a-fA-F]+\b', Number.Hex),
+            (r'\b\d+\b', Number.Decimal),
+        ],
+        'pragma': [
+            include('whitespace'),
+            include('comments'),
+            (r'(\^|>=|<)(\s*)(\d+\.\d+\.\d+)',
+             bygroups(Operator, Whitespace, Keyword)),
+            (r';', Punctuation, '#pop')
+        ],
+        'whitespace': [
+            (r'\s+', Whitespace),
+            (r'\n', Whitespace)
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/soong.py b/.venv/Lib/site-packages/pygments/lexers/soong.py
new file mode 100644
index 0000000..bbf204d
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/soong.py
@@ -0,0 +1,78 @@
+"""
+    pygments.lexers.soong
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for Soong (Android.bp Blueprint) files.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, include
+from pygments.token import Comment, Name, Number, Operator, Punctuation, \
+        String, Whitespace
+
+__all__ = ['SoongLexer']
+
+class SoongLexer(RegexLexer):
+    name = 'Soong'
+    version_added = '2.18'
+    url = 'https://source.android.com/docs/setup/reference/androidbp'
+    aliases = ['androidbp', 'bp', 'soong']
+    filenames = ['Android.bp']
+
+    tokens = {
+        'root': [
+            # A variable assignment
+            (r'(\w*)(\s*)(\+?=)(\s*)',
+             bygroups(Name.Variable, Whitespace, Operator, Whitespace),
+             'assign-rhs'),
+
+            # A top-level module
+            (r'(\w*)(\s*)(\{)',
+             bygroups(Name.Function, Whitespace, Punctuation),
+             'in-rule'),
+
+            # Everything else
+            include('comments'),
+            (r'\s+', Whitespace),  # newlines okay
+        ],
+        'assign-rhs': [
+            include('expr'),
+            (r'\n', Whitespace, '#pop'),
+        ],
+        'in-list': [
+            include('expr'),
+            include('comments'),
+            (r'\s+', Whitespace),  # newlines okay in a list
+            (r',', Punctuation),
+            (r'\]', Punctuation, '#pop'),
+        ],
+        'in-map': [
+            # A map key
+            (r'(\w+)(:)(\s*)', bygroups(Name, Punctuation, Whitespace)),
+
+            include('expr'),
+            include('comments'),
+            (r'\s+', Whitespace),  # newlines okay in a map
+            (r',', Punctuation),
+            (r'\}', Punctuation, '#pop'),
+        ],
+        'in-rule': [
+            # Just re-use map syntax
+            include('in-map'),
+        ],
+        'comments': [
+            (r'//.*', Comment.Single),
+            (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
+        ],
+        'expr': [
+            (r'(true|false)\b', Name.Builtin),
+            (r'0x[0-9a-fA-F]+', Number.Hex),
+            (r'\d+', Number.Integer),
+            (r'".*?"', String),
+            (r'\{', Punctuation, 'in-map'),
+            (r'\[', Punctuation, 'in-list'),
+            (r'\w+', Name),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/sophia.py b/.venv/Lib/site-packages/pygments/lexers/sophia.py
new file mode 100644
index 0000000..37fcec5
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/sophia.py
@@ -0,0 +1,102 @@
+"""
+    pygments.lexers.sophia
+    ~~~~~~~~~~~~~~~~~~~~~~
+
+    Lexer for Sophia.
+
+    Derived from pygments/lexers/reason.py.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, include, default, words
+from pygments.token import Comment, Keyword, Name, Number, Operator, \
+    Punctuation, String, Text
+
+__all__ = ['SophiaLexer']
+
+class SophiaLexer(RegexLexer):
+    """
+    A Sophia lexer.
+    """
+
+    name = 'Sophia'
+    aliases = ['sophia']
+    filenames = ['*.aes']
+    mimetypes = []
+    url = 'https://docs.aeternity.com/aesophia'
+    version_added = '2.11'
+
+    keywords = (
+        'contract', 'include', 'let', 'switch', 'type', 'record', 'datatype',
+        'if', 'elif', 'else', 'function', 'stateful', 'payable', 'public',
+        'entrypoint', 'private', 'indexed', 'namespace', 'interface', 'main',
+        'using', 'as', 'for', 'hiding',
+    )
+
+    builtins = ('state', 'put', 'abort', 'require')
+
+    word_operators = ('mod', 'band', 'bor', 'bxor', 'bnot')
+
+    primitive_types = ('int', 'address', 'bool', 'bits', 'bytes', 'string',
+                       'list', 'option', 'char', 'unit', 'map', 'event',
+                       'hash', 'signature', 'oracle', 'oracle_query')
+
+    tokens = {
+        'escape-sequence': [
+            (r'\\[\\"\'ntbr]', String.Escape),
+            (r'\\[0-9]{3}', String.Escape),
+            (r'\\x[0-9a-fA-F]{2}', String.Escape),
+        ],
+        'root': [
+            (r'\s+', Text.Whitespace),
+            (r'(true|false)\b', Keyword.Constant),
+            (r'\b([A-Z][\w\']*)(?=\s*\.)', Name.Class, 'dotted'),
+            (r'\b([A-Z][\w\']*)', Name.Function),
+            (r'//.*?\n', Comment.Single),
+            (r'\/\*(?!/)', Comment.Multiline, 'comment'),
+
+            (r'0[xX][\da-fA-F][\da-fA-F_]*', Number.Hex),
+            (r'#[\da-fA-F][\da-fA-F_]*', Name.Label),
+            (r'\d[\d_]*', Number.Integer),
+
+            (words(keywords, suffix=r'\b'), Keyword),
+            (words(builtins, suffix=r'\b'), Name.Builtin),
+            (words(word_operators, prefix=r'\b', suffix=r'\b'), Operator.Word),
+            (words(primitive_types, prefix=r'\b', suffix=r'\b'), Keyword.Type),
+
+            (r'[=!<>+\\*/:&|?~@^-]', Operator.Word),
+            (r'[.;:{}(),\[\]]', Punctuation),
+
+            (r"(ak_|ok_|oq_|ct_)[\w']*", Name.Label),
+            (r"[^\W\d][\w']*", Name),
+
+            (r"'(?:(\\[\\\"'ntbr ])|(\\[0-9]{3})|(\\x[0-9a-fA-F]{2}))'",
+             String.Char),
+            (r"'.'", String.Char),
+            (r"'[a-z][\w]*", Name.Variable),
+
+            (r'"', String.Double, 'string')
+        ],
+        'comment': [
+            (r'[^/*]+', Comment.Multiline),
+            (r'\/\*', Comment.Multiline, '#push'),
+            (r'\*\/', Comment.Multiline, '#pop'),
+            (r'\*', Comment.Multiline),
+        ],
+        'string': [
+            (r'[^\\"]+', String.Double),
+            include('escape-sequence'),
+            (r'\\\n', String.Double),
+            (r'"', String.Double, '#pop'),
+        ],
+        'dotted': [
+            (r'\s+', Text),
+            (r'\.', Punctuation),
+            (r'[A-Z][\w\']*(?=\s*\.)', Name.Function),
+            (r'[A-Z][\w\']*', Name.Function, '#pop'),
+            (r'[a-z_][\w\']*', Name, '#pop'),
+            default('#pop'),
+        ],
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/special.py b/.venv/Lib/site-packages/pygments/lexers/special.py
new file mode 100644
index 0000000..524946f
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/special.py
@@ -0,0 +1,122 @@
+"""
+    pygments.lexers.special
+    ~~~~~~~~~~~~~~~~~~~~~~~
+
+    Special lexers.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+import ast
+
+from pygments.lexer import Lexer, line_re
+from pygments.token import Token, Error, Text, Generic
+from pygments.util import get_choice_opt
+
+
+__all__ = ['TextLexer', 'OutputLexer', 'RawTokenLexer']
+
+
+class TextLexer(Lexer):
+    """
+    "Null" lexer, doesn't highlight anything.
+    """
+    name = 'Text only'
+    aliases = ['text']
+    filenames = ['*.txt']
+    mimetypes = ['text/plain']
+    url = ""
+    version_added = ''
+
+    priority = 0.01
+
+    def get_tokens_unprocessed(self, text):
+        yield 0, Text, text
+
+    def analyse_text(text):
+        return TextLexer.priority
+
+
+class OutputLexer(Lexer):
+    """
+    Simple lexer that highlights everything as ``Token.Generic.Output``.
+    """
+    name = 'Text output'
+    aliases = ['output']
+    url = ""
+    version_added = '2.10'
+    _example = "output/output"
+
+    def get_tokens_unprocessed(self, text):
+        yield 0, Generic.Output, text
+
+
+_ttype_cache = {}
+
+
+class RawTokenLexer(Lexer):
+    """
+    Recreate a token stream formatted with the `RawTokenFormatter`.
+
+    Additional options accepted:
+
+    `compress`
+        If set to ``"gz"`` or ``"bz2"``, decompress the token stream with
+        the given compression algorithm before lexing (default: ``""``).
+    """
+    name = 'Raw token data'
+    aliases = []
+    filenames = []
+    mimetypes = ['application/x-pygments-tokens']
+    url = 'https://pygments.org/docs/formatters/#RawTokenFormatter'
+    version_added = ''
+
+    def __init__(self, **options):
+        self.compress = get_choice_opt(options, 'compress',
+                                       ['', 'none', 'gz', 'bz2'], '')
+        Lexer.__init__(self, **options)
+
+    def get_tokens(self, text):
+        if self.compress:
+            if isinstance(text, str):
+                text = text.encode('latin1')
+            try:
+                if self.compress == 'gz':
+                    import gzip
+                    text = gzip.decompress(text)
+                elif self.compress == 'bz2':
+                    import bz2
+                    text = bz2.decompress(text)
+            except OSError:
+                yield Error, text.decode('latin1')
+        if isinstance(text, bytes):
+            text = text.decode('latin1')
+
+        # do not call Lexer.get_tokens() because stripping is not optional.
+        text = text.strip('\n') + '\n'
+        for i, t, v in self.get_tokens_unprocessed(text):
+            yield t, v
+
+    def get_tokens_unprocessed(self, text):
+        length = 0
+        for match in line_re.finditer(text):
+            try:
+                ttypestr, val = match.group().rstrip().split('\t', 1)
+                ttype = _ttype_cache.get(ttypestr)
+                if not ttype:
+                    ttype = Token
+                    ttypes = ttypestr.split('.')[1:]
+                    for ttype_ in ttypes:
+                        if not ttype_ or not ttype_[0].isupper():
+                            raise ValueError('malformed token name')
+                        ttype = getattr(ttype, ttype_)
+                    _ttype_cache[ttypestr] = ttype
+                val = ast.literal_eval(val)
+                if not isinstance(val, str):
+                    raise ValueError('expected str')
+            except (SyntaxError, ValueError):
+                val = match.group()
+                ttype = Error
+            yield length, ttype, val
+            length += len(val)
diff --git a/.venv/Lib/site-packages/pygments/lexers/spice.py b/.venv/Lib/site-packages/pygments/lexers/spice.py
new file mode 100644
index 0000000..9d2b1a1
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/spice.py
@@ -0,0 +1,70 @@
+"""
+    pygments.lexers.spice
+    ~~~~~~~~~~~~~~~~~~~~~
+
+    Lexers for the Spice programming language.
+
+    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from pygments.lexer import RegexLexer, bygroups, words
+from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
+    Number, Punctuation, Whitespace
+
+__all__ = ['SpiceLexer']
+
+
+class SpiceLexer(RegexLexer):
+    """
+    For Spice source.
+    """
+    name = 'Spice'
+    url = 'https://www.spicelang.com'
+    filenames = ['*.spice']
+    aliases = ['spice', 'spicelang']
+    mimetypes = ['text/x-spice']
+    version_added = '2.11'
+
+    tokens = {
+        'root': [
+            (r'\n', Whitespace),
+            (r'\s+', Whitespace),
+            (r'\\\n', Text),
+            # comments
+            (r'//(.*?)\n', Comment.Single),
+            (r'/(\\\n)?[*]{2}(.|\n)*?[*](\\\n)?/', String.Doc),
+            (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline),
+            # keywords
+            (r'(import|as)\b', Keyword.Namespace),
+            (r'(f|p|type|struct|interface|enum|alias|operator)\b', Keyword.Declaration),
+            (words(('if', 'else', 'switch', 'case', 'default', 'for', 'foreach', 'do',
+                    'while', 'break', 'continue', 'fallthrough', 'return', 'assert',
+                    'unsafe', 'ext'), suffix=r'\b'), Keyword),
+            (words(('const', 'signed', 'unsigned', 'inline', 'public', 'heap', 'compose'),
+                   suffix=r'\b'), Keyword.Pseudo),
+            (words(('new', 'yield', 'stash', 'pick', 'sync', 'class'), suffix=r'\b'),
+                   Keyword.Reserved),
+            (r'(true|false|nil)\b', Keyword.Constant),
+            (words(('double', 'int', 'short', 'long', 'byte', 'char', 'string',
+                    'bool', 'dyn'), suffix=r'\b'), Keyword.Type),
+            (words(('printf', 'sizeof', 'alignof', 'len', 'panic'), suffix=r'\b(\()'),
+             bygroups(Name.Builtin, Punctuation)),
+            # numeric literals
+            (r'[-]?[0-9]*[.][0-9]+([eE][+-]?[0-9]+)?', Number.Double),
+            (r'0[bB][01]+[slu]?', Number.Bin),
+            (r'0[oO][0-7]+[slu]?', Number.Oct),
+            (r'0[xXhH][0-9a-fA-F]+[slu]?', Number.Hex),
+            (r'(0[dD])?[0-9]+[slu]?', Number.Integer),
+            # string literal
+            (r'"(\\\\|\\[^\\]|[^"\\])*"', String),
+            # char literal
+            (r'\'(\\\\|\\[^\\]|[^\'\\])\'', String.Char),
+            # tokens
+            (r'<<=|>>=|<<|>>|<=|>=|\+=|-=|\*=|/=|\%=|\|=|&=|\^=|&&|\|\||&|\||'
+             r'\+\+|--|\%|\^|\~|==|!=|->|::|[.]{3}|#!|#|[+\-*/&]', Operator),
+            (r'[|<>=!()\[\]{}.,;:\?]', Punctuation),
+            # identifiers
+            (r'[^\W\d]\w*', Name.Other),
+        ]
+    }
diff --git a/.venv/Lib/site-packages/pygments/lexers/sql.py b/.venv/Lib/site-packages/pygments/lexers/sql.py
new file mode 100644
index 0000000..c3a11f4
--- /dev/null
+++ b/.venv/Lib/site-packages/pygments/lexers/sql.py
@@ -0,0 +1,1203 @@
+"""
+    pygments.lexers.sql
+    ~~~~~~~~~~~~~~~~~~~
+
+    Lexers for various SQL dialects and related interactive sessions.
+
+    Postgres specific lexers:
+
+    `PostgresLexer`
+        A SQL lexer for the PostgreSQL dialect. Differences w.r.t. the SQL
+        lexer are:
+
+        - keywords and data types list parsed from the PG docs (run the
+          `_postgres_builtins` module to update them);
+        - Content of $-strings parsed using a specific lexer, e.g. the content
+          of a PL/Python function is parsed using the Python lexer;
+        - parse PG specific constructs: E-strings, $-strings, U&-strings,
+          different operators and punctuation.
+
+    `PlPgsqlLexer`
+        A lexer for the PL/pgSQL language. Adds a few specific construct on
+        top of the PG SQL lexer (such as <{text}' if rule else text
+                    append(text)
+            else:
+                styles: Dict[str, int] = {}
+                for text, style, _ in Segment.filter_control(
+                    Segment.simplify(self._record_buffer)
+                ):
+                    text = escape(text)
+                    if style:
+                        rule = style.get_html_style(_theme)
+                        style_number = styles.setdefault(rule, len(styles) + 1)
+                        if style.link:
+                            text = f'{text}'
+                        else:
+                            text = f'{text}'
+                    append(text)
+                stylesheet_rules: List[str] = []
+                stylesheet_append = stylesheet_rules.append
+                for style_rule, style_number in styles.items():
+                    if style_rule:
+                        stylesheet_append(f".r{style_number} {{{style_rule}}}")
+                stylesheet = "\n".join(stylesheet_rules)
+
+            rendered_code = render_code_format.format(
+                code="".join(fragments),
+                stylesheet=stylesheet,
+                foreground=_theme.foreground_color.hex,
+                background=_theme.background_color.hex,
+            )
+            if clear:
+                del self._record_buffer[:]
+        return rendered_code
+
+    def save_html(
+        self,
+        path: str,
+        *,
+        theme: Optional[TerminalTheme] = None,
+        clear: bool = True,
+        code_format: str = CONSOLE_HTML_FORMAT,
+        inline_styles: bool = False,
+    ) -> None:
+        """Generate HTML from console contents and write to a file (requires record=True argument in constructor).
+
+        Args:
+            path (str): Path to write html file.
+            theme (TerminalTheme, optional): TerminalTheme object containing console colors.
+            clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``.
+            code_format (str, optional): Format string to render HTML. In addition to '{foreground}',
+                '{background}', and '{code}', should contain '{stylesheet}' if inline_styles is ``False``.
+            inline_styles (bool, optional): If ``True`` styles will be inlined in to spans, which makes files
+                larger but easier to cut and paste markup. If ``False``, styles will be embedded in a style tag.
+                Defaults to False.
+
+        """
+        html = self.export_html(
+            theme=theme,
+            clear=clear,
+            code_format=code_format,
+            inline_styles=inline_styles,
+        )
+        with open(path, "w", encoding="utf-8") as write_file:
+            write_file.write(html)
+
+    def export_svg(
+        self,
+        *,
+        title: str = "Rich",
+        theme: Optional[TerminalTheme] = None,
+        clear: bool = True,
+        code_format: str = CONSOLE_SVG_FORMAT,
+        font_aspect_ratio: float = 0.61,
+        unique_id: Optional[str] = None,
+    ) -> str:
+        """
+        Generate an SVG from the console contents (requires record=True in Console constructor).
+
+        Args:
+            title (str, optional): The title of the tab in the output image
+            theme (TerminalTheme, optional): The ``TerminalTheme`` object to use to style the terminal
+            clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``
+            code_format (str, optional): Format string used to generate the SVG. Rich will inject a number of variables
+                into the string in order to form the final SVG output. The default template used and the variables
+                injected by Rich can be found by inspecting the ``console.CONSOLE_SVG_FORMAT`` variable.
+            font_aspect_ratio (float, optional): The width to height ratio of the font used in the ``code_format``
+                string. Defaults to 0.61, which is the width to height ratio of Fira Code (the default font).
+                If you aren't specifying a different font inside ``code_format``, you probably don't need this.
+            unique_id (str, optional): unique id that is used as the prefix for various elements (CSS styles, node
+                ids). If not set, this defaults to a computed value based on the recorded content.
+        """
+
+        from rich.cells import cell_len
+
+        style_cache: Dict[Style, str] = {}
+
+        def get_svg_style(style: Style) -> str:
+            """Convert a Style to CSS rules for SVG."""
+            if style in style_cache:
+                return style_cache[style]
+            css_rules = []
+            color = (
+                _theme.foreground_color
+                if (style.color is None or style.color.is_default)
+                else style.color.get_truecolor(_theme)
+            )
+            bgcolor = (
+                _theme.background_color
+                if (style.bgcolor is None or style.bgcolor.is_default)
+                else style.bgcolor.get_truecolor(_theme)
+            )
+            if style.reverse:
+                color, bgcolor = bgcolor, color
+            if style.dim:
+                color = blend_rgb(color, bgcolor, 0.4)
+            css_rules.append(f"fill: {color.hex}")
+            if style.bold:
+                css_rules.append("font-weight: bold")
+            if style.italic:
+                css_rules.append("font-style: italic;")
+            if style.underline:
+                css_rules.append("text-decoration: underline;")
+            if style.strike:
+                css_rules.append("text-decoration: line-through;")
+
+            css = ";".join(css_rules)
+            style_cache[style] = css
+            return css
+
+        _theme = theme or SVG_EXPORT_THEME
+
+        width = self.width
+        char_height = 20
+        char_width = char_height * font_aspect_ratio
+        line_height = char_height * 1.22
+
+        margin_top = 1
+        margin_right = 1
+        margin_bottom = 1
+        margin_left = 1
+
+        padding_top = 40
+        padding_right = 8
+        padding_bottom = 8
+        padding_left = 8
+
+        padding_width = padding_left + padding_right
+        padding_height = padding_top + padding_bottom
+        margin_width = margin_left + margin_right
+        margin_height = margin_top + margin_bottom
+
+        text_backgrounds: List[str] = []
+        text_group: List[str] = []
+        classes: Dict[str, int] = {}
+        style_no = 1
+
+        def escape_text(text: str) -> str:
+            """HTML escape text and replace spaces with nbsp."""
+            return escape(text).replace(" ", " ")
+
+        def make_tag(
+            name: str, content: Optional[str] = None, **attribs: object
+        ) -> str:
+            """Make a tag from name, content, and attributes."""
+
+            def stringify(value: object) -> str:
+                if isinstance(value, (float)):
+                    return format(value, "g")
+                return str(value)
+
+            tag_attribs = " ".join(
+                f'{k.lstrip("_").replace("_", "-")}="{stringify(v)}"'
+                for k, v in attribs.items()
+            )
+            return (
+                f"<{name} {tag_attribs}>{content}"
+                if content
+                else f"<{name} {tag_attribs}/>"
+            )
+
+        with self._record_buffer_lock:
+            segments = list(Segment.filter_control(self._record_buffer))
+            if clear:
+                self._record_buffer.clear()
+
+        if unique_id is None:
+            unique_id = "terminal-" + str(
+                zlib.adler32(
+                    ("".join(repr(segment) for segment in segments)).encode(
+                        "utf-8",
+                        "ignore",
+                    )
+                    + title.encode("utf-8", "ignore")
+                )
+            )
+        y = 0
+        for y, line in enumerate(Segment.split_and_crop_lines(segments, length=width)):
+            x = 0
+            for text, style, _control in line:
+                style = style or Style()
+                rules = get_svg_style(style)
+                if rules not in classes:
+                    classes[rules] = style_no
+                    style_no += 1
+                class_name = f"r{classes[rules]}"
+
+                if style.reverse:
+                    has_background = True
+                    background = (
+                        _theme.foreground_color.hex
+                        if style.color is None
+                        else style.color.get_truecolor(_theme).hex
+                    )
+                else:
+                    bgcolor = style.bgcolor
+                    has_background = bgcolor is not None and not bgcolor.is_default
+                    background = (
+                        _theme.background_color.hex
+                        if style.bgcolor is None
+                        else style.bgcolor.get_truecolor(_theme).hex
+                    )
+
+                text_length = cell_len(text)
+                if has_background:
+                    text_backgrounds.append(
+                        make_tag(
+                            "rect",
+                            fill=background,
+                            x=x * char_width,
+                            y=y * line_height + 1.5,
+                            width=char_width * text_length,
+                            height=line_height + 0.25,
+                            shape_rendering="crispEdges",
+                        )
+                    )
+
+                if text != " " * len(text):
+                    text_group.append(
+                        make_tag(
+                            "text",
+                            escape_text(text),
+                            _class=f"{unique_id}-{class_name}",
+                            x=x * char_width,
+                            y=y * line_height + char_height,
+                            textLength=char_width * len(text),
+                            clip_path=f"url(#{unique_id}-line-{y})",
+                        )
+                    )
+                x += cell_len(text)
+
+        line_offsets = [line_no * line_height + 1.5 for line_no in range(y)]
+        lines = "\n".join(
+            f"""
+    {make_tag("rect", x=0, y=offset, width=char_width * width, height=line_height + 0.25)}
+            """
+            for line_no, offset in enumerate(line_offsets)
+        )
+
+        styles = "\n".join(
+            f".{unique_id}-r{rule_no} {{ {css} }}" for css, rule_no in classes.items()
+        )
+        backgrounds = "".join(text_backgrounds)
+        matrix = "".join(text_group)
+
+        terminal_width = ceil(width * char_width + padding_width)
+        terminal_height = (y + 1) * line_height + padding_height
+        chrome = make_tag(
+            "rect",
+            fill=_theme.background_color.hex,
+            stroke="rgba(255,255,255,0.35)",
+            stroke_width="1",
+            x=margin_left,
+            y=margin_top,
+            width=terminal_width,
+            height=terminal_height,
+            rx=8,
+        )
+
+        title_color = _theme.foreground_color.hex
+        if title:
+            chrome += make_tag(
+                "text",
+                escape_text(title),
+                _class=f"{unique_id}-title",
+                fill=title_color,
+                text_anchor="middle",
+                x=terminal_width // 2,
+                y=margin_top + char_height + 6,
+            )
+        chrome += f"""
+            
+            
+            
+            
+            
+        """
+
+        svg = code_format.format(
+            unique_id=unique_id,
+            char_width=char_width,
+            char_height=char_height,
+            line_height=line_height,
+            terminal_width=char_width * width - 1,
+            terminal_height=(y + 1) * line_height - 1,
+            width=terminal_width + margin_width,
+            height=terminal_height + margin_height,
+            terminal_x=margin_left + padding_left,
+            terminal_y=margin_top + padding_top,
+            styles=styles,
+            chrome=chrome,
+            backgrounds=backgrounds,
+            matrix=matrix,
+            lines=lines,
+        )
+        return svg
+
+    def save_svg(
+        self,
+        path: str,
+        *,
+        title: str = "Rich",
+        theme: Optional[TerminalTheme] = None,
+        clear: bool = True,
+        code_format: str = CONSOLE_SVG_FORMAT,
+        font_aspect_ratio: float = 0.61,
+        unique_id: Optional[str] = None,
+    ) -> None:
+        """Generate an SVG file from the console contents (requires record=True in Console constructor).
+
+        Args:
+            path (str): The path to write the SVG to.
+            title (str, optional): The title of the tab in the output image
+            theme (TerminalTheme, optional): The ``TerminalTheme`` object to use to style the terminal
+            clear (bool, optional): Clear record buffer after exporting. Defaults to ``True``
+            code_format (str, optional): Format string used to generate the SVG. Rich will inject a number of variables
+                into the string in order to form the final SVG output. The default template used and the variables
+                injected by Rich can be found by inspecting the ``console.CONSOLE_SVG_FORMAT`` variable.
+            font_aspect_ratio (float, optional): The width to height ratio of the font used in the ``code_format``
+                string. Defaults to 0.61, which is the width to height ratio of Fira Code (the default font).
+                If you aren't specifying a different font inside ``code_format``, you probably don't need this.
+            unique_id (str, optional): unique id that is used as the prefix for various elements (CSS styles, node
+                ids). If not set, this defaults to a computed value based on the recorded content.
+        """
+        svg = self.export_svg(
+            title=title,
+            theme=theme,
+            clear=clear,
+            code_format=code_format,
+            font_aspect_ratio=font_aspect_ratio,
+            unique_id=unique_id,
+        )
+        with open(path, "w", encoding="utf-8") as write_file:
+            write_file.write(svg)
+
+
+def _svg_hash(svg_main_code: str) -> str:
+    """Returns a unique hash for the given SVG main code.
+
+    Args:
+        svg_main_code (str): The content we're going to inject in the SVG envelope.
+
+    Returns:
+        str: a hash of the given content
+    """
+    return str(zlib.adler32(svg_main_code.encode()))
+
+
+if __name__ == "__main__":  # pragma: no cover
+    console = Console(record=True)
+
+    console.log(
+        "JSONRPC [i]request[/i]",
+        5,
+        1.3,
+        True,
+        False,
+        None,
+        {
+            "jsonrpc": "2.0",
+            "method": "subtract",
+            "params": {"minuend": 42, "subtrahend": 23},
+            "id": 3,
+        },
+    )
+
+    console.log("Hello, World!", "{'a': 1}", repr(console))
+
+    console.print(
+        {
+            "name": None,
+            "empty": [],
+            "quiz": {
+                "sport": {
+                    "answered": True,
+                    "q1": {
+                        "question": "Which one is correct team name in NBA?",
+                        "options": [
+                            "New York Bulls",
+                            "Los Angeles Kings",
+                            "Golden State Warriors",
+                            "Huston Rocket",
+                        ],
+                        "answer": "Huston Rocket",
+                    },
+                },
+                "maths": {
+                    "answered": False,
+                    "q1": {
+                        "question": "5 + 7 = ?",
+                        "options": [10, 11, 12, 13],
+                        "answer": 12,
+                    },
+                    "q2": {
+                        "question": "12 - 8 = ?",
+                        "options": [1, 2, 3, 4],
+                        "answer": 4,
+                    },
+                },
+            },
+        }
+    )
diff --git a/.venv/Lib/site-packages/rich/constrain.py b/.venv/Lib/site-packages/rich/constrain.py
new file mode 100644
index 0000000..65fdf56
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/constrain.py
@@ -0,0 +1,37 @@
+from typing import Optional, TYPE_CHECKING
+
+from .jupyter import JupyterMixin
+from .measure import Measurement
+
+if TYPE_CHECKING:
+    from .console import Console, ConsoleOptions, RenderableType, RenderResult
+
+
+class Constrain(JupyterMixin):
+    """Constrain the width of a renderable to a given number of characters.
+
+    Args:
+        renderable (RenderableType): A renderable object.
+        width (int, optional): The maximum width (in characters) to render. Defaults to 80.
+    """
+
+    def __init__(self, renderable: "RenderableType", width: Optional[int] = 80) -> None:
+        self.renderable = renderable
+        self.width = width
+
+    def __rich_console__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "RenderResult":
+        if self.width is None:
+            yield self.renderable
+        else:
+            child_options = options.update_width(min(self.width, options.max_width))
+            yield from console.render(self.renderable, child_options)
+
+    def __rich_measure__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "Measurement":
+        if self.width is not None:
+            options = options.update_width(self.width)
+        measurement = Measurement.get(console, options, self.renderable)
+        return measurement
diff --git a/.venv/Lib/site-packages/rich/containers.py b/.venv/Lib/site-packages/rich/containers.py
new file mode 100644
index 0000000..901ff8b
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/containers.py
@@ -0,0 +1,167 @@
+from itertools import zip_longest
+from typing import (
+    TYPE_CHECKING,
+    Iterable,
+    Iterator,
+    List,
+    Optional,
+    TypeVar,
+    Union,
+    overload,
+)
+
+if TYPE_CHECKING:
+    from .console import (
+        Console,
+        ConsoleOptions,
+        JustifyMethod,
+        OverflowMethod,
+        RenderResult,
+        RenderableType,
+    )
+    from .text import Text
+
+from .cells import cell_len
+from .measure import Measurement
+
+T = TypeVar("T")
+
+
+class Renderables:
+    """A list subclass which renders its contents to the console."""
+
+    def __init__(
+        self, renderables: Optional[Iterable["RenderableType"]] = None
+    ) -> None:
+        self._renderables: List["RenderableType"] = (
+            list(renderables) if renderables is not None else []
+        )
+
+    def __rich_console__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "RenderResult":
+        """Console render method to insert line-breaks."""
+        yield from self._renderables
+
+    def __rich_measure__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "Measurement":
+        dimensions = [
+            Measurement.get(console, options, renderable)
+            for renderable in self._renderables
+        ]
+        if not dimensions:
+            return Measurement(1, 1)
+        _min = max(dimension.minimum for dimension in dimensions)
+        _max = max(dimension.maximum for dimension in dimensions)
+        return Measurement(_min, _max)
+
+    def append(self, renderable: "RenderableType") -> None:
+        self._renderables.append(renderable)
+
+    def __iter__(self) -> Iterable["RenderableType"]:
+        return iter(self._renderables)
+
+
+class Lines:
+    """A list subclass which can render to the console."""
+
+    def __init__(self, lines: Iterable["Text"] = ()) -> None:
+        self._lines: List["Text"] = list(lines)
+
+    def __repr__(self) -> str:
+        return f"Lines({self._lines!r})"
+
+    def __iter__(self) -> Iterator["Text"]:
+        return iter(self._lines)
+
+    @overload
+    def __getitem__(self, index: int) -> "Text":
+        ...
+
+    @overload
+    def __getitem__(self, index: slice) -> List["Text"]:
+        ...
+
+    def __getitem__(self, index: Union[slice, int]) -> Union["Text", List["Text"]]:
+        return self._lines[index]
+
+    def __setitem__(self, index: int, value: "Text") -> "Lines":
+        self._lines[index] = value
+        return self
+
+    def __len__(self) -> int:
+        return self._lines.__len__()
+
+    def __rich_console__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "RenderResult":
+        """Console render method to insert line-breaks."""
+        yield from self._lines
+
+    def append(self, line: "Text") -> None:
+        self._lines.append(line)
+
+    def extend(self, lines: Iterable["Text"]) -> None:
+        self._lines.extend(lines)
+
+    def pop(self, index: int = -1) -> "Text":
+        return self._lines.pop(index)
+
+    def justify(
+        self,
+        console: "Console",
+        width: int,
+        justify: "JustifyMethod" = "left",
+        overflow: "OverflowMethod" = "fold",
+    ) -> None:
+        """Justify and overflow text to a given width.
+
+        Args:
+            console (Console): Console instance.
+            width (int): Number of cells available per line.
+            justify (str, optional): Default justify method for text: "left", "center", "full" or "right". Defaults to "left".
+            overflow (str, optional): Default overflow for text: "crop", "fold", or "ellipsis". Defaults to "fold".
+
+        """
+        from .text import Text
+
+        if justify == "left":
+            for line in self._lines:
+                line.truncate(width, overflow=overflow, pad=True)
+        elif justify == "center":
+            for line in self._lines:
+                line.rstrip()
+                line.truncate(width, overflow=overflow)
+                line.pad_left((width - cell_len(line.plain)) // 2)
+                line.pad_right(width - cell_len(line.plain))
+        elif justify == "right":
+            for line in self._lines:
+                line.rstrip()
+                line.truncate(width, overflow=overflow)
+                line.pad_left(width - cell_len(line.plain))
+        elif justify == "full":
+            for line_index, line in enumerate(self._lines):
+                if line_index == len(self._lines) - 1:
+                    break
+                words = line.split(" ")
+                words_size = sum(cell_len(word.plain) for word in words)
+                num_spaces = len(words) - 1
+                spaces = [1 for _ in range(num_spaces)]
+                index = 0
+                if spaces:
+                    while words_size + num_spaces < width:
+                        spaces[len(spaces) - index - 1] += 1
+                        num_spaces += 1
+                        index = (index + 1) % len(spaces)
+                tokens: List[Text] = []
+                for index, (word, next_word) in enumerate(
+                    zip_longest(words, words[1:])
+                ):
+                    tokens.append(word)
+                    if index < len(spaces):
+                        style = word.get_style_at_offset(console, -1)
+                        next_style = next_word.get_style_at_offset(console, 0)
+                        space_style = style if style == next_style else line.style
+                        tokens.append(Text(" " * spaces[index], style=space_style))
+                self[line_index] = Text("").join(tokens)
diff --git a/.venv/Lib/site-packages/rich/control.py b/.venv/Lib/site-packages/rich/control.py
new file mode 100644
index 0000000..a8a9125
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/control.py
@@ -0,0 +1,225 @@
+import sys
+import time
+from typing import TYPE_CHECKING, Callable, Dict, Iterable, List, Union
+
+if sys.version_info >= (3, 8):
+    from typing import Final
+else:
+    from typing_extensions import Final  # pragma: no cover
+
+from .segment import ControlCode, ControlType, Segment
+
+if TYPE_CHECKING:
+    from .console import Console, ConsoleOptions, RenderResult
+
+STRIP_CONTROL_CODES: Final = [
+    7,  # Bell
+    8,  # Backspace
+    11,  # Vertical tab
+    12,  # Form feed
+    13,  # Carriage return
+]
+_CONTROL_STRIP_TRANSLATE: Final = {
+    _codepoint: None for _codepoint in STRIP_CONTROL_CODES
+}
+
+CONTROL_ESCAPE: Final = {
+    7: "\\a",
+    8: "\\b",
+    11: "\\v",
+    12: "\\f",
+    13: "\\r",
+}
+
+CONTROL_CODES_FORMAT: Dict[int, Callable[..., str]] = {
+    ControlType.BELL: lambda: "\x07",
+    ControlType.CARRIAGE_RETURN: lambda: "\r",
+    ControlType.HOME: lambda: "\x1b[H",
+    ControlType.CLEAR: lambda: "\x1b[2J",
+    ControlType.ENABLE_ALT_SCREEN: lambda: "\x1b[?1049h",
+    ControlType.DISABLE_ALT_SCREEN: lambda: "\x1b[?1049l",
+    ControlType.SHOW_CURSOR: lambda: "\x1b[?25h",
+    ControlType.HIDE_CURSOR: lambda: "\x1b[?25l",
+    ControlType.CURSOR_UP: lambda param: f"\x1b[{param}A",
+    ControlType.CURSOR_DOWN: lambda param: f"\x1b[{param}B",
+    ControlType.CURSOR_FORWARD: lambda param: f"\x1b[{param}C",
+    ControlType.CURSOR_BACKWARD: lambda param: f"\x1b[{param}D",
+    ControlType.CURSOR_MOVE_TO_COLUMN: lambda param: f"\x1b[{param+1}G",
+    ControlType.ERASE_IN_LINE: lambda param: f"\x1b[{param}K",
+    ControlType.CURSOR_MOVE_TO: lambda x, y: f"\x1b[{y+1};{x+1}H",
+    ControlType.SET_WINDOW_TITLE: lambda title: f"\x1b]0;{title}\x07",
+}
+
+
+class Control:
+    """A renderable that inserts a control code (non printable but may move cursor).
+
+    Args:
+        *codes (str): Positional arguments are either a :class:`~rich.segment.ControlType` enum or a
+            tuple of ControlType and an integer parameter
+    """
+
+    __slots__ = ["segment"]
+
+    def __init__(self, *codes: Union[ControlType, ControlCode]) -> None:
+        control_codes: List[ControlCode] = [
+            (code,) if isinstance(code, ControlType) else code for code in codes
+        ]
+        _format_map = CONTROL_CODES_FORMAT
+        rendered_codes = "".join(
+            _format_map[code](*parameters) for code, *parameters in control_codes
+        )
+        self.segment = Segment(rendered_codes, None, control_codes)
+
+    @classmethod
+    def bell(cls) -> "Control":
+        """Ring the 'bell'."""
+        return cls(ControlType.BELL)
+
+    @classmethod
+    def home(cls) -> "Control":
+        """Move cursor to 'home' position."""
+        return cls(ControlType.HOME)
+
+    @classmethod
+    def move(cls, x: int = 0, y: int = 0) -> "Control":
+        """Move cursor relative to current position.
+
+        Args:
+            x (int): X offset.
+            y (int): Y offset.
+
+        Returns:
+            ~Control: Control object.
+
+        """
+
+        def get_codes() -> Iterable[ControlCode]:
+            control = ControlType
+            if x:
+                yield (
+                    control.CURSOR_FORWARD if x > 0 else control.CURSOR_BACKWARD,
+                    abs(x),
+                )
+            if y:
+                yield (
+                    control.CURSOR_DOWN if y > 0 else control.CURSOR_UP,
+                    abs(y),
+                )
+
+        control = cls(*get_codes())
+        return control
+
+    @classmethod
+    def move_to_column(cls, x: int, y: int = 0) -> "Control":
+        """Move to the given column, optionally add offset to row.
+
+        Returns:
+            x (int): absolute x (column)
+            y (int): optional y offset (row)
+
+        Returns:
+            ~Control: Control object.
+        """
+
+        return (
+            cls(
+                (ControlType.CURSOR_MOVE_TO_COLUMN, x),
+                (
+                    ControlType.CURSOR_DOWN if y > 0 else ControlType.CURSOR_UP,
+                    abs(y),
+                ),
+            )
+            if y
+            else cls((ControlType.CURSOR_MOVE_TO_COLUMN, x))
+        )
+
+    @classmethod
+    def move_to(cls, x: int, y: int) -> "Control":
+        """Move cursor to absolute position.
+
+        Args:
+            x (int): x offset (column)
+            y (int): y offset (row)
+
+        Returns:
+            ~Control: Control object.
+        """
+        return cls((ControlType.CURSOR_MOVE_TO, x, y))
+
+    @classmethod
+    def clear(cls) -> "Control":
+        """Clear the screen."""
+        return cls(ControlType.CLEAR)
+
+    @classmethod
+    def show_cursor(cls, show: bool) -> "Control":
+        """Show or hide the cursor."""
+        return cls(ControlType.SHOW_CURSOR if show else ControlType.HIDE_CURSOR)
+
+    @classmethod
+    def alt_screen(cls, enable: bool) -> "Control":
+        """Enable or disable alt screen."""
+        if enable:
+            return cls(ControlType.ENABLE_ALT_SCREEN, ControlType.HOME)
+        else:
+            return cls(ControlType.DISABLE_ALT_SCREEN)
+
+    @classmethod
+    def title(cls, title: str) -> "Control":
+        """Set the terminal window title
+
+        Args:
+            title (str): The new terminal window title
+        """
+        return cls((ControlType.SET_WINDOW_TITLE, title))
+
+    def __str__(self) -> str:
+        return self.segment.text
+
+    def __rich_console__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "RenderResult":
+        if self.segment.text:
+            yield self.segment
+
+
+def strip_control_codes(
+    text: str, _translate_table: Dict[int, None] = _CONTROL_STRIP_TRANSLATE
+) -> str:
+    """Remove control codes from text.
+
+    Args:
+        text (str): A string possibly contain control codes.
+
+    Returns:
+        str: String with control codes removed.
+    """
+    return text.translate(_translate_table)
+
+
+def escape_control_codes(
+    text: str,
+    _translate_table: Dict[int, str] = CONTROL_ESCAPE,
+) -> str:
+    """Replace control codes with their "escaped" equivalent in the given text.
+    (e.g. "\b" becomes "\\b")
+
+    Args:
+        text (str): A string possibly containing control codes.
+
+    Returns:
+        str: String with control codes replaced with their escaped version.
+    """
+    return text.translate(_translate_table)
+
+
+if __name__ == "__main__":  # pragma: no cover
+    from rich.console import Console
+
+    console = Console()
+    console.print("Look at the title of your terminal window ^")
+    # console.print(Control((ControlType.SET_WINDOW_TITLE, "Hello, world!")))
+    for i in range(10):
+        console.set_window_title("🚀 Loading" + "." * i)
+        time.sleep(0.5)
diff --git a/.venv/Lib/site-packages/rich/default_styles.py b/.venv/Lib/site-packages/rich/default_styles.py
new file mode 100644
index 0000000..3a0ad83
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/default_styles.py
@@ -0,0 +1,193 @@
+from typing import Dict
+
+from .style import Style
+
+DEFAULT_STYLES: Dict[str, Style] = {
+    "none": Style.null(),
+    "reset": Style(
+        color="default",
+        bgcolor="default",
+        dim=False,
+        bold=False,
+        italic=False,
+        underline=False,
+        blink=False,
+        blink2=False,
+        reverse=False,
+        conceal=False,
+        strike=False,
+    ),
+    "dim": Style(dim=True),
+    "bright": Style(dim=False),
+    "bold": Style(bold=True),
+    "strong": Style(bold=True),
+    "code": Style(reverse=True, bold=True),
+    "italic": Style(italic=True),
+    "emphasize": Style(italic=True),
+    "underline": Style(underline=True),
+    "blink": Style(blink=True),
+    "blink2": Style(blink2=True),
+    "reverse": Style(reverse=True),
+    "strike": Style(strike=True),
+    "black": Style(color="black"),
+    "red": Style(color="red"),
+    "green": Style(color="green"),
+    "yellow": Style(color="yellow"),
+    "magenta": Style(color="magenta"),
+    "cyan": Style(color="cyan"),
+    "white": Style(color="white"),
+    "inspect.attr": Style(color="yellow", italic=True),
+    "inspect.attr.dunder": Style(color="yellow", italic=True, dim=True),
+    "inspect.callable": Style(bold=True, color="red"),
+    "inspect.async_def": Style(italic=True, color="bright_cyan"),
+    "inspect.def": Style(italic=True, color="bright_cyan"),
+    "inspect.class": Style(italic=True, color="bright_cyan"),
+    "inspect.error": Style(bold=True, color="red"),
+    "inspect.equals": Style(),
+    "inspect.help": Style(color="cyan"),
+    "inspect.doc": Style(dim=True),
+    "inspect.value.border": Style(color="green"),
+    "live.ellipsis": Style(bold=True, color="red"),
+    "layout.tree.row": Style(dim=False, color="red"),
+    "layout.tree.column": Style(dim=False, color="blue"),
+    "logging.keyword": Style(bold=True, color="yellow"),
+    "logging.level.notset": Style(dim=True),
+    "logging.level.debug": Style(color="green"),
+    "logging.level.info": Style(color="blue"),
+    "logging.level.warning": Style(color="yellow"),
+    "logging.level.error": Style(color="red", bold=True),
+    "logging.level.critical": Style(color="red", bold=True, reverse=True),
+    "log.level": Style.null(),
+    "log.time": Style(color="cyan", dim=True),
+    "log.message": Style.null(),
+    "log.path": Style(dim=True),
+    "repr.ellipsis": Style(color="yellow"),
+    "repr.indent": Style(color="green", dim=True),
+    "repr.error": Style(color="red", bold=True),
+    "repr.str": Style(color="green", italic=False, bold=False),
+    "repr.brace": Style(bold=True),
+    "repr.comma": Style(bold=True),
+    "repr.ipv4": Style(bold=True, color="bright_green"),
+    "repr.ipv6": Style(bold=True, color="bright_green"),
+    "repr.eui48": Style(bold=True, color="bright_green"),
+    "repr.eui64": Style(bold=True, color="bright_green"),
+    "repr.tag_start": Style(bold=True),
+    "repr.tag_name": Style(color="bright_magenta", bold=True),
+    "repr.tag_contents": Style(color="default"),
+    "repr.tag_end": Style(bold=True),
+    "repr.attrib_name": Style(color="yellow", italic=False),
+    "repr.attrib_equal": Style(bold=True),
+    "repr.attrib_value": Style(color="magenta", italic=False),
+    "repr.number": Style(color="cyan", bold=True, italic=False),
+    "repr.number_complex": Style(color="cyan", bold=True, italic=False),  # same
+    "repr.bool_true": Style(color="bright_green", italic=True),
+    "repr.bool_false": Style(color="bright_red", italic=True),
+    "repr.none": Style(color="magenta", italic=True),
+    "repr.url": Style(underline=True, color="bright_blue", italic=False, bold=False),
+    "repr.uuid": Style(color="bright_yellow", bold=False),
+    "repr.call": Style(color="magenta", bold=True),
+    "repr.path": Style(color="magenta"),
+    "repr.filename": Style(color="bright_magenta"),
+    "rule.line": Style(color="bright_green"),
+    "rule.text": Style.null(),
+    "json.brace": Style(bold=True),
+    "json.bool_true": Style(color="bright_green", italic=True),
+    "json.bool_false": Style(color="bright_red", italic=True),
+    "json.null": Style(color="magenta", italic=True),
+    "json.number": Style(color="cyan", bold=True, italic=False),
+    "json.str": Style(color="green", italic=False, bold=False),
+    "json.key": Style(color="blue", bold=True),
+    "prompt": Style.null(),
+    "prompt.choices": Style(color="magenta", bold=True),
+    "prompt.default": Style(color="cyan", bold=True),
+    "prompt.invalid": Style(color="red"),
+    "prompt.invalid.choice": Style(color="red"),
+    "pretty": Style.null(),
+    "scope.border": Style(color="blue"),
+    "scope.key": Style(color="yellow", italic=True),
+    "scope.key.special": Style(color="yellow", italic=True, dim=True),
+    "scope.equals": Style(color="red"),
+    "table.header": Style(bold=True),
+    "table.footer": Style(bold=True),
+    "table.cell": Style.null(),
+    "table.title": Style(italic=True),
+    "table.caption": Style(italic=True, dim=True),
+    "traceback.error": Style(color="red", italic=True),
+    "traceback.border.syntax_error": Style(color="bright_red"),
+    "traceback.border": Style(color="red"),
+    "traceback.text": Style.null(),
+    "traceback.title": Style(color="red", bold=True),
+    "traceback.exc_type": Style(color="bright_red", bold=True),
+    "traceback.exc_value": Style.null(),
+    "traceback.offset": Style(color="bright_red", bold=True),
+    "traceback.error_range": Style(underline=True, bold=True),
+    "traceback.note": Style(color="green", bold=True),
+    "traceback.group.border": Style(color="magenta"),
+    "bar.back": Style(color="grey23"),
+    "bar.complete": Style(color="rgb(249,38,114)"),
+    "bar.finished": Style(color="rgb(114,156,31)"),
+    "bar.pulse": Style(color="rgb(249,38,114)"),
+    "progress.description": Style.null(),
+    "progress.filesize": Style(color="green"),
+    "progress.filesize.total": Style(color="green"),
+    "progress.download": Style(color="green"),
+    "progress.elapsed": Style(color="yellow"),
+    "progress.percentage": Style(color="magenta"),
+    "progress.remaining": Style(color="cyan"),
+    "progress.data.speed": Style(color="red"),
+    "progress.spinner": Style(color="green"),
+    "status.spinner": Style(color="green"),
+    "tree": Style(),
+    "tree.line": Style(),
+    "markdown.paragraph": Style(),
+    "markdown.text": Style(),
+    "markdown.em": Style(italic=True),
+    "markdown.emph": Style(italic=True),  # For commonmark backwards compatibility
+    "markdown.strong": Style(bold=True),
+    "markdown.code": Style(bold=True, color="cyan", bgcolor="black"),
+    "markdown.code_block": Style(color="cyan", bgcolor="black"),
+    "markdown.block_quote": Style(color="magenta"),
+    "markdown.list": Style(color="cyan"),
+    "markdown.item": Style(),
+    "markdown.item.bullet": Style(color="yellow", bold=True),
+    "markdown.item.number": Style(color="yellow", bold=True),
+    "markdown.hr": Style(color="yellow"),
+    "markdown.h1.border": Style(),
+    "markdown.h1": Style(bold=True),
+    "markdown.h2": Style(bold=True, underline=True),
+    "markdown.h3": Style(bold=True),
+    "markdown.h4": Style(bold=True, dim=True),
+    "markdown.h5": Style(underline=True),
+    "markdown.h6": Style(italic=True),
+    "markdown.h7": Style(italic=True, dim=True),
+    "markdown.link": Style(color="bright_blue"),
+    "markdown.link_url": Style(color="blue", underline=True),
+    "markdown.s": Style(strike=True),
+    "iso8601.date": Style(color="blue"),
+    "iso8601.time": Style(color="magenta"),
+    "iso8601.timezone": Style(color="yellow"),
+}
+
+
+if __name__ == "__main__":  # pragma: no cover
+    import argparse
+    import io
+
+    from rich.console import Console
+    from rich.table import Table
+    from rich.text import Text
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--html", action="store_true", help="Export as HTML table")
+    args = parser.parse_args()
+    html: bool = args.html
+    console = Console(record=True, width=70, file=io.StringIO()) if html else Console()
+
+    table = Table("Name", "Styling")
+
+    for style_name, style in DEFAULT_STYLES.items():
+        table.add_row(Text(style_name, style=style), str(style))
+
+    console.print(table)
+    if html:
+        print(console.export_html(inline_styles=True))
diff --git a/.venv/Lib/site-packages/rich/diagnose.py b/.venv/Lib/site-packages/rich/diagnose.py
new file mode 100644
index 0000000..5d16387
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/diagnose.py
@@ -0,0 +1,38 @@
+import os
+import platform
+
+from rich import inspect
+from rich.console import Console, get_windows_console_features
+from rich.panel import Panel
+from rich.pretty import Pretty
+
+
+def report() -> None:  # pragma: no cover
+    """Print a report to the terminal with debugging information"""
+    console = Console()
+    inspect(console)
+    features = get_windows_console_features()
+    inspect(features)
+
+    env_names = (
+        "CLICOLOR",
+        "COLORTERM",
+        "COLUMNS",
+        "JPY_PARENT_PID",
+        "JUPYTER_COLUMNS",
+        "JUPYTER_LINES",
+        "LINES",
+        "NO_COLOR",
+        "TERM_PROGRAM",
+        "TERM",
+        "TTY_COMPATIBLE",
+        "VSCODE_VERBOSE_LOGGING",
+    )
+    env = {name: os.getenv(name) for name in env_names}
+    console.print(Panel.fit((Pretty(env)), title="[b]Environment Variables"))
+
+    console.print(f'platform="{platform.system()}"')
+
+
+if __name__ == "__main__":  # pragma: no cover
+    report()
diff --git a/.venv/Lib/site-packages/rich/emoji.py b/.venv/Lib/site-packages/rich/emoji.py
new file mode 100644
index 0000000..d5a1062
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/emoji.py
@@ -0,0 +1,96 @@
+import sys
+from typing import TYPE_CHECKING, Optional, Union
+
+from .jupyter import JupyterMixin
+from .segment import Segment
+from .style import Style
+from ._emoji_codes import EMOJI
+from ._emoji_replace import _emoji_replace
+
+if sys.version_info >= (3, 8):
+    from typing import Literal
+else:
+    from typing_extensions import Literal  # pragma: no cover
+
+
+if TYPE_CHECKING:
+    from .console import Console, ConsoleOptions, RenderResult
+
+
+EmojiVariant = Literal["emoji", "text"]
+
+
+class NoEmoji(Exception):
+    """No emoji by that name."""
+
+
+class Emoji(JupyterMixin):
+    __slots__ = ["name", "style", "_char", "variant"]
+
+    VARIANTS = {"text": "\uFE0E", "emoji": "\uFE0F"}
+
+    def __init__(
+        self,
+        name: str,
+        style: Union[str, Style] = "none",
+        variant: Optional[EmojiVariant] = None,
+    ) -> None:
+        """A single emoji character.
+
+        Args:
+            name (str): Name of emoji.
+            style (Union[str, Style], optional): Optional style. Defaults to None.
+
+        Raises:
+            NoEmoji: If the emoji doesn't exist.
+        """
+        self.name = name
+        self.style = style
+        self.variant = variant
+        try:
+            self._char = EMOJI[name]
+        except KeyError:
+            raise NoEmoji(f"No emoji called {name!r}")
+        if variant is not None:
+            self._char += self.VARIANTS.get(variant, "")
+
+    @classmethod
+    def replace(cls, text: str) -> str:
+        """Replace emoji markup with corresponding unicode characters.
+
+        Args:
+            text (str): A string with emojis codes, e.g. "Hello :smiley:!"
+
+        Returns:
+            str: A string with emoji codes replaces with actual emoji.
+        """
+        return _emoji_replace(text)
+
+    def __repr__(self) -> str:
+        return f""
+
+    def __str__(self) -> str:
+        return self._char
+
+    def __rich_console__(
+        self, console: "Console", options: "ConsoleOptions"
+    ) -> "RenderResult":
+        yield Segment(self._char, console.get_style(self.style))
+
+
+if __name__ == "__main__":  # pragma: no cover
+    import sys
+
+    from rich.columns import Columns
+    from rich.console import Console
+
+    console = Console(record=True)
+
+    columns = Columns(
+        (f":{name}: {name}" for name in sorted(EMOJI.keys()) if "\u200D" not in name),
+        column_first=True,
+    )
+
+    console.print(columns)
+    if len(sys.argv) > 1:
+        console.save_html(sys.argv[1])
diff --git a/.venv/Lib/site-packages/rich/errors.py b/.venv/Lib/site-packages/rich/errors.py
new file mode 100644
index 0000000..0bcbe53
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/errors.py
@@ -0,0 +1,34 @@
+class ConsoleError(Exception):
+    """An error in console operation."""
+
+
+class StyleError(Exception):
+    """An error in styles."""
+
+
+class StyleSyntaxError(ConsoleError):
+    """Style was badly formatted."""
+
+
+class MissingStyle(StyleError):
+    """No such style."""
+
+
+class StyleStackError(ConsoleError):
+    """Style stack is invalid."""
+
+
+class NotRenderableError(ConsoleError):
+    """Object is not renderable."""
+
+
+class MarkupError(ConsoleError):
+    """Markup was badly formatted."""
+
+
+class LiveError(ConsoleError):
+    """Error related to Live display."""
+
+
+class NoAltScreen(ConsoleError):
+    """Alt screen mode was required."""
diff --git a/.venv/Lib/site-packages/rich/file_proxy.py b/.venv/Lib/site-packages/rich/file_proxy.py
new file mode 100644
index 0000000..4b0b0da
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/file_proxy.py
@@ -0,0 +1,57 @@
+import io
+from typing import IO, TYPE_CHECKING, Any, List
+
+from .ansi import AnsiDecoder
+from .text import Text
+
+if TYPE_CHECKING:
+    from .console import Console
+
+
+class FileProxy(io.TextIOBase):
+    """Wraps a file (e.g. sys.stdout) and redirects writes to a console."""
+
+    def __init__(self, console: "Console", file: IO[str]) -> None:
+        self.__console = console
+        self.__file = file
+        self.__buffer: List[str] = []
+        self.__ansi_decoder = AnsiDecoder()
+
+    @property
+    def rich_proxied_file(self) -> IO[str]:
+        """Get proxied file."""
+        return self.__file
+
+    def __getattr__(self, name: str) -> Any:
+        return getattr(self.__file, name)
+
+    def write(self, text: str) -> int:
+        if not isinstance(text, str):
+            raise TypeError(f"write() argument must be str, not {type(text).__name__}")
+        buffer = self.__buffer
+        lines: List[str] = []
+        while text:
+            line, new_line, text = text.partition("\n")
+            if new_line:
+                lines.append("".join(buffer) + line)
+                buffer.clear()
+            else:
+                buffer.append(line)
+                break
+        if lines:
+            console = self.__console
+            with console:
+                output = Text("\n").join(
+                    self.__ansi_decoder.decode_line(line) for line in lines
+                )
+                console.print(output)
+        return len(text)
+
+    def flush(self) -> None:
+        output = "".join(self.__buffer)
+        if output:
+            self.__console.print(output)
+        del self.__buffer[:]
+
+    def fileno(self) -> int:
+        return self.__file.fileno()
diff --git a/.venv/Lib/site-packages/rich/filesize.py b/.venv/Lib/site-packages/rich/filesize.py
new file mode 100644
index 0000000..83bc911
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/filesize.py
@@ -0,0 +1,88 @@
+"""Functions for reporting filesizes. Borrowed from https://github.com/PyFilesystem/pyfilesystem2
+
+The functions declared in this module should cover the different
+use cases needed to generate a string representation of a file size
+using several different units. Since there are many standards regarding
+file size units, three different functions have been implemented.
+
+See Also:
+    * `Wikipedia: Binary prefix `_
+
+"""
+
+__all__ = ["decimal"]
+
+from typing import Iterable, List, Optional, Tuple
+
+
+def _to_str(
+    size: int,
+    suffixes: Iterable[str],
+    base: int,
+    *,
+    precision: Optional[int] = 1,
+    separator: Optional[str] = " ",
+) -> str:
+    if size == 1:
+        return "1 byte"
+    elif size < base:
+        return f"{size:,} bytes"
+
+    for i, suffix in enumerate(suffixes, 2):  # noqa: B007
+        unit = base**i
+        if size < unit:
+            break
+    return "{:,.{precision}f}{separator}{}".format(
+        (base * size / unit),
+        suffix,
+        precision=precision,
+        separator=separator,
+    )
+
+
+def pick_unit_and_suffix(size: int, suffixes: List[str], base: int) -> Tuple[int, str]:
+    """Pick a suffix and base for the given size."""
+    for i, suffix in enumerate(suffixes):
+        unit = base**i
+        if size < unit * base:
+            break
+    return unit, suffix
+
+
+def decimal(
+    size: int,
+    *,
+    precision: Optional[int] = 1,
+    separator: Optional[str] = " ",
+) -> str:
+    """Convert a filesize in to a string (powers of 1000, SI prefixes).
+
+    In this convention, ``1000 B = 1 kB``.
+
+    This is typically the format used to advertise the storage
+    capacity of USB flash drives and the like (*256 MB* meaning
+    actually a storage capacity of more than *256 000 000 B*),
+    or used by **Mac OS X** since v10.6 to report file sizes.
+
+    Arguments:
+        int (size): A file size.
+        int (precision): The number of decimal places to include (default = 1).
+        str (separator): The string to separate the value from the units (default = " ").
+
+    Returns:
+        `str`: A string containing a abbreviated file size and units.
+
+    Example:
+        >>> filesize.decimal(30000)
+        '30.0 kB'
+        >>> filesize.decimal(30000, precision=2, separator="")
+        '30.00kB'
+
+    """
+    return _to_str(
+        size,
+        ("kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"),
+        1000,
+        precision=precision,
+        separator=separator,
+    )
diff --git a/.venv/Lib/site-packages/rich/highlighter.py b/.venv/Lib/site-packages/rich/highlighter.py
new file mode 100644
index 0000000..e4c462e
--- /dev/null
+++ b/.venv/Lib/site-packages/rich/highlighter.py
@@ -0,0 +1,232 @@
+import re
+from abc import ABC, abstractmethod
+from typing import List, Union
+
+from .text import Span, Text
+
+
+def _combine_regex(*regexes: str) -> str:
+    """Combine a number of regexes in to a single regex.
+
+    Returns:
+        str: New regex with all regexes ORed together.
+    """
+    return "|".join(regexes)
+
+
+class Highlighter(ABC):
+    """Abstract base class for highlighters."""
+
+    def __call__(self, text: Union[str, Text]) -> Text:
+        """Highlight a str or Text instance.
+
+        Args:
+            text (Union[str, ~Text]): Text to highlight.
+
+        Raises:
+            TypeError: If not called with text or str.
+
+        Returns:
+            Text: A test instance with highlighting applied.
+        """
+        if isinstance(text, str):
+            highlight_text = Text(text)
+        elif isinstance(text, Text):
+            highlight_text = text.copy()
+        else:
+            raise TypeError(f"str or Text instance required, not {text!r}")
+        self.highlight(highlight_text)
+        return highlight_text
+
+    @abstractmethod
+    def highlight(self, text: Text) -> None:
+        """Apply highlighting in place to text.
+
+        Args:
+            text (~Text): A text object highlight.
+        """
+
+
+class NullHighlighter(Highlighter):
+    """A highlighter object that doesn't highlight.
+
+    May be used to disable highlighting entirely.
+
+    """
+
+    def highlight(self, text: Text) -> None:
+        """Nothing to do"""
+
+
+class RegexHighlighter(Highlighter):
+    """Applies highlighting from a list of regular expressions."""
+
+    highlights: List[str] = []
+    base_style: str = ""
+
+    def highlight(self, text: Text) -> None:
+        """Highlight :class:`rich.text.Text` using regular expressions.
+
+        Args:
+            text (~Text): Text to highlighted.
+
+        """
+
+        highlight_regex = text.highlight_regex
+        for re_highlight in self.highlights:
+            highlight_regex(re_highlight, style_prefix=self.base_style)
+
+
+class ReprHighlighter(RegexHighlighter):
+    """Highlights the text typically produced from ``__repr__`` methods."""
+
+    base_style = "repr."
+    highlights = [
+        r"(?P<)(?P[-\w.:|]*)(?P[\w\W]*)(?P>)",
+        r'(?P[\w_]{1,50})=(?P"?[\w_]+"?)?',
+        r"(?P[][{}()])",
+        _combine_regex(
+            r"(?P[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})",
+            r"(?P([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4})",
+            r"(?P(?:[0-9A-Fa-f]{1,2}-){7}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{1,2}:){7}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{4}\.){3}[0-9A-Fa-f]{4})",
+            r"(?P(?:[0-9A-Fa-f]{1,2}-){5}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{1,2}:){5}[0-9A-Fa-f]{1,2}|(?:[0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})",
+            r"(?P[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})",
+            r"(?P[\w.]*?)\(",
+            r"\b(?PTrue)\b|\b(?PFalse)\b|\b(?PNone)\b",
+            r"(?P\.\.\.)",
+            r"(?P(?(?\B(/[-\w._+]+)*\/)(?P[-\w._+]*)?",
+            r"(?b?'''.*?(?(file|https|http|ws|wss)://[-0-9a-zA-Z$_+!`(),.?/;:&=%#~@]*)",
+        ),
+    ]
+
+
+class JSONHighlighter(RegexHighlighter):
+    """Highlights JSON"""
+
+    # Captures the start and end of JSON strings, handling escaped quotes
+    JSON_STR = r"(?b?\".*?(?[\{\[\(\)\]\}])",
+            r"\b(?Ptrue)\b|\b(?Pfalse)\b|\b(?Pnull)\b",
+            r"(?P(? None:
+        super().highlight(text)
+
+        # Additional work to handle highlighting JSON keys
+        plain = text.plain
+        append = text.spans.append
+        whitespace = self.JSON_WHITESPACE
+        for match in re.finditer(self.JSON_STR, plain):
+            start, end = match.span()
+            cursor = end
+            while cursor < len(plain):
+                char = plain[cursor]
+                cursor += 1
+                if char == ":":
+                    append(Span(start, end, "json.key"))
+                elif char in whitespace:
+                    continue
+                break
+
+
+class ISO8601Highlighter(RegexHighlighter):
+    """Highlights the ISO8601 date time strings.
+    Regex reference: https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s07.html
+    """
+
+    base_style = "iso8601."
+    highlights = [
+        #
+        # Dates
+        #
+        # Calendar month (e.g. 2008-08). The hyphen is required
+        r"^(?P[0-9]{4})-(?P1[0-2]|0[1-9])$",
+        # Calendar date w/o hyphens (e.g. 20080830)
+        r"^(?P(?P[0-9]{4})(?P1[0-2]|0[1-9])(?P3[01]|0[1-9]|[12][0-9]))$",
+        # Ordinal date (e.g. 2008-243). The hyphen is optional
+        r"^(?P(?P[0-9]{4})-?(?P36[0-6]|3[0-5][0-9]|[12][0-9]{2}|0[1-9][0-9]|00[1-9]))$",
+        #
+        # Weeks
+        #
+        # Week of the year (e.g., 2008-W35). The hyphen is optional
+        r"^(?P(?P[0-9]{4})-?W(?P5[0-3]|[1-4][0-9]|0[1-9]))$",
+        # Week date (e.g., 2008-W35-6). The hyphens are optional
+        r"^(?P(?P[0-9]{4})-?W(?P5[0-3]|[1-4][0-9]|0[1-9])-?(?P[1-7]))$",
+        #
+        # Times
+        #
+        # Hours and minutes (e.g., 17:21). The colon is optional
+        r"^(?P